2021-09-22 19:52:38 +00:00
|
|
|
import MockDate from "mockdate";
|
2023-05-24 23:35:44 +00:00
|
|
|
import { describe, expect, it } from "vitest";
|
2021-09-22 19:52:38 +00:00
|
|
|
|
2022-06-28 20:40:58 +00:00
|
|
|
import dayjs from "@calcom/dayjs";
|
2023-01-26 22:51:03 +00:00
|
|
|
import { MINUTES_DAY_END, MINUTES_DAY_START } from "@calcom/lib/availability";
|
2022-07-22 17:27:06 +00:00
|
|
|
import getSlots from "@calcom/lib/slots";
|
2022-06-28 20:40:58 +00:00
|
|
|
|
2021-08-19 12:27:01 +00:00
|
|
|
MockDate.set("2021-06-20T11:59:59Z");
|
2021-06-24 22:15:18 +00:00
|
|
|
|
2022-11-02 09:40:30 +00:00
|
|
|
describe("Tests the slot logic", () => {
|
|
|
|
it("can fit 24 hourly slots for an empty day", async () => {
|
|
|
|
// 24h in a day.
|
|
|
|
expect(
|
|
|
|
getSlots({
|
2022-03-12 06:52:27 +00:00
|
|
|
inviteeDate: dayjs.utc().add(1, "day"),
|
|
|
|
frequency: 60,
|
|
|
|
minimumBookingNotice: 0,
|
|
|
|
workingHours: [
|
|
|
|
{
|
2022-12-21 19:32:42 +00:00
|
|
|
userId: 1,
|
2022-03-12 06:52:27 +00:00
|
|
|
days: Array.from(Array(7).keys()),
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: MINUTES_DAY_END,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 60,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-03 16:33:16 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
2022-11-02 09:40:30 +00:00
|
|
|
})
|
|
|
|
).toHaveLength(24);
|
|
|
|
});
|
2022-03-12 06:52:27 +00:00
|
|
|
|
2022-11-02 09:40:30 +00:00
|
|
|
// TODO: This test is sound; it should pass!
|
|
|
|
it("only shows future booking slots on the same day", async () => {
|
|
|
|
// The mock date is 1s to midday, so 12 slots should be open given 0 booking notice.
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs.utc(),
|
|
|
|
frequency: 60,
|
|
|
|
minimumBookingNotice: 0,
|
|
|
|
workingHours: [
|
|
|
|
{
|
2022-12-21 19:32:42 +00:00
|
|
|
userId: 1,
|
2022-11-02 09:40:30 +00:00
|
|
|
days: Array.from(Array(7).keys()),
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: MINUTES_DAY_END,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 60,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-03 16:33:16 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
2022-11-02 09:40:30 +00:00
|
|
|
})
|
|
|
|
).toHaveLength(12);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("can cut off dates that due to invitee timezone differences fall on the next day", async () => {
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs().tz("Europe/Amsterdam").startOf("day"), // time translation +01:00
|
|
|
|
frequency: 60,
|
|
|
|
minimumBookingNotice: 0,
|
|
|
|
workingHours: [
|
|
|
|
{
|
2022-12-21 19:32:42 +00:00
|
|
|
userId: 1,
|
2022-11-02 09:40:30 +00:00
|
|
|
days: [0],
|
|
|
|
startTime: 23 * 60, // 23h
|
|
|
|
endTime: MINUTES_DAY_END,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 60,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-03 16:33:16 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
2022-11-02 09:40:30 +00:00
|
|
|
})
|
|
|
|
).toHaveLength(0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("can cut off dates that due to invitee timezone differences fall on the previous day", async () => {
|
|
|
|
const workingHours = [
|
|
|
|
{
|
2022-12-21 19:32:42 +00:00
|
|
|
userId: 1,
|
2022-11-02 09:40:30 +00:00
|
|
|
days: [0],
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: 1 * 60, // 1h
|
|
|
|
},
|
|
|
|
];
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs().tz("Atlantic/Cape_Verde").startOf("day"), // time translation -01:00
|
|
|
|
frequency: 60,
|
2022-03-12 06:52:27 +00:00
|
|
|
minimumBookingNotice: 0,
|
2022-11-02 09:40:30 +00:00
|
|
|
workingHours,
|
|
|
|
eventLength: 60,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-03 16:33:16 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
2022-11-02 09:40:30 +00:00
|
|
|
})
|
|
|
|
).toHaveLength(0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("adds minimum booking notice correctly", async () => {
|
|
|
|
// 24h in a day.
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs.utc().add(1, "day").startOf("day"),
|
|
|
|
frequency: 60,
|
|
|
|
minimumBookingNotice: 1500,
|
2022-03-12 06:52:27 +00:00
|
|
|
workingHours: [
|
|
|
|
{
|
2022-12-21 19:32:42 +00:00
|
|
|
userId: 1,
|
2022-03-12 06:52:27 +00:00
|
|
|
days: Array.from(Array(7).keys()),
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: MINUTES_DAY_END,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 60,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-03 16:33:16 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
2022-11-02 09:40:30 +00:00
|
|
|
})
|
|
|
|
).toHaveLength(11);
|
|
|
|
});
|
2023-03-17 20:02:56 +00:00
|
|
|
|
|
|
|
it("shows correct time slots for 20 minutes long events with working hours that do not end at a full hour ", async () => {
|
|
|
|
// 72 20-minutes events in a 24h day
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs.utc().add(1, "day"),
|
|
|
|
frequency: 20,
|
|
|
|
minimumBookingNotice: 0,
|
|
|
|
workingHours: [
|
|
|
|
{
|
|
|
|
userId: 1,
|
|
|
|
days: Array.from(Array(7).keys()),
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: MINUTES_DAY_END - 14, // 23:45
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 20,
|
2023-05-17 11:56:55 +00:00
|
|
|
offsetStart: 0,
|
2023-03-17 20:02:56 +00:00
|
|
|
organizerTimeZone: "America/Toronto",
|
|
|
|
})
|
|
|
|
).toHaveLength(71);
|
|
|
|
});
|
2023-05-17 11:56:55 +00:00
|
|
|
|
|
|
|
it("can fit 48 25 minute slots with a 5 minute offset for an empty day", async () => {
|
|
|
|
expect(
|
|
|
|
getSlots({
|
|
|
|
inviteeDate: dayjs.utc().add(1, "day"),
|
|
|
|
frequency: 25,
|
|
|
|
minimumBookingNotice: 0,
|
|
|
|
workingHours: [
|
|
|
|
{
|
|
|
|
userId: 1,
|
|
|
|
days: Array.from(Array(7).keys()),
|
|
|
|
startTime: MINUTES_DAY_START,
|
|
|
|
endTime: MINUTES_DAY_END,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
eventLength: 25,
|
|
|
|
offsetStart: 5,
|
|
|
|
organizerTimeZone: "America/Toronto",
|
|
|
|
})
|
|
|
|
).toHaveLength(48);
|
|
|
|
});
|
2022-03-12 06:52:27 +00:00
|
|
|
});
|