diff --git a/.talismanrc b/.talismanrc index a93354e4..bd6ed741 100644 --- a/.talismanrc +++ b/.talismanrc @@ -12,13 +12,15 @@ fileignoreconfig: - filename: SECURITY.md checksum: b1743150cdd537be3a66f5308f887d130f0f320ab21628b63713808090a84e3f - filename: app/routes/login.tsx - checksum: 71439f7a400334caeb550ee897753dec4b8d36ded11952b3b81594b745aaa18b + allowed_patterns: [password] - filename: app/components/troi.client.tsx - checksum: f8a42a7eaf66377662298793bb806905a807dd5ab2388e629345db80029197e4 + allowed_patterns: [password, /wiki/spaces/DIGITALSER/pages/\d+] - filename: app/routes/projects.tsx - checksum: 68dde5f568d7d4a01c207d5bc6fb95976b1bfe469ad7614ad71241fce8820130 + allowed_patterns: [password] - filename: app/troi/useTroi.hook.tsx - checksum: a0139b548ba37a46ac023bef5f71a6b9a41aa4486a5b59dd97fdc3408c2b7972 + allowed_patterns: [password] +- filename: tests/unit/transformCalendarEvents.test.ts + allowed_patterns: [key] version: "" scopeconfig: - scope: node diff --git a/globals.d.ts b/globals.d.ts index 2759f635..069513a8 100644 --- a/globals.d.ts +++ b/globals.d.ts @@ -10,7 +10,7 @@ declare module "troi-library" { }; export type CalenderEventType = "R" | "H" | "G" | "P" | "T"; export type CalenderEvent = { - id: number; + id: string; startDate: string; endDate: string; subject: string; diff --git a/tests/unit/calendarEventUtils.test.ts b/tests/unit/calendarEventUtils.test.ts new file mode 100644 index 00000000..98162f7f --- /dev/null +++ b/tests/unit/calendarEventUtils.test.ts @@ -0,0 +1,34 @@ +import { + getDescriptionForEventType, + getItemForEventType, +} from "~/utils/calendarEventUtils"; + +test("getItemForEventType should return correct icons", () => { + expect(getItemForEventType("Holiday")).toBe("wb_sunny"); + expect(getItemForEventType("Training")).toBe("school"); + expect(getItemForEventType("PaidVacation")).toBe("beach_access"); + expect(getItemForEventType("UnpaidVacation")).toBe("beach_access"); + expect(getItemForEventType("CompensatoryTimeOff")).toBe("beach_access"); + expect(getItemForEventType("Sick")).toBe("sick"); + expect(getItemForEventType("NonExistentEventType" as any)).toBe("close"); +}); + +test("getDescriptionForEventType should return correct descriptions", () => { + expect(getDescriptionForEventType("Holiday")).toBe( + "Public holiday, working impossible", + ); + expect(getDescriptionForEventType("Training")).toBe("Learning"); + expect(getDescriptionForEventType("PaidVacation")).toBe( + "You are on paid vacation", + ); + expect(getDescriptionForEventType("UnpaidVacation")).toBe( + "You are on unpaid vacation", + ); + expect(getDescriptionForEventType("CompensatoryTimeOff")).toBe( + "Looks like you had some over hours", + ); + expect(getDescriptionForEventType("Sick")).toBe("Sick leave"); + expect(getDescriptionForEventType("NonExistentEventType" as any)).toBe( + "Unknown", + ); +}); diff --git a/tests/unit/timeConverter.test.ts b/tests/unit/timeConverter.test.ts new file mode 100644 index 00000000..fb79aed1 --- /dev/null +++ b/tests/unit/timeConverter.test.ts @@ -0,0 +1,88 @@ +import { + convertFloatTimeToHHMM, + convertTimeStringToFloat, +} from "~/utils/timeConverter"; + +describe("convertFloatTimeToHHMM", () => { + test("1 returns 1:00", () => { + expect(convertFloatTimeToHHMM(1)).toBe("1:00"); + }); + + test("5 returns 5:00", () => { + expect(convertFloatTimeToHHMM(5)).toBe("5:00"); + }); + + test("1.5 returns 1:30", () => { + expect(convertFloatTimeToHHMM(1.5)).toBe("1:30"); + }); + + test("0.2 returns 0:20", () => { + expect(convertFloatTimeToHHMM(0.2)).toBe("0:12"); + }); + + test("0.33333 returns 0:20", () => { + expect(convertFloatTimeToHHMM(0.33333)).toBe("0:20"); + }); + + test("2.05 returns 2:03", () => { + expect(convertFloatTimeToHHMM(2.05)).toBe("2:03"); + }); + + test("0.0166 returns 0:01", () => { + expect(convertFloatTimeToHHMM(0.0166)).toBe("0:01"); + }); +}); + +describe("convertTimeStringToFloat", () => { + test("1:00 returns 1", () => { + expect(convertTimeStringToFloat("1:00")).toBe(1); + }); + + test("5:00 returns 5", () => { + expect(convertTimeStringToFloat("5:00")).toBe(5); + }); + + test("1:30 returns 1.5", () => { + expect(convertTimeStringToFloat("1:30")).toBe(1.5); + }); + + test("0:20 returns 0.2", () => { + expect(convertTimeStringToFloat("0:12")).toBe(0.2); + }); + + test("0:20 returns 0.33333", () => { + expect(convertTimeStringToFloat("0:20")).toBe(1 / 3); + }); + + test("2:03 returns 2.05", () => { + expect(convertTimeStringToFloat("2:03")).toBe(2.05); + }); + + test("0:01 returns 0.0166", () => { + expect(convertTimeStringToFloat("0:01")).toBe(1 / 60); + }); + + test("1:3 returns 1.5", () => { + expect(convertTimeStringToFloat("1:3")).toBe(1.5); + }); + + test("0,5 returns 0.5", () => { + expect(convertTimeStringToFloat("0,5")).toBe(0.5); + }); + + test("1,34563 returns 1.34563", () => { + expect(convertTimeStringToFloat("1,34563")).toBe(1.34563); + }); + + test("21,34563 returns 21.34563", () => { + expect(convertTimeStringToFloat("21,34563")).toBe(21.34563); + }); + + test("1.34563 returns 1.34563", () => { + expect(convertTimeStringToFloat("1.34563")).toBe(1.34563); + }); + + test("21.34563 returns 21.34563", () => { + expect(convertTimeStringToFloat("21.34563")).toBe(21.34563); + }); +}); diff --git a/tests/unit/transformCalendarEvents.test.ts b/tests/unit/transformCalendarEvents.test.ts new file mode 100644 index 00000000..b4597b4d --- /dev/null +++ b/tests/unit/transformCalendarEvents.test.ts @@ -0,0 +1,527 @@ +import type { CalenderEvent } from "troi-library"; +import { utcMidnightDateFromString } from "~/utils/dateUtils"; +import { transformCalendarEvent } from "~/utils/transformCalendarEvents"; + +const singleDayEventsMockData: { [key: string]: CalenderEvent } = { + holiday: { + id: "12824", + startDate: "2023-07-04 00:00:00", + endDate: "2023-07-04 23:59:59", + subject: "Christi Himmelfahrt", + type: "H", + }, + training: { + id: "P6887", + startDate: "2023-07-04 00:09:00", + endDate: "2023-07-04 18:00:00", + subject: "Fortbildung", + type: "P", + }, + paidVacation: { + id: "P6889", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-04 18:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + paidVacationMorning: { + id: "P6889", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-04 13:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + paidVacationAfternoon: { + id: "P6889", + startDate: "2023-07-04 14:00:00", + endDate: "2023-07-04 18:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + unpaidVacation: { + id: "P6889", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-04 18:00:00", + subject: "Unbezahlter Urlaub", + type: "P", + }, + compensatoryTimeOff: { + id: "P6888", + startDate: "2023-07-04 9:00:00", + endDate: "2023-07-04 18:00:00", + subject: "Freizeitausgleich (Überstunden)", + type: "P", + }, + sick: { + id: "P6804", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-04 18:00:00", + subject: "Krankheit", + type: "P", + }, +}; + +const multiDayEventsMockData: { [key: string]: CalenderEvent } = { + paidVacation: { + id: "P6889", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-07 18:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + paidVacationMorning: { + id: "P6889", + startDate: "2023-07-04 09:00:00", + endDate: "2023-07-07 13:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + paidVacationStartingAfternoon: { + id: "P6889", + startDate: "2023-07-04 14:00:00", + endDate: "2023-07-07 18:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, + paidVacationStartingAfternoonToMorning: { + id: "P6889", + startDate: "2023-07-04 14:00:00", + endDate: "2023-07-07 13:00:00", + subject: "Bezahlter Urlaub", + type: "P", + }, +}; + +describe("Single day event tests", () => { + test("holiday is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.holiday; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "Holiday", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("training is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.training; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "Training", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("paidVacation is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.paidVacation; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("paidVacation half day morning is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.paidVacationMorning; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("paidVacation half day afternoon is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.paidVacationAfternoon; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("unpaidVacation is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.unpaidVacation; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "UnpaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("compensatoryTimeOff is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.compensatoryTimeOff; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "CompensatoryTimeOff", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); + + test("sick is tranformed correctly", () => { + // GIVEN + const mockEvent = singleDayEventsMockData.sick; + const minDate = utcMidnightDateFromString("2023-07-03"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = { + type: "Sick", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }; + expect(tranformedEvents).toStrictEqual([expected]); + }); +}); + +describe("Multi day event tests", () => { + test("multi day vacation is tranformed correctly", () => { + // GIVEN + const mockEvent = multiDayEventsMockData.paidVacation; + const minDate = utcMidnightDateFromString("2023-07-04"); + const maxDate = utcMidnightDateFromString("2023-07-07"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.endDate), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation last day half day morning is tranformed correctly", () => { + // GIVEN + const mockEvent = multiDayEventsMockData.paidVacationMorning; + const minDate = utcMidnightDateFromString("2023-07-04"); + const maxDate = utcMidnightDateFromString("2023-07-07"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.endDate), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation first day half day afternoon is tranformed correctly", () => { + // GIVEN + const mockEvent = multiDayEventsMockData.paidVacationStartingAfternoon; + const minDate = utcMidnightDateFromString("2023-07-04"); + const maxDate = utcMidnightDateFromString("2023-07-07"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString(mockEvent.endDate), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation first day half day afternoon last day half day morning is tranformed correctly", () => { + // GIVEN + const mockEvent = + multiDayEventsMockData.paidVacationStartingAfternoonToMorning; + const minDate = utcMidnightDateFromString("2023-07-04"); + const maxDate = utcMidnightDateFromString("2023-07-07"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.endDate), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation first day half day afternoon cut off after second day", () => { + // GIVEN + const mockEvent = + multiDayEventsMockData.paidVacationStartingAfternoonToMorning; + const minDate = utcMidnightDateFromString("2023-07-02"); + const maxDate = utcMidnightDateFromString("2023-07-05"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.startDate), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation first hald cut off", () => { + // GIVEN + const mockEvent = + multiDayEventsMockData.paidVacationStartingAfternoonToMorning; + const minDate = utcMidnightDateFromString("2023-07-06"); + const maxDate = utcMidnightDateFromString("2023-07-15"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + { + type: "PaidVacation", + duration: "HalfDay", + date: utcMidnightDateFromString(mockEvent.endDate), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); + + test("multi day vacation start and end cut off", () => { + // GIVEN + const mockEvent = + multiDayEventsMockData.paidVacationStartingAfternoonToMorning; + const minDate = utcMidnightDateFromString("2023-07-05"); + const maxDate = utcMidnightDateFromString("2023-07-06"); + + // WHEN + const tranformedEvents = transformCalendarEvent( + mockEvent, + minDate, + maxDate, + ); + + // THEN + const expected = [ + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-05"), + }, + { + type: "PaidVacation", + duration: "AllDay", + date: utcMidnightDateFromString("2023-07-06"), + }, + ]; + + expect(tranformedEvents).toStrictEqual(expected); + }); +});