@@ -2,11 +2,25 @@ import "../__mocks__/CalendarAuth";
22
33import { beforeEach , describe , expect , test , vi } from "vitest" ;
44
5+ import dayjs from "@calcom/dayjs" ;
56import type { SelectedCalendar } from "@calcom/prisma/client" ;
67import type { CredentialForCalendarServiceWithEmail } from "@calcom/types/Credential" ;
78
89import { GoogleCalendarSubscriptionAdapter } from "../GoogleCalendarSubscription.adapter" ;
910
11+ const addMonthsFromNow = ( months : number ) => {
12+ const date = dayjs ( ) ;
13+ return date . add ( months , "months" ) . startOf ( "day" ) ;
14+ } ;
15+
16+ const today = dayjs ( ) . startOf ( "day" ) ;
17+
18+ const oneWeekFromNow = today . add ( 7 , "days" ) ;
19+
20+ const eventEndTime = oneWeekFromNow . add ( 1 , "hours" ) ;
21+
22+ const channelExpirationDate = new Date ( Date . now ( ) + 86400000 ) ;
23+
1024vi . mock ( "uuid" , ( ) => ( {
1125 v4 : vi . fn ( ) . mockReturnValue ( "test-uuid" ) ,
1226} ) ) ;
@@ -30,16 +44,16 @@ const mockSelectedCalendar: SelectedCalendar = {
3044 watchAttempts : 0 ,
3145 maxAttempts : 3 ,
3246 unwatchAttempts : 0 ,
33- createdAt : new Date ( ) ,
34- updatedAt : new Date ( ) ,
47+ createdAt : today . toDate ( ) ,
48+ updatedAt : today . toDate ( ) ,
3549 channelId : "test-channel-id" ,
3650 channelKind : "web_hook" ,
3751 channelResourceId : "test-resource-id" ,
3852 channelResourceUri : "test-resource-uri" ,
39- channelExpiration : new Date ( Date . now ( ) + 86400000 ) ,
40- syncSubscribedAt : new Date ( ) ,
53+ channelExpiration : channelExpirationDate ,
54+ syncSubscribedAt : today . toDate ( ) ,
4155 syncToken : "test-sync-token" ,
42- syncedAt : new Date ( ) ,
56+ syncedAt : today . toDate ( ) ,
4357 syncErrorAt : null ,
4458 syncErrorCount : 0 ,
4559} ;
@@ -176,7 +190,7 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
176190 id : "test-channel-id" ,
177191 resourceId : "test-resource-id" ,
178192 resourceUri : "test-resource-uri" ,
179- expiration : "1640995200000" ,
193+ expiration : String ( channelExpirationDate . getTime ( ) ) ,
180194 } ,
181195 } ;
182196
@@ -202,25 +216,26 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
202216 id : "test-channel-id" ,
203217 resourceId : "test-resource-id" ,
204218 resourceUri : "test-resource-uri" ,
205- expiration : new Date ( 1640995200000 ) ,
219+ expiration : channelExpirationDate ,
206220 } ) ;
207221 } ) ;
208222
209223 test ( "should handle expiration as ISO string" , async ( ) => {
224+ const mockExpirationDate = new Date ( Date . now ( ) + 10000000 ) ;
210225 const mockWatchResponse = {
211226 data : {
212227 id : "test-channel-id" ,
213228 resourceId : "test-resource-id" ,
214229 resourceUri : "test-resource-uri" ,
215- expiration : "2023-12-01T10:00:00Z" ,
230+ expiration : mockExpirationDate . toISOString ( ) ,
216231 } ,
217232 } ;
218233
219234 mockClient . events . watch . mockResolvedValue ( mockWatchResponse ) ;
220235
221236 const result = await adapter . subscribe ( mockSelectedCalendar , mockCredential ) ;
222237
223- expect ( result . expiration ) . toEqual ( new Date ( "2023-12-01T10:00:00Z" ) ) ;
238+ expect ( result . expiration ) . toEqual ( mockExpirationDate ) ;
224239 } ) ;
225240
226241 test ( "should handle missing expiration" , async ( ) => {
@@ -265,30 +280,34 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
265280 } ) ;
266281
267282 describe ( "fetchEvents" , ( ) => {
283+ const commonEventData = {
284+ iCalUID : "event-1@cal.com" ,
285+ summary : "Test Event" ,
286+ description : "Test Description" ,
287+ location : "Test Location" ,
288+ status : "confirmed" ,
289+ transparency : "opaque" ,
290+ kind : "calendar#event" ,
291+ etag : "test-etag" ,
292+ created : today . toISOString ( ) ,
293+ updated : today . toISOString ( ) ,
294+ } ;
295+
268296 test ( "should fetch events with sync token" , async ( ) => {
269297 const mockEventsResponse = {
270298 data : {
271299 nextSyncToken : "new-sync-token" ,
272300 items : [
273301 {
274302 id : "event-1" ,
275- iCalUID : "event-1@cal.com" ,
276- summary : "Test Event" ,
277- description : "Test Description" ,
278- location : "Test Location" ,
303+ ...commonEventData ,
279304 start : {
280- dateTime : "2023-12-01T10:00:00Z" ,
305+ dateTime : oneWeekFromNow . toISOString ( ) ,
281306 timeZone : "UTC" ,
282307 } ,
283308 end : {
284- dateTime : "2023-12-01T11:00:00Z" ,
309+ dateTime : eventEndTime . toISOString ( ) ,
285310 } ,
286- status : "confirmed" ,
287- transparency : "opaque" ,
288- kind : "calendar#event" ,
289- etag : "test-etag" ,
290- created : "2023-12-01T09:00:00Z" ,
291- updated : "2023-12-01T09:30:00Z" ,
292311 } ,
293312 ] ,
294313 } ,
@@ -312,8 +331,8 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
312331 {
313332 id : "event-1" ,
314333 iCalUID : "event-1@cal.com" ,
315- start : new Date ( "2023-12-01T10:00:00Z" ) ,
316- end : new Date ( "2023-12-01T11:00:00Z" ) ,
334+ start : oneWeekFromNow . toDate ( ) ,
335+ end : eventEndTime . toDate ( ) ,
317336 busy : true ,
318337 summary : "Test Event" ,
319338 description : "Test Description" ,
@@ -325,14 +344,14 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
325344 timeZone : "UTC" ,
326345 recurringEventId : null ,
327346 originalStartDate : null ,
328- createdAt : new Date ( "2023-12-01T09:00:00Z" ) ,
329- updatedAt : new Date ( "2023-12-01T09:30:00Z" ) ,
347+ createdAt : today . toDate ( ) ,
348+ updatedAt : today . toDate ( ) ,
330349 } ,
331350 ] ,
332351 } ) ;
333352 } ) ;
334353
335- test ( "should fetch events without sync token (initial sync)" , async ( ) => {
354+ test ( "should fetch events without sync token (initial sync) with a 3-month range " , async ( ) => {
336355 const calendarWithoutSyncToken = {
337356 ...mockSelectedCalendar ,
338357 syncToken : null ,
@@ -349,34 +368,37 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
349368
350369 const result = await adapter . fetchEvents ( calendarWithoutSyncToken , mockCredential ) ;
351370
371+ const expectedTimeMin = today . startOf ( "day" ) . toISOString ( ) ;
372+ const expectedTimeMax = addMonthsFromNow ( 3 ) . endOf ( "day" ) . toISOString ( ) ;
373+
352374 expect ( mockClient . events . list ) . toHaveBeenCalledWith ( {
353375 calendarId : "test@example.com" ,
354376 pageToken : undefined ,
355377 singleEvents : true ,
356- timeMin : expect . any ( String ) ,
357- timeMax : expect . any ( String ) ,
378+ timeMin : expectedTimeMin ,
379+ timeMax : expectedTimeMax ,
358380 } ) ;
359381
360382 expect ( result . syncToken ) . toBe ( "initial-sync-token" ) ;
361383 } ) ;
362384
363385 test ( "should handle all-day events" , async ( ) => {
386+ const allDayStart = oneWeekFromNow . startOf ( "day" ) ;
387+ const allDayEnd = oneWeekFromNow . endOf ( "day" ) ;
388+
364389 const mockEventsResponse = {
365390 data : {
366391 nextSyncToken : "new-sync-token" ,
367392 items : [
368393 {
369394 id : "event-1" ,
370- iCalUID : "event-1@cal.com" ,
371- summary : "All Day Event" ,
395+ ...commonEventData ,
372396 start : {
373- date : "2023-12-01" ,
397+ date : allDayStart . toISOString ( ) . split ( "T" ) [ 0 ] ,
374398 } ,
375399 end : {
376- date : "2023-12-02" ,
400+ date : allDayEnd . toISOString ( ) . split ( "T" ) [ 0 ] ,
377401 } ,
378- status : "confirmed" ,
379- transparency : "opaque" ,
380402 } ,
381403 ] ,
382404 } ,
@@ -387,8 +409,8 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
387409 const result = await adapter . fetchEvents ( mockSelectedCalendar , mockCredential ) ;
388410
389411 expect ( result . items [ 0 ] . isAllDay ) . toBe ( true ) ;
390- expect ( result . items [ 0 ] . start ) . toEqual ( new Date ( "2023-12-01" ) ) ;
391- expect ( result . items [ 0 ] . end ) . toEqual ( new Date ( "2023-12-02" ) ) ;
412+ expect ( result . items [ 0 ] . start ) . toEqual ( new Date ( allDayStart . toISOString ( ) . split ( "T" ) [ 0 ] ) ) ;
413+ expect ( result . items [ 0 ] . end ) . toEqual ( new Date ( allDayEnd . toISOString ( ) . split ( "T" ) [ 0 ] ) ) ;
392414 } ) ;
393415
394416 test ( "should handle free events (transparent)" , async ( ) => {
@@ -398,15 +420,14 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
398420 items : [
399421 {
400422 id : "event-1" ,
401- iCalUID : "event-1@cal.com" ,
423+ ... commonEventData ,
402424 summary : "Free Event" ,
403425 start : {
404- dateTime : "2023-12-01T10:00:00Z" ,
426+ dateTime : oneWeekFromNow . toISOString ( ) ,
405427 } ,
406428 end : {
407- dateTime : "2023-12-01T11:00:00Z" ,
429+ dateTime : eventEndTime . toISOString ( ) ,
408430 } ,
409- status : "confirmed" ,
410431 transparency : "transparent" ,
411432 } ,
412433 ] ,
@@ -421,15 +442,18 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
421442 } ) ;
422443
423444 test ( "should handle pagination" , async ( ) => {
445+ const date2 = new Date ( oneWeekFromNow . toDate ( ) ) ;
446+ date2 . setDate ( date2 . getDate ( ) + 1 ) ;
447+
424448 const mockEventsResponse1 = {
425449 data : {
426450 nextPageToken : "page-2" ,
427451 items : [
428452 {
429453 id : "event-1" ,
430454 summary : "Event 1" ,
431- start : { dateTime : "2023-12-01T10:00:00Z" } ,
432- end : { dateTime : "2023-12-01T11:00:00Z" } ,
455+ start : { dateTime : oneWeekFromNow . toISOString ( ) } ,
456+ end : { dateTime : eventEndTime . toISOString ( ) } ,
433457 } ,
434458 ] ,
435459 } ,
@@ -442,8 +466,8 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
442466 {
443467 id : "event-2" ,
444468 summary : "Event 2" ,
445- start : { dateTime : "2023-12-01T12:00:00Z" } ,
446- end : { dateTime : "2023-12-01T13:00:00Z" } ,
469+ start : { dateTime : date2 . toISOString ( ) } ,
470+ end : { dateTime : new Date ( date2 . getTime ( ) + 3600000 ) . toISOString ( ) } ,
447471 } ,
448472 ] ,
449473 } ,
@@ -468,19 +492,19 @@ describe("GoogleCalendarSubscriptionAdapter", () => {
468492 {
469493 id : "event-1" ,
470494 summary : "Valid Event" ,
471- start : { dateTime : "2023-12-01T10:00:00Z" } ,
472- end : { dateTime : "2023-12-01T11:00:00Z" } ,
495+ start : { dateTime : oneWeekFromNow . toISOString ( ) } ,
496+ end : { dateTime : eventEndTime . toISOString ( ) } ,
473497 } ,
474498 {
475499 summary : "Invalid Event" ,
476- start : { dateTime : "2023-12-01T12:00:00Z" } ,
477- end : { dateTime : "2023-12-01T13:00:00Z" } ,
500+ start : { dateTime : oneWeekFromNow . toISOString ( ) } ,
501+ end : { dateTime : eventEndTime . toISOString ( ) } ,
478502 } ,
479503 {
480504 id : "" ,
481505 summary : "Empty ID Event" ,
482- start : { dateTime : "2023-12-01T14:00:00Z" } ,
483- end : { dateTime : "2023-12-01T15:00:00Z" } ,
506+ start : { dateTime : oneWeekFromNow . toISOString ( ) } ,
507+ end : { dateTime : eventEndTime . toISOString ( ) } ,
484508 } ,
485509 ] ,
486510 } ,
0 commit comments