1- import { beforeEach , describe , expect , it , jest } from '@jest/globals' ;
2- import moment from 'moment' ;
1+ import { beforeEach , describe , expect , it , jest , beforeAll , afterAll } from '@jest/globals' ;
32import {
43 createTimeWindow ,
54 filterUpcomingTimeslots ,
65 getTodayDateString ,
7- isMomentBetween ,
6+ isBetween ,
87 parseTimeAndGetFromNow ,
98 parseTimeAndSubtract ,
109} from '../src/time' ;
1110
12- // Mock moment to control time for testing
13- jest . mock ( 'moment' , ( ) => {
14- const originalMoment = jest . requireActual ( 'moment' ) ;
15- const mockMoment = ( ...args ) => {
16- if ( args . length === 0 ) {
17- // Return a fixed date when called without arguments (UTC)
18- return originalMoment . utc ( '2025-06-22T14:30:00Z' ) ;
19- }
20- return originalMoment ( ...args ) ;
21- } ;
22-
23- // Copy all moment properties
24- Object . setPrototypeOf ( mockMoment , originalMoment ) ;
25- Object . assign ( mockMoment , originalMoment ) ;
26-
27- return mockMoment ;
11+ // Mock Date to control time for testing
12+ const MOCK_TIME = new Date ( '2025-06-22T14:30:00.000Z' ) ;
13+
14+ beforeAll ( ( ) => {
15+ jest . useFakeTimers ( ) ;
16+ jest . setSystemTime ( MOCK_TIME ) ;
17+ } ) ;
18+
19+ afterAll ( ( ) => {
20+ jest . useRealTimers ( ) ;
2821} ) ;
2922
3023describe ( 'Time utilities' , ( ) => {
@@ -38,7 +31,7 @@ describe('Time utilities', () => {
3831 expect ( result ) . toBe ( '2025-06-22' ) ;
3932 } ) ;
4033
41- it ( 'should return today date with timezone offset' , ( ) => {
34+ it ( 'should return today date with positive timezone offset' , ( ) => {
4235 const result = getTodayDateString ( '+05:00' ) ;
4336 expect ( result ) . toBe ( '2025-06-22' ) ;
4437 } ) ;
@@ -53,69 +46,76 @@ describe('Time utilities', () => {
5346 it ( 'should create a time window around current time' , ( ) => {
5447 const window = createTimeWindow ( 3 , 3 ) ;
5548
56- expect ( window . before . utc ( ) . format ( ) ) . toBe ( '2025-06-22T14:27:00Z ' ) ;
57- expect ( window . after . utc ( ) . format ( ) ) . toBe ( '2025-06-22T14:33:00Z ' ) ;
49+ expect ( window . before . toISOString ( ) ) . toBe ( '2025-06-22T14:27:00.000Z ' ) ;
50+ expect ( window . after . toISOString ( ) ) . toBe ( '2025-06-22T14:33:00.000Z ' ) ;
5851 } ) ;
5952
6053 it ( 'should handle different before and after minutes' , ( ) => {
6154 const window = createTimeWindow ( 5 , 10 ) ;
6255
63- expect ( window . before . utc ( ) . format ( ) ) . toBe ( '2025-06-22T14:25:00Z ' ) ;
64- expect ( window . after . utc ( ) . format ( ) ) . toBe ( '2025-06-22T14:40:00Z ' ) ;
56+ expect ( window . before . toISOString ( ) ) . toBe ( '2025-06-22T14:25:00.000Z ' ) ;
57+ expect ( window . after . toISOString ( ) ) . toBe ( '2025-06-22T14:40:00.000Z ' ) ;
6558 } ) ;
6659 } ) ;
6760
6861 describe ( 'parseTimeAndSubtract' , ( ) => {
6962 it ( 'should parse time string and subtract minutes' , ( ) => {
70- const result = parseTimeAndSubtract ( '15:00' , '+02:00' , 'HH:mm' , 10 ) ;
63+ const result = parseTimeAndSubtract ( '15:00' , '+02:00' , 10 ) ;
7164
72- expect ( result . utc ( ) . format ( ) ) . toBe ( '2025-06-22T12:50:00Z ' ) ;
65+ expect ( result . toISOString ( ) ) . toBe ( '2025-06-22T12:50:00.000Z ' ) ;
7366 } ) ;
7467
7568 it ( 'should handle different timezones' , ( ) => {
76- const result = parseTimeAndSubtract ( '09:30' , '-05:00' , 'HH:mm' , 5 ) ;
69+ const result = parseTimeAndSubtract ( '09:30' , '-05:00' , 5 ) ;
7770
78- expect ( result . utc ( ) . format ( ) ) . toBe ( '2025-06-22T14:25:00Z ' ) ;
71+ expect ( result . toISOString ( ) ) . toBe ( '2025-06-22T14:25:00.000Z ' ) ;
7972 } ) ;
8073 } ) ;
8174
82- describe ( 'isMomentBetween ' , ( ) => {
83- it ( 'should return true when moment is between two other moments ' , ( ) => {
84- const start = moment ( '2025-06-22T14:00:00Z' ) ;
85- const end = moment ( '2025-06-22T15:00:00Z' ) ;
86- const target = moment ( '2025-06-22T14:30:00Z' ) ;
75+ describe ( 'isBetween ' , ( ) => {
76+ it ( 'should return true when date is between two other dates ' , ( ) => {
77+ const start = new Date ( '2025-06-22T14:00:00Z' ) ;
78+ const end = new Date ( '2025-06-22T15:00:00Z' ) ;
79+ const target = new Date ( '2025-06-22T14:30:00Z' ) ;
8780
88- expect ( isMomentBetween ( target , start , end ) ) . toBe ( true ) ;
81+ expect ( isBetween ( target , start , end ) ) . toBe ( true ) ;
8982 } ) ;
9083
91- it ( 'should return false when moment is before the range' , ( ) => {
92- const start = moment ( '2025-06-22T14:00:00Z' ) ;
93- const end = moment ( '2025-06-22T15:00:00Z' ) ;
94- const target = moment ( '2025-06-22T13:30:00Z' ) ;
84+ it ( 'should return false when date is before the range' , ( ) => {
85+ const start = new Date ( '2025-06-22T14:00:00Z' ) ;
86+ const end = new Date ( '2025-06-22T15:00:00Z' ) ;
87+ const target = new Date ( '2025-06-22T13:30:00Z' ) ;
9588
96- expect ( isMomentBetween ( target , start , end ) ) . toBe ( false ) ;
89+ expect ( isBetween ( target , start , end ) ) . toBe ( false ) ;
9790 } ) ;
9891
99- it ( 'should return false when moment is after the range' , ( ) => {
100- const start = moment ( '2025-06-22T14:00:00Z' ) ;
101- const end = moment ( '2025-06-22T15:00:00Z' ) ;
102- const target = moment ( '2025-06-22T15:30:00Z' ) ;
92+ it ( 'should return false when date is after the range' , ( ) => {
93+ const start = new Date ( '2025-06-22T14:00:00Z' ) ;
94+ const end = new Date ( '2025-06-22T15:00:00Z' ) ;
95+ const target = new Date ( '2025-06-22T15:30:00Z' ) ;
10396
104- expect ( isMomentBetween ( target , start , end ) ) . toBe ( false ) ;
97+ expect ( isBetween ( target , start , end ) ) . toBe ( false ) ;
10598 } ) ;
10699 } ) ;
107100
108101 describe ( 'parseTimeAndGetFromNow' , ( ) => {
109102 it ( 'should handle past times' , ( ) => {
110103 // For a time in the past (14:00 UTC today from 14:30 UTC)
111- const result = parseTimeAndGetFromNow ( '14:00' , '+00:00' , 'HH:mm' ) ;
104+ const result = parseTimeAndGetFromNow ( '14:00' , '+00:00' ) ;
112105
113106 expect ( result ) . toContain ( 'ago' ) ;
114107 } ) ;
115108
109+ it ( 'should handle future times' , ( ) => {
110+ // For a time in the future (15:00 UTC today from 14:30 UTC)
111+ const result = parseTimeAndGetFromNow ( '15:00' , '+00:00' ) ;
112+
113+ expect ( result ) . toContain ( 'in' ) ;
114+ } ) ;
115+
116116 it ( 'should work with different timezones' , ( ) => {
117117 // Test that the function doesn't throw and returns a string
118- const result = parseTimeAndGetFromNow ( '09:00' , '-05:00' , 'HH:mm' ) ;
118+ const result = parseTimeAndGetFromNow ( '09:00' , '-05:00' ) ;
119119
120120 expect ( typeof result ) . toBe ( 'string' ) ;
121121 expect ( result . length ) . toBeGreaterThan ( 0 ) ;
@@ -138,7 +138,6 @@ describe('Time utilities', () => {
138138 timeWindow ,
139139 10 , // notification offset
140140 '+00:00' ,
141- 'HH:mm' ,
142141 ) ;
143142
144143 // With a 10-minute notification offset, 14:30 start time becomes 14:20 notification time
@@ -150,7 +149,7 @@ describe('Time utilities', () => {
150149 it ( 'should include timeslots that match the notification window' , ( ) => {
151150 const timeWindow = createTimeWindow ( 15 , 5 ) ; // 14:15 to 14:35
152151
153- const result = filterUpcomingTimeslots ( mockTimeslots , timeWindow , 10 , '+00:00' , 'HH:mm' ) ;
152+ const result = filterUpcomingTimeslots ( mockTimeslots , timeWindow , 10 , '+00:00' ) ;
154153
155154 // 14:30 start time with 10min offset = 14:20 notification time (within 14:15-14:35)
156155 // 15:00 start time with 10min offset = 14:50 notification time (outside window)
@@ -160,7 +159,7 @@ describe('Time utilities', () => {
160159 it ( 'should handle empty timeslots array' , ( ) => {
161160 const timeWindow = createTimeWindow ( 3 , 3 ) ;
162161
163- const result = filterUpcomingTimeslots ( [ ] , timeWindow , 10 , '+00:00' , 'HH:mm' ) ;
162+ const result = filterUpcomingTimeslots ( [ ] , timeWindow , 10 , '+00:00' ) ;
164163
165164 expect ( result ) . toEqual ( [ ] ) ;
166165 } ) ;
0 commit comments