Skip to content

Commit d9e3da4

Browse files
🐛 fix(gcal-series): use dayjs util function in _generateInstances logic (#654)
1 parent f216499 commit d9e3da4

File tree

2 files changed

+37
-51
lines changed

2 files changed

+37
-51
lines changed

packages/backend/src/event/services/recur/recur.week.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { areDatesUnique, haveSharedValues } from "./recur.test.util";
55
import { assembleInstances } from "./util/recur.util";
66

77
describe("Weekly Recurrence: Basics", () => {
8-
it("uses sunday & saturday as start/end dates", () => {
8+
it("starts recurrences on the first day and last day of the week", () => {
99
const rEvents = assembleInstances({
1010
startDate: "2023-07-21",
1111
endDate: "2023-07-22",
@@ -14,8 +14,8 @@ describe("Weekly Recurrence: Basics", () => {
1414
},
1515
} as Schema_Event_Core);
1616

17-
const start = dayjs(rEvents[1].startDate);
18-
const end = dayjs(rEvents[rEvents.length - 1].endDate);
17+
const start = dayjs(rEvents[1]?.startDate);
18+
const end = dayjs(rEvents[rEvents.length - 1]?.endDate);
1919

2020
const isStartSunday = start.day() === 0;
2121
const isEndSaturday = end.day() === 6;
@@ -33,18 +33,18 @@ describe("Weekly Recurrence: Cases", () => {
3333
recurrence: { rule: [RRULE.WEEK] },
3434
} as Schema_Event_Core);
3535

36-
expect(events[1].startDate).toBe("2023-01-15");
37-
expect(events[1].endDate).toBe("2023-01-21");
36+
expect(events[1]?.startDate).toBe("2023-01-15");
37+
expect(events[1]?.endDate).toBe("2023-01-21");
3838

39-
expect(events[2].startDate).toBe("2023-01-22");
40-
expect(events[2].endDate).toBe("2023-01-28");
39+
expect(events[2]?.startDate).toBe("2023-01-22");
40+
expect(events[2]?.endDate).toBe("2023-01-28");
4141
});
4242
it("uses correct dates: case 3: DST (11.5)", () => {
4343
const events = assembleInstances({
4444
startDate: "2023-07-23",
4545
endDate: "2023-07-29",
4646
recurrence: { rule: [RRULE.WEEK] },
47-
} as Schema_Event_Core);
47+
} as Schema_Event_Core).map((e) => ({ ...e, _id: e._id?.toString() }));
4848

4949
expect(areDatesUnique(events)).toBe(true);
5050
expect(haveSharedValues(events)).toBe(false);

packages/backend/src/event/services/recur/util/recur.util.ts

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import dayjs, { Dayjs } from "dayjs";
2-
import utc from "dayjs/plugin/utc";
31
import { ObjectId } from "mongodb";
42
import { RRule } from "rrule";
53
import { RRULE } from "@core/constants/core.constants";
@@ -10,11 +8,10 @@ import {
108
Schema_Event_Recur_Base,
119
Schema_Event_Recur_Instance,
1210
} from "@core/types/event.types";
11+
import dayjs, { Dayjs } from "@core/util/date/dayjs";
1312
import { GenericError } from "@backend/common/errors/generic/generic.errors";
1413
import { error } from "@backend/common/errors/handlers/error.handler";
1514

16-
dayjs.extend(utc);
17-
1815
export const assembleInstances = (
1916
event: Schema_Event_Core,
2017
baseId?: string,
@@ -36,19 +33,32 @@ export const assembleInstances = (
3633
return events;
3734
};
3835

39-
export const stripBaseProps = (base: Schema_Event_Recur_Base) => {
40-
const {
41-
_id, // preserve existing event
42-
gEventId, // strip this so instances remain unique
43-
startDate, // dates changed during DB update
44-
endDate, // dates changed during DB update
45-
order, // preserve order
46-
recurrence, // recurrence change during DB update
47-
user, // preserve user
48-
updatedAt, // changed during DB update
49-
...baseForUpdate // remaining event
50-
} = base;
51-
return baseForUpdate;
36+
export const stripBaseProps = (
37+
base: Schema_Event_Recur_Base,
38+
): Omit<
39+
Schema_Event_Recur_Base,
40+
| "_id"
41+
| "gEventId"
42+
| "startDate"
43+
| "endDate"
44+
| "order"
45+
| "recurrence"
46+
| "user"
47+
| "updatedAt"
48+
> => {
49+
const { allDayOrder, description, gRecurringEventId, isAllDay } = base;
50+
const { isSomeday, origin, priority, title } = base;
51+
52+
return {
53+
allDayOrder,
54+
description,
55+
gRecurringEventId,
56+
isAllDay,
57+
isSomeday,
58+
origin,
59+
priority,
60+
title,
61+
};
5262
};
5363

5464
const _generateInstances = (
@@ -221,36 +231,12 @@ const _getRule = (rule: string, startDate: string, endDate: string) => {
221231
const _getNextStart = (rule: string, startDate: string, endDate: string) => {
222232
switch (rule) {
223233
case RRULE.WEEK:
224-
return _getNextSunday(startDate);
234+
return dayjs(startDate).startOfNextWeek();
225235
break;
226236
case RRULE.MONTH:
227-
return _getNextMonth(endDate);
237+
return dayjs(endDate).startOfNextMonth();
228238
break;
229239
default:
230240
throw error(GenericError.DeveloperError, "Failed to get next start");
231241
}
232242
};
233-
234-
const _getNextMonth = (target: string) => {
235-
const date = dayjs(target, YEAR_MONTH_DAY_FORMAT).hour(0).minute(0).second(0);
236-
237-
const firstOfNextMonth = date.add(1, "month").date(1);
238-
return firstOfNextMonth;
239-
};
240-
241-
const _getNextSunday = (startDate: string) => {
242-
const date = dayjs(startDate, YEAR_MONTH_DAY_FORMAT)
243-
.hour(0)
244-
.minute(0)
245-
.second(0);
246-
247-
const dayOfWeek = date.day();
248-
249-
let daysUntilNextSunday = (7 - dayOfWeek) % 7;
250-
if (daysUntilNextSunday === 0) {
251-
daysUntilNextSunday = 7;
252-
}
253-
254-
const nextSunday = date.add(daysUntilNextSunday, "day");
255-
return nextSunday;
256-
};

0 commit comments

Comments
 (0)