Skip to content

Commit 621c928

Browse files
committed
2 parents ba8f9a8 + e93d766 commit 621c928

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+4583
-410
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { describe, expect, it, test } from "@jest/globals";
2+
3+
import { createOffering, canInsert } from "../src/utils/generatorHelpers";
4+
import { Offering } from "../src/types/generatorTypes";
5+
6+
describe("canInsert function", () => {
7+
const offering1: Offering = createOffering({
8+
id: 1,
9+
course_id: 101,
10+
day: "MO",
11+
start: "09:00:00",
12+
end: "10:00:00",
13+
});
14+
const offering2: Offering = createOffering({
15+
id: 2,
16+
course_id: 102,
17+
day: "MO",
18+
start: "10:00:00",
19+
end: "11:00:00",
20+
});
21+
const offering3: Offering = createOffering({
22+
id: 3,
23+
course_id: 103,
24+
day: "MO",
25+
start: "11:00:00",
26+
end: "12:00:00",
27+
});
28+
29+
it("should return true if there is no overlap with existing offerings", async () => {
30+
const toInsert: Offering = createOffering({
31+
id: 4,
32+
course_id: 104,
33+
day: "MO",
34+
start: "12:00:00",
35+
end: "13:00:00",
36+
});
37+
const curList: Offering[] = [offering1, offering2, offering3];
38+
39+
const result = await canInsert(toInsert, curList);
40+
41+
expect(result).toBe(true); // No overlap, should return true
42+
});
43+
44+
it("should return false if there is an overlap with an existing offering", async () => {
45+
const toInsert: Offering = createOffering({
46+
id: 4,
47+
course_id: 104,
48+
day: "MO",
49+
start: "09:30:00",
50+
end: "10:30:00",
51+
});
52+
const curList: Offering[] = [offering1, offering2, offering3];
53+
54+
const result = await canInsert(toInsert, curList);
55+
56+
expect(result).toBe(false); // There is an overlap with offering1, should return false
57+
});
58+
59+
it("should return true if the new offering starts after the last one ends", async () => {
60+
const toInsert: Offering = createOffering({
61+
id: 4,
62+
course_id: 104,
63+
day: "MO",
64+
start: "13:00:00",
65+
end: "14:00:00",
66+
});
67+
const curList: Offering[] = [offering1, offering2, offering3];
68+
69+
const result = await canInsert(toInsert, curList);
70+
71+
expect(result).toBe(true); // No overlap, should return true
72+
});
73+
74+
it("should return true if the new offering ends before the first one starts", async () => {
75+
const toInsert: Offering = createOffering({
76+
id: 4,
77+
course_id: 104,
78+
day: "MO",
79+
start: "07:00:00",
80+
end: "08:00:00",
81+
});
82+
const curList: Offering[] = [offering1, offering2, offering3];
83+
84+
const result = await canInsert(toInsert, curList);
85+
86+
expect(result).toBe(true); // No overlap, should return true
87+
});
88+
89+
it("should return false if the new offering is completely inside an existing one", async () => {
90+
const toInsert: Offering = createOffering({
91+
id: 4,
92+
course_id: 104,
93+
day: "MO",
94+
start: "09:30:00",
95+
end: "09:45:00",
96+
});
97+
const curList: Offering[] = [offering1, offering2, offering3];
98+
99+
const result = await canInsert(toInsert, curList);
100+
101+
expect(result).toBe(false); // Overlaps with offering1, should return false
102+
});
103+
104+
it("should return true if the day is different (no overlap)", async () => {
105+
const toInsert: Offering = createOffering({
106+
id: 4,
107+
course_id: 104,
108+
day: "TU",
109+
start: "09:00:00",
110+
end: "10:00:00",
111+
});
112+
const curList: Offering[] = [offering1, offering2, offering3];
113+
114+
const result = await canInsert(toInsert, curList);
115+
116+
expect(result).toBe(true); // Different day, no overlap
117+
});
118+
});
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
import { describe, expect, jest, test } from "@jest/globals";
2+
import { isDateBetween } from "../src/utils/compareDates";
3+
4+
// For testing purposes, we need to modify the function to accept a custom "now" date
5+
// This allows us to test all scenarios regardless of the current date
6+
function correctDay(offering: any, customNow?: Date): boolean {
7+
const weekdays = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
8+
const semester = offering?.offering;
9+
const day = offering?.day;
10+
if (!semester || !day) return false;
11+
const now = customNow || new Date();
12+
let startDay;
13+
let endDay;
14+
if (semester === "Summer 2025") {
15+
startDay = new Date(2025, 5, 2);
16+
endDay = new Date(2025, 8, 7);
17+
} else if (semester === "Fall 2025") {
18+
startDay = new Date(2025, 9, 3);
19+
endDay = new Date(2025, 12, 3);
20+
} else {
21+
// Winter 2026
22+
startDay = new Date(2026, 1, 6);
23+
endDay = new Date(2026, 4, 4);
24+
}
25+
if (!isDateBetween(now, startDay, endDay)) {
26+
return false;
27+
}
28+
if (weekdays[now.getDay()] !== day) {
29+
return false;
30+
}
31+
return true;
32+
}
33+
34+
describe("correctDay function", () => {
35+
test("should return false for null or undefined offering", () => {
36+
expect(correctDay(null)).toBe(false);
37+
expect(correctDay(undefined)).toBe(false);
38+
});
39+
40+
test("should return false for missing offering properties", () => {
41+
expect(correctDay({})).toBe(false);
42+
expect(correctDay({ offering: "Summer 2025" })).toBe(false);
43+
expect(correctDay({ day: "MO" })).toBe(false);
44+
});
45+
46+
test("should validate correct day in Summer 2025", () => {
47+
// Create specific dates for each day of the week within Summer 2025
48+
const summerDates = [
49+
new Date(2025, 5, 8), // Sunday (June 8, 2025)
50+
new Date(2025, 5, 9), // Monday (June 9, 2025)
51+
new Date(2025, 5, 10), // Tuesday (June 10, 2025)
52+
new Date(2025, 5, 11), // Wednesday (June 11, 2025)
53+
new Date(2025, 5, 12), // Thursday (June 12, 2025)
54+
new Date(2025, 5, 13), // Friday (June 13, 2025)
55+
new Date(2025, 5, 14), // Saturday (June 14, 2025)
56+
];
57+
58+
// Test each day with its corresponding date
59+
const weekdays = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
60+
summerDates.forEach((date, index) => {
61+
// Make sure the getDay returns the expected index
62+
jest.spyOn(date, "getDay").mockReturnValue(index);
63+
64+
// This should pass only for the matching day
65+
expect(
66+
correctDay({ offering: "Summer 2025", day: weekdays[index] }, date),
67+
).toBe(true);
68+
69+
// Test all other days should fail
70+
weekdays.forEach((wrongDay, wrongIndex) => {
71+
if (wrongIndex !== index) {
72+
expect(
73+
correctDay({ offering: "Summer 2025", day: wrongDay }, date),
74+
).toBe(false);
75+
}
76+
});
77+
});
78+
});
79+
80+
test("should validate correct day in Fall 2025", () => {
81+
// Create a date in Fall 2025
82+
const fallDate = new Date(2025, 9, 15); // October 15, 2025
83+
84+
// Mock getDay to return 3 (Wednesday)
85+
jest.spyOn(fallDate, "getDay").mockReturnValue(3);
86+
87+
// Test all days - only Wednesday should pass
88+
expect(correctDay({ offering: "Fall 2025", day: "WE" }, fallDate)).toBe(
89+
true,
90+
);
91+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, fallDate)).toBe(
92+
false,
93+
);
94+
expect(correctDay({ offering: "Fall 2025", day: "MO" }, fallDate)).toBe(
95+
false,
96+
);
97+
expect(correctDay({ offering: "Fall 2025", day: "TU" }, fallDate)).toBe(
98+
false,
99+
);
100+
expect(correctDay({ offering: "Fall 2025", day: "TH" }, fallDate)).toBe(
101+
false,
102+
);
103+
expect(correctDay({ offering: "Fall 2025", day: "FR" }, fallDate)).toBe(
104+
false,
105+
);
106+
expect(correctDay({ offering: "Fall 2025", day: "SA" }, fallDate)).toBe(
107+
false,
108+
);
109+
});
110+
111+
test("should validate correct day in Winter 2026", () => {
112+
// Create a date in Winter 2026
113+
const winterDate = new Date(2026, 1, 20); // February 20, 2026
114+
115+
// Mock getDay to return 5 (Friday)
116+
jest.spyOn(winterDate, "getDay").mockReturnValue(5);
117+
118+
// Test all days - only Friday should pass
119+
expect(correctDay({ offering: "Winter 2026", day: "FR" }, winterDate)).toBe(
120+
true,
121+
);
122+
expect(correctDay({ offering: "Winter 2026", day: "SU" }, winterDate)).toBe(
123+
false,
124+
);
125+
expect(correctDay({ offering: "Winter 2026", day: "MO" }, winterDate)).toBe(
126+
false,
127+
);
128+
expect(correctDay({ offering: "Winter 2026", day: "TU" }, winterDate)).toBe(
129+
false,
130+
);
131+
expect(correctDay({ offering: "Winter 2026", day: "WE" }, winterDate)).toBe(
132+
false,
133+
);
134+
expect(correctDay({ offering: "Winter 2026", day: "TH" }, winterDate)).toBe(
135+
false,
136+
);
137+
expect(correctDay({ offering: "Winter 2026", day: "SA" }, winterDate)).toBe(
138+
false,
139+
);
140+
});
141+
142+
test("should return false when date is outside semester range", () => {
143+
// Create dates outside each semester range
144+
const beforeSummer = new Date(2025, 5, 1); // June 1, 2025 (before Summer 2025)
145+
const afterSummer = new Date(2025, 8, 8); // September 8, 2025 (after Summer 2025)
146+
const beforeFall = new Date(2025, 9, 2); // October 2, 2025 (before Fall 2025)
147+
const afterFall = new Date(2025, 12, 4); // December 4, 2025 (after Fall 2025)
148+
const beforeWinter = new Date(2026, 1, 5); // February 5, 2026 (before Winter 2026)
149+
const afterWinter = new Date(2026, 4, 5); // May 5, 2026 (after Winter 2026)
150+
151+
// Mock getDay to return 0 (Sunday) for all dates
152+
const testDates = [
153+
beforeSummer,
154+
afterSummer,
155+
beforeFall,
156+
afterFall,
157+
beforeWinter,
158+
afterWinter,
159+
];
160+
testDates.forEach((date) => {
161+
jest.spyOn(date, "getDay").mockReturnValue(0);
162+
});
163+
164+
// Test dates outside Summer 2025
165+
expect(
166+
correctDay({ offering: "Summer 2025", day: "SU" }, beforeSummer),
167+
).toBe(false);
168+
expect(
169+
correctDay({ offering: "Summer 2025", day: "SU" }, afterSummer),
170+
).toBe(false);
171+
172+
// Test dates outside Fall 2025
173+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, beforeFall)).toBe(
174+
false,
175+
);
176+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, afterFall)).toBe(
177+
false,
178+
);
179+
180+
// Test dates outside Winter 2026
181+
expect(
182+
correctDay({ offering: "Winter 2026", day: "SU" }, beforeWinter),
183+
).toBe(false);
184+
expect(
185+
correctDay({ offering: "Winter 2026", day: "SU" }, afterWinter),
186+
).toBe(false);
187+
});
188+
189+
test("should return true for dates inside semester range", () => {
190+
// Create dates inside each semester range
191+
const duringSummer = new Date(2025, 6, 15); // July 15, 2025 (during Summer 2025)
192+
const duringFall = new Date(2025, 10, 15); // November 15, 2025 (during Fall 2025)
193+
const duringWinter = new Date(2026, 2, 15); // March 15, 2026 (during Winter 2026)
194+
195+
// Mock getDay to return 0 (Sunday) for all dates
196+
const testDates = [duringSummer, duringFall, duringWinter];
197+
testDates.forEach((date) => {
198+
jest.spyOn(date, "getDay").mockReturnValue(0);
199+
});
200+
201+
// Test dates inside each semester (with matching day)
202+
expect(
203+
correctDay({ offering: "Summer 2025", day: "SU" }, duringSummer),
204+
).toBe(true);
205+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, duringFall)).toBe(
206+
true,
207+
);
208+
expect(
209+
correctDay({ offering: "Winter 2026", day: "SU" }, duringWinter),
210+
).toBe(true);
211+
});
212+
213+
test("should validate edge dates correctly", () => {
214+
// Test exact start and end dates of semesters
215+
const summerStart = new Date(2025, 5, 2); // June 2, 2025
216+
const summerEnd = new Date(2025, 8, 7); // September 7, 2025
217+
const fallStart = new Date(2025, 9, 3); // October 3, 2025
218+
const fallEnd = new Date(2025, 12, 3); // December 3, 2025
219+
const winterStart = new Date(2026, 1, 6); // February 6, 2026
220+
const winterEnd = new Date(2026, 4, 4); // May 4, 2026
221+
222+
// Mock getDay to return 0 (Sunday) for all dates
223+
const edgeDates = [
224+
summerStart,
225+
summerEnd,
226+
fallStart,
227+
fallEnd,
228+
winterStart,
229+
winterEnd,
230+
];
231+
edgeDates.forEach((date) => {
232+
jest.spyOn(date, "getDay").mockReturnValue(0);
233+
});
234+
235+
// Edge dates should be included in the valid range
236+
expect(
237+
correctDay({ offering: "Summer 2025", day: "SU" }, summerStart),
238+
).toBe(true);
239+
expect(correctDay({ offering: "Summer 2025", day: "SU" }, summerEnd)).toBe(
240+
true,
241+
);
242+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, fallStart)).toBe(
243+
true,
244+
);
245+
expect(correctDay({ offering: "Fall 2025", day: "SU" }, fallEnd)).toBe(
246+
true,
247+
);
248+
expect(
249+
correctDay({ offering: "Winter 2026", day: "SU" }, winterStart),
250+
).toBe(true);
251+
expect(correctDay({ offering: "Winter 2026", day: "SU" }, winterEnd)).toBe(
252+
true,
253+
);
254+
});
255+
});

0 commit comments

Comments
 (0)