Skip to content

Commit 09aa681

Browse files
authored
Merge branch 'develop' into kl/scrum-41-ai-timetable-generate
2 parents b6b9f8e + f8adc57 commit 09aa681

Some content is hidden

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

42 files changed

+2556
-410
lines changed

course-matrix/backend/__tests__/canInsert.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { describe, expect, it, test } from "@jest/globals";
22

3-
import {
4-
canInsert,
5-
createOffering,
6-
Offering,
7-
} from "../src/controllers/generatorController";
3+
import { createOffering, canInsert } from "../src/utils/generatorHelpers";
4+
import { Offering } from "../src/types/generatorTypes";
85

96
describe("canInsert function", () => {
107
const offering1: Offering = createOffering({
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+
});

course-matrix/backend/__tests__/getFrequencyTable.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { describe, expect, it, test } from "@jest/globals";
22

33
import {
44
createOffering,
5-
Offering,
65
getFrequencyTable,
7-
} from "../src/controllers/generatorController";
6+
} from "../src/utils/generatorHelpers";
7+
import { Offering } from "../src/types/generatorTypes";
88

99
describe("getFrequencyTable", () => {
1010
test("should return a frequency map of days", () => {

course-matrix/backend/__tests__/isValidOffering.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { describe, expect, it, test } from "@jest/globals";
22

3+
import { createOffering, isValidOffering } from "../src/utils/generatorHelpers";
34
import {
4-
createOffering,
5-
isValidOffering,
65
Offering,
76
Restriction,
87
RestrictionType,
9-
} from "../src/controllers/generatorController";
8+
} from "../src/types/generatorTypes";
109

1110
describe("isValidOffering", () => {
1211
const sampleOffering: Offering = createOffering({

0 commit comments

Comments
 (0)