diff --git a/backend/src/test/FakeDataFactory.ts b/backend/src/test/FakeDataFactory.ts index 86e5e43b..593b1890 100644 --- a/backend/src/test/FakeDataFactory.ts +++ b/backend/src/test/FakeDataFactory.ts @@ -63,6 +63,9 @@ class FakeDataFactory { }; } + + + /** * Create a random user event for testing purposes. * @returns A random user event object. @@ -109,6 +112,8 @@ class FakeDataFactory { }; } + + /** * Create a random user event for testing purposes. The event is set to be recurring. * @returns A random user event object. @@ -127,19 +132,6 @@ class FakeDataFactory { private static addMinutes(date: Date, minutes: number) { return new Date(date.getTime() + minutes * 60000); } - - /** - * Return the specified id, generates an id, or returns undefined - */ - // private generateId(id?: boolean | string): string | undefined { - // if (id === true) { - // return faker.string.uuid(); - // } else if (typeof id === 'string') { - // return id; - // } else { - // return undefined; - // } - // } } export default FakeDataFactory; \ No newline at end of file diff --git a/backend/src/test/scheduler.spec.ts b/backend/src/test/scheduler.spec.ts new file mode 100644 index 00000000..a0dc5a33 --- /dev/null +++ b/backend/src/test/scheduler.spec.ts @@ -0,0 +1,125 @@ +import { describe, it, expect, beforeAll } from 'vitest'; +import FakeDataFactory from './FakeDataFactory'; +import Scheduler from '../utils/Scheduler'; +import { PreferenceQuestion, User, UserDeadline, UserEvent, UserPreference } from '../db/types.ts'; +import { faker } from '@faker-js/faker'; + +/* +* Test to test the calculate deadline remainders function +*/ + +describe("calculate deadline remainders with specific data", () => { + // Declares types of variables + let factory: FakeDataFactory; + let user: User; + let userEvents: UserEvent[] = []; + let userDeadlines: UserDeadline[] = []; + let userPreferences: UserPreference[] = []; + + // Initializes all of the variables before the test + beforeAll(() => { + factory = new FakeDataFactory(); + user = factory.randomUser(); + userEvents = [ + { + id: "event1", + user_id: user.id, + title: "Event 1", + start_time: new Date("2025-05-15T09:00:00"), + end_time: new Date("2025-05-15T11:00:00"), + description: "CS Class", + location_place: "Noyce", + is_recurring: false, + recurrence_pattern: null, + recurrence_start_date: null, + recurrence_end_date: null, + is_generated: false, + break_time: "00:15", + created_at: new Date(), + deadline_id: "class", + }, + { + id: "Tennis practce", + user_id: user.id, + title: "Tennis practice", + start_time: new Date("2025-05-15T14:00:00"), + end_time: new Date("2025-05-15T16:00:00"), + description: "Tennis practice", + location_place: "Tennis Courts", + is_recurring: false, + recurrence_pattern: null, + recurrence_start_date: null, + recurrence_end_date: null, + is_generated: false, + break_time: "00:10", + created_at: new Date(), + deadline_id: "tennis", + } + ]; + + userDeadlines = [ + { + id: "test", + user_id: user.id, + event_id: "test", + title: "test", + due_time: new Date("2025-05-15T12:00:00"), + description: "Test", + priority: "High", + projected_duration: 60, // 1 hour + created_at: new Date(), + }, + { + id: "essay", + user_id: user.id, + event_id: "essay", + title: "essay", + due_time: new Date("2025-05-15T18:00:00"), + description: "essay", + priority: "Medium", + projected_duration: 120, // 2 hours + created_at: new Date(), + } + ]; + + userPreferences = [ + { + id: "pref", + user_id: user.id, + question_id: "question", + answer: "answer", + } + ]; + }); + // Testing for a regular unscheduled minutes + it("regular test case to schedule unscheduled minutes", () => { + userEvents.forEach((event) => { + const deadline = userDeadlines.find(d => d.id === event.deadline_id); + // Makes sure deadline, end time, and start times found + if (deadline && event.end_time && event.start_time) { + const result = Scheduler.calculateDeadlineRemainders([event], [deadline]); + + // Expected scheduled duration in minutes + const scheduledDuration = (event.end_time.getTime() - event.start_time.getTime()) / 60000; + + // Declare outside the if-block + let expectedUnscheduled = 0; + + // Checks to make sure deadline isn't null and if it's not null then subtract the total amount scheduled minutes away from the unscheduled minutes + if (deadline.projected_duration != null) { + expectedUnscheduled = deadline.projected_duration - scheduledDuration; + } + // Checks to make sure the test passes + expect(result[0].unscheduledMinutes).toBeCloseTo(expectedUnscheduled, 1); + } + // throws an error otherwise + else { + console.error(`Missing data for event: ${event.id}`); + } + }); + }); +}); + + + + diff --git a/backend/src/test/userPreferenceUtils.spec.ts b/backend/src/test/userPreferenceUtils.spec.ts index e001b493..1a286c45 100644 --- a/backend/src/test/userPreferenceUtils.spec.ts +++ b/backend/src/test/userPreferenceUtils.spec.ts @@ -9,7 +9,7 @@ describe('Test the transform method of user preference utils', () => { question_id : "pt", user_id : user_id, id: faker.string.uuid(), - }; +}; const wdData : UserPreference = { answer : "45", @@ -54,4 +54,89 @@ describe('Test the transform method of user preference utils', () => { it('should return the correct User Preferences model data', async () => { expect(UserPreferenceUtils.transform(fullUserPreference)).toEqual(expectedUserPreferences); }); -}); \ No newline at end of file +}); + + +/* + * Tests converting minutes into the correct number of minutes and hours: minuteNumberToHourAndMinute + */ +describe ("test minute number to hour and minute", () => { + // Tests for 0 edge case + it ("0 min -> 0 hr, 0 min,", () => { + expect (UserPreferenceUtils.minuteNumberToHourAndMinute(0)).toEqual([0, 0]); + }); + // Tests for minutes having a number, but hour having 0 + it ("20 min -> 0 hr, 20 min", () => { + expect (UserPreferenceUtils.minuteNumberToHourAndMinute(20)).toEqual([0, 20]); + }); + // Tests for hour having a number, but minutes having 0 + it ("120 min -> 2 hr, 0 min", () => { + expect (UserPreferenceUtils.minuteNumberToHourAndMinute(120)).toEqual([2, 0]); + }); + // Tests for both hours and minutes having a number + it ("400 min -> 6 hr, 40 min", () => { + expect(UserPreferenceUtils.minuteNumberToHourAndMinute(400)).toEqual([6, 40]); + }); +}); + +/* +* dateToMinuteNumber +*/ +describe ("test date to minutes", () => { + // Testing for 0 + it("00:00 => 0", () => { + const result = UserPreferenceUtils.dateToMinuteNumber(new Date('2025-05-08T00:00:00')); + expect(result).toBe(0); + }); + // Testing for minutes and no hours + it("00:35 => 0", () => { + const result = UserPreferenceUtils.dateToMinuteNumber(new Date('2025-05-08T00:35:00')); + expect(result).toBe(35); + }); + // Testing for hours and no minutes + it ("4:00 -> 240", () => { + const result = UserPreferenceUtils.dateToMinuteNumber(new Date('2025-05-08T04:00:00')); + expect(result).toBe(240); +}); +// Testing for both hours and minutes +it ("10:30 -> 630", () => { + // Checks for both + const result = UserPreferenceUtils.dateToMinuteNumber(new Date('2025-05-08T10:30:00')); + expect(result).toBe(630); +}); + +it ("05:05 -> 305", () => { + // Checks for future dates + const result = UserPreferenceUtils.dateToMinuteNumber(new Date('2025-08-20T05:05:00')); + expect(result).toBe(305); + }); +}); + +/* +* Tests converting a string to minutes : timeStringToMinuteNumber +*/ +describe ("string to minute", () => { + // Tests for 0 edge case + it ("0 min -> 0 min,", () => { + expect (UserPreferenceUtils.timeStringToMinuteNumber("0:0")).toEqual(0); + }); + // Tests for only minutes and no hours + it ("45 min -> 45 min", () => { + expect (UserPreferenceUtils.timeStringToMinuteNumber("0:45")).toEqual(45); + }); + // Tests for both hours and minutes + it ("1 hr and 30 min -> 90 min", () => { + expect (UserPreferenceUtils.timeStringToMinuteNumber("1:30")).toEqual(90); + }); + // Tests for only hours converted into minutes + it ("5 hrs and 0 min -> 300 min", () => { + expect (UserPreferenceUtils.timeStringToMinuteNumber("5:0")).toEqual(300); + }); + // Tests for large numbers + it ("20 hrs and 20 min -> 1220 min", () => { + expect (UserPreferenceUtils.timeStringToMinuteNumber("20:20")).toEqual(1220); + }); +}); + + +