1- import { Categories_Recurrence , Schema_Event } from "@core/types/event.types" ;
1+ import { Categories_Recurrence } from "@core/types/event.types" ;
22import { WithGcalId , gSchema$Event } from "@core/types/gcal" ;
3- import {
4- categorizeEvents ,
5- isExistingInstance ,
6- } from "@core/util/event/event.util" ;
3+ import { categorizeEvents } from "@core/util/event/event.util" ;
74import { UtilDriver } from "@backend/__tests__/drivers/util.driver" ;
85import {
96 getEventsInDb ,
@@ -16,11 +13,8 @@ import {
1613} from "@backend/__tests__/helpers/mock.db.setup" ;
1714import { simulateDbAfterGcalImport } from "@backend/__tests__/helpers/mock.events.init" ;
1815import { mockRecurringGcalBaseEvent } from "@backend/__tests__/mocks.gcal/factories/gcal.event.factory" ;
19- import { RecurringEventRepository } from "@backend/event/services/recur/repo/recur.event.repo" ;
20- import { createSeries } from "@backend/sync/services/sync/__tests__/gcal.sync.processor.delete.util" ;
2116import { createCompassSeriesFromGcalBase } from "@backend/sync/services/sync/__tests__/gcal.sync.processor.test.util" ;
2217import { GcalSyncProcessor } from "@backend/sync/services/sync/gcal.sync.processor" ;
23- import { Change_Gcal } from "@backend/sync/sync.types" ;
2418
2519describe ( "GcalSyncProcessor: DELETE" , ( ) => {
2620 beforeAll ( setupTestDb ) ;
@@ -32,7 +26,6 @@ describe("GcalSyncProcessor: DELETE", () => {
3226 it ( "should delete a STANDALONE event" , async ( ) => {
3327 /* Assemble */
3428 const { user } = await UtilDriver . setupTestUser ( ) ;
35- const repo = new RecurringEventRepository ( user . _id . toString ( ) ) ;
3629
3730 const { gcalEvents } = await simulateDbAfterGcalImport ( user . _id . toString ( ) ) ;
3831
@@ -47,14 +40,14 @@ describe("GcalSyncProcessor: DELETE", () => {
4740 status : "cancelled" ,
4841 } as WithGcalId < gSchema$Event > ;
4942
50- const processor = new GcalSyncProcessor ( repo ) ;
43+ const processor = new GcalSyncProcessor ( user . _id . toString ( ) ) ;
5144 const changes = await processor . processEvents ( [ cancelledGStandalone ] ) ;
5245
5346 /* Assert: Should return a DELETED change */
5447 expect ( changes ) . toHaveLength ( 1 ) ;
5548 expect ( changes [ 0 ] ) . toMatchObject ( {
5649 title : cancelledGStandalone . id ,
57- operation : "DELETED " ,
50+ operation : "STANDALONE_DELETED " ,
5851 } ) ;
5952
6053 // Verify the event is deleted from the DB
@@ -76,48 +69,66 @@ describe("GcalSyncProcessor: DELETE", () => {
7669 it ( "should delete an INSTANCE after cancelling it" , async ( ) => {
7770 /* Assemble */
7871 const { user } = await UtilDriver . setupTestUser ( ) ;
79- const repo = new RecurringEventRepository ( user . _id . toString ( ) ) ;
80- const { compassBaseId, gcalBaseId, meta } = await createSeries ( user ) ;
8172
82- // Query the Compass DB for actual recurring instances
83- const compassInstances = await getEventsInDb ( {
84- gRecurringEventId : compassBaseId ,
85- } ) ;
73+ const { gcalEvents, compassEvents } = await simulateDbAfterGcalImport (
74+ user . _id . toString ( ) ,
75+ ) ;
8676
87- const compassInstance = compassInstances [ 0 ] ;
77+ const compassInstance = compassEvents [ 0 ] ;
8878
8979 const cancelledGcalInstance = {
90- kind : "calendar#event" ,
91- id : compassInstance ?. gEventId ,
80+ ...gcalEvents . instances [ 1 ] ,
9281 status : "cancelled" ,
93- recurringEventId : gcalBaseId ,
9482 originalStartTime : {
95- date : compassInstance ?. startDate ?. slice ( 0 , 10 ) || "2025-04-10" ,
83+ dateTime : compassInstance ?. startDate || "2025-04-10" ,
9684 } ,
9785 } ;
9886
9987 /* Act */
100- const processor = new GcalSyncProcessor ( repo ) ;
101- const changes = await processor . processEvents ( [ cancelledGcalInstance ] ) ;
88+ const processor = new GcalSyncProcessor ( user . _id . toString ( ) ) ;
89+
90+ const changes = await processor . processEvents ( [
91+ gcalEvents . recurring ,
92+ cancelledGcalInstance ,
93+ ] ) ;
10294
10395 /* Assert */
104- expect ( changes ) . toHaveLength ( 1 ) ;
105- const expected : Change_Gcal = {
106- title : cancelledGcalInstance . id as string ,
107- category : Categories_Recurrence . RECURRENCE_INSTANCE ,
108- operation : "DELETED" ,
109- } ;
110- expect ( changes [ 0 ] ) . toEqual ( expected ) ;
96+ expect ( changes ) . toHaveLength ( 3 ) ;
97+
98+ expect ( changes ) . toEqual (
99+ expect . arrayContaining ( [
100+ expect . objectContaining ( {
101+ title : gcalEvents . recurring . summary ,
102+ category : Categories_Recurrence . RECURRENCE_BASE ,
103+ operation : "RECURRENCE_BASE_UPDATED" ,
104+ } ) ,
105+ expect . objectContaining ( {
106+ title : gcalEvents . recurring . summary ,
107+ category : Categories_Recurrence . RECURRENCE_BASE ,
108+ operation : "TIMED_INSTANCES_UPDATED" ,
109+ } ) ,
110+ expect . objectContaining ( {
111+ title : cancelledGcalInstance . summary as string ,
112+ category : Categories_Recurrence . RECURRENCE_INSTANCE ,
113+ operation : "RECURRENCE_INSTANCE_DELETED" ,
114+ } ) ,
115+ ] ) ,
116+ ) ;
111117
112118 const remainingEvents = await getEventsInDb ( { user : user . _id . toString ( ) } ) ;
113119
114120 // Verify only the instance was deleted
115- expect ( remainingEvents ) . toHaveLength ( meta . createdCount - 1 ) ;
116- expect ( remainingEvents [ 0 ] ?. _id ?. toString ( ) ) . toBe ( compassBaseId ) ;
121+ expect ( remainingEvents ) . toHaveLength ( compassEvents . length - 1 ) ;
122+ expect ( remainingEvents [ 0 ] ?. _id ?. toString ( ) ) . toBe (
123+ compassEvents [ 0 ] ?. _id . toString ( ) ,
124+ ) ;
117125
118126 expect (
119- isExistingInstance ( remainingEvents [ 1 ] as unknown as Schema_Event ) ,
120- ) . toBe ( true ) ;
127+ remainingEvents . find (
128+ ( { gRecurringEventId } ) =>
129+ gRecurringEventId === cancelledGcalInstance . id ,
130+ ) ,
131+ ) . toBeUndefined ( ) ;
121132 } ) ;
122133
123134 it ( "should handle a mixed payload of multiple INSTANCE DELETIONS and one BASE UPSERT" , async ( ) => {
@@ -129,36 +140,37 @@ describe("GcalSyncProcessor: DELETE", () => {
129140 } ) ;
130141
131142 const { user } = await UtilDriver . setupTestUser ( ) ;
132- const repo = new RecurringEventRepository ( user . _id . toString ( ) ) ;
133143
134144 const { state } = await createCompassSeriesFromGcalBase (
135145 user ,
136146 gcalBaseEvent ,
137147 ) ;
138148
139149 // Create cancellation payloads for each instance
140- const cancellations = state . instances . map ( ( i ) => ( {
150+ const cancellations : gSchema$Event [ ] = state . instances . map ( ( i ) => ( {
141151 kind : "calendar#event" ,
142152 id : i . gEventId ,
153+ start : { dateTime : i . startDate } ,
154+ recurringEventId : gcalBaseEvent . id ,
143155 status : "cancelled" ,
144156 } ) ) ;
145157
146158 /* Act */
147- const processor = new GcalSyncProcessor ( repo ) ;
159+ const processor = new GcalSyncProcessor ( user . _id . toString ( ) ) ;
148160 const changes = await processor . processEvents ( [
149161 gcalBaseEvent ,
150162 ...cancellations ,
151163 ] ) ;
152164
153165 /* Assert */
154166 // Validate all changes detected
155- expect ( changes ) . toHaveLength ( 3 ) ;
167+ expect ( changes ) . toHaveLength ( 4 ) ;
156168
157169 // Validate change types
158- const deletions = changes . filter ( ( c ) => c . operation === "DELETED" ) ;
159- const upserts = changes . filter ( ( c ) => c . operation === "UPSERTED" ) ;
160- expect ( deletions ) . toHaveLength ( 2 ) ;
161- expect ( upserts ) . toHaveLength ( 1 ) ;
170+ const deletions = changes . filter ( ( c ) => c . operation ?. includes ( "DELETED" ) ) ;
171+ const upserts = changes . filter ( ( c ) => c . operation ?. includes ( "UPDATED" ) ) ;
172+ expect ( deletions ) . toHaveLength ( cancellations . length ) ;
173+ expect ( upserts ) . toHaveLength ( cancellations . length ) ;
162174
163175 // Validate DB state
164176 const remainingEvents = await getEventsInDb ( {
@@ -180,7 +192,6 @@ describe("GcalSyncProcessor: DELETE", () => {
180192
181193 it ( "should delete BASE and all INSTANCES after cancelling a BASE" , async ( ) => {
182194 const { user } = await UtilDriver . setupTestUser ( ) ;
183- const repo = new RecurringEventRepository ( user . _id . toString ( ) ) ;
184195
185196 const gcalBaseEvent = mockRecurringGcalBaseEvent ( {
186197 recurrence : [ "RRULE:FREQ=DAILY" ] ,
@@ -190,21 +201,24 @@ describe("GcalSyncProcessor: DELETE", () => {
190201
191202 // Cancel the entire series
192203 const cancelledBase = {
193- kind : "calendar#event" ,
194- id : gcalBaseEvent . id ,
204+ ...gcalBaseEvent ,
195205 status : "cancelled" ,
196206 } ;
197207
198- const processor = new GcalSyncProcessor ( repo ) ;
208+ const processor = new GcalSyncProcessor ( user . _id . toString ( ) ) ;
199209 const changes = await processor . processEvents ( [ cancelledBase ] ) ;
200210
201211 expect ( changes ) . toHaveLength ( 1 ) ;
202- const expected : Change_Gcal = {
203- title : cancelledBase . id as string ,
204- category : Categories_Recurrence . RECURRENCE_BASE ,
205- operation : "DELETED" ,
206- } ;
207- expect ( changes [ 0 ] ) . toEqual ( expected ) ;
212+
213+ expect ( changes ) . toEqual (
214+ expect . arrayContaining ( [
215+ expect . objectContaining ( {
216+ title : cancelledBase . summary as string ,
217+ category : Categories_Recurrence . RECURRENCE_BASE ,
218+ operation : "SERIES_DELETED" ,
219+ } ) ,
220+ ] ) ,
221+ ) ;
208222
209223 // Verify all Compass events that match the gcal base were deleted
210224 const isEmpty = await isEventCollectionEmpty ( ) ;
0 commit comments