Skip to content

Commit 07c8bb7

Browse files
authored
Merge pull request #3307 from gdg-x/moment
Moment
2 parents bb515ab + ca73bab commit 07c8bb7

File tree

7 files changed

+3741
-183
lines changed

7 files changed

+3741
-183
lines changed

functions/__tests__/time.test.ts

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import { beforeEach, describe, expect, it, jest, beforeAll, afterAll } from '@jest/globals';
2+
import {
3+
createTimeWindow,
4+
filterUpcomingTimeslots,
5+
getTodayDateString,
6+
isBetween,
7+
parseTimeAndGetFromNow,
8+
parseTimeAndSubtract,
9+
} from '../src/time';
10+
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();
21+
});
22+
23+
describe('Time utilities', () => {
24+
beforeEach(() => {
25+
jest.clearAllMocks();
26+
});
27+
28+
describe('getTodayDateString', () => {
29+
it('should return today date in YYYY-MM-DD format', () => {
30+
const result = getTodayDateString();
31+
expect(result).toBe('2025-06-22');
32+
});
33+
34+
it('should return today date with positive timezone offset', () => {
35+
const result = getTodayDateString('+05:00');
36+
expect(result).toBe('2025-06-22');
37+
});
38+
39+
it('should handle negative timezone offset', () => {
40+
const result = getTodayDateString('-08:00');
41+
expect(result).toBe('2025-06-22');
42+
});
43+
});
44+
45+
describe('createTimeWindow', () => {
46+
it('should create a time window around current time', () => {
47+
const window = createTimeWindow(3, 3);
48+
49+
expect(window.before.toISOString()).toBe('2025-06-22T14:27:00.000Z');
50+
expect(window.after.toISOString()).toBe('2025-06-22T14:33:00.000Z');
51+
});
52+
53+
it('should handle different before and after minutes', () => {
54+
const window = createTimeWindow(5, 10);
55+
56+
expect(window.before.toISOString()).toBe('2025-06-22T14:25:00.000Z');
57+
expect(window.after.toISOString()).toBe('2025-06-22T14:40:00.000Z');
58+
});
59+
});
60+
61+
describe('parseTimeAndSubtract', () => {
62+
it('should parse time string and subtract minutes', () => {
63+
const result = parseTimeAndSubtract('15:00', '+02:00', 10);
64+
65+
expect(result.toISOString()).toBe('2025-06-22T12:50:00.000Z');
66+
});
67+
68+
it('should handle different timezones', () => {
69+
const result = parseTimeAndSubtract('09:30', '-05:00', 5);
70+
71+
expect(result.toISOString()).toBe('2025-06-22T14:25:00.000Z');
72+
});
73+
});
74+
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');
80+
81+
expect(isBetween(target, start, end)).toBe(true);
82+
});
83+
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');
88+
89+
expect(isBetween(target, start, end)).toBe(false);
90+
});
91+
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');
96+
97+
expect(isBetween(target, start, end)).toBe(false);
98+
});
99+
});
100+
101+
describe('parseTimeAndGetFromNow', () => {
102+
it('should handle past times', () => {
103+
// For a time in the past (14:00 UTC today from 14:30 UTC)
104+
const result = parseTimeAndGetFromNow('14:00', '+00:00');
105+
106+
expect(result).toContain('ago');
107+
});
108+
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+
116+
it('should work with different timezones', () => {
117+
// Test that the function doesn't throw and returns a string
118+
const result = parseTimeAndGetFromNow('09:00', '-05:00');
119+
120+
expect(typeof result).toBe('string');
121+
expect(result.length).toBeGreaterThan(0);
122+
});
123+
});
124+
125+
describe('filterUpcomingTimeslots', () => {
126+
const mockTimeslots = [
127+
{ id: '1', startTime: '14:00' },
128+
{ id: '2', startTime: '14:30' },
129+
{ id: '3', startTime: '15:00' },
130+
{ id: '4', startTime: '16:00' },
131+
];
132+
133+
it('should filter timeslots within the time window', () => {
134+
const timeWindow = createTimeWindow(3, 3);
135+
136+
const result = filterUpcomingTimeslots(
137+
mockTimeslots,
138+
timeWindow,
139+
10, // notification offset
140+
'+00:00',
141+
);
142+
143+
// With a 10-minute notification offset, 14:30 start time becomes 14:20 notification time
144+
// Current time is 14:30, so the window is 14:27-14:33
145+
// 14:20 is outside this window, so it shouldn't be included
146+
expect(result).toEqual([]);
147+
});
148+
149+
it('should include timeslots that match the notification window', () => {
150+
const timeWindow = createTimeWindow(15, 5); // 14:15 to 14:35
151+
152+
const result = filterUpcomingTimeslots(mockTimeslots, timeWindow, 10, '+00:00');
153+
154+
// 14:30 start time with 10min offset = 14:20 notification time (within 14:15-14:35)
155+
// 15:00 start time with 10min offset = 14:50 notification time (outside window)
156+
expect(result).toEqual([{ id: '2', startTime: '14:30' }]);
157+
});
158+
159+
it('should handle empty timeslots array', () => {
160+
const timeWindow = createTimeWindow(3, 3);
161+
162+
const result = filterUpcomingTimeslots([], timeWindow, 10, '+00:00');
163+
164+
expect(result).toEqual([]);
165+
});
166+
});
167+
});

0 commit comments

Comments
 (0)