Compare commits
5 Commits
main
...
fix/bookin
Author | SHA1 | Date |
---|---|---|
CarinaWolli | 554b85a600 | |
CarinaWolli | dae16fa6e9 | |
CarinaWolli | a5f906b9b6 | |
CarinaWolli | f54c5675d6 | |
CarinaWolli | 2882b5f7ca |
|
@ -4,6 +4,7 @@ import prismock from "../../../../tests/libs/__mocks__/prisma";
|
||||||
import { diff } from "jest-diff";
|
import { diff } from "jest-diff";
|
||||||
import { describe, expect, vi, beforeEach, afterEach, test } from "vitest";
|
import { describe, expect, vi, beforeEach, afterEach, test } from "vitest";
|
||||||
|
|
||||||
|
import dayjs from "@calcom/dayjs";
|
||||||
import type { BookingStatus } from "@calcom/prisma/enums";
|
import type { BookingStatus } from "@calcom/prisma/enums";
|
||||||
import type { Slot } from "@calcom/trpc/server/routers/viewer/slots/types";
|
import type { Slot } from "@calcom/trpc/server/routers/viewer/slots/types";
|
||||||
import { getAvailableSlots as getSchedule } from "@calcom/trpc/server/routers/viewer/slots/util";
|
import { getAvailableSlots as getSchedule } from "@calcom/trpc/server/routers/viewer/slots/util";
|
||||||
|
@ -874,6 +875,128 @@ describe("getSchedule", () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
test("test that booking limit is working correctly if user is all day available", async () => {
|
||||||
|
const { dateString: plus1DateString } = getDate({ dateIncrement: 1 });
|
||||||
|
const { dateString: plus2DateString } = getDate({ dateIncrement: 2 });
|
||||||
|
const { dateString: plus3DateString } = getDate({ dateIncrement: 3 });
|
||||||
|
|
||||||
|
const scenarioData = {
|
||||||
|
eventTypes: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
length: 60,
|
||||||
|
beforeEventBuffer: 0,
|
||||||
|
afterEventBuffer: 0,
|
||||||
|
bookingLimits: {
|
||||||
|
PER_DAY: 1,
|
||||||
|
},
|
||||||
|
users: [
|
||||||
|
{
|
||||||
|
id: 101,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
length: 60,
|
||||||
|
beforeEventBuffer: 0,
|
||||||
|
afterEventBuffer: 0,
|
||||||
|
bookingLimits: {
|
||||||
|
PER_DAY: 2,
|
||||||
|
},
|
||||||
|
users: [
|
||||||
|
{
|
||||||
|
id: 101,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
users: [
|
||||||
|
{
|
||||||
|
...TestData.users.example,
|
||||||
|
id: 101,
|
||||||
|
schedules: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "All Day available",
|
||||||
|
availability: [
|
||||||
|
{
|
||||||
|
userId: null,
|
||||||
|
eventTypeId: null,
|
||||||
|
days: [0, 1, 2, 3, 4, 5, 6],
|
||||||
|
startTime: new Date("1970-01-01T00:00:00.000Z"),
|
||||||
|
endTime: new Date("1970-01-01T23:59:59.999Z"),
|
||||||
|
date: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timeZone: Timezones["+5:30"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
bookings: [
|
||||||
|
{
|
||||||
|
userId: 101,
|
||||||
|
eventTypeId: 1,
|
||||||
|
startTime: `${plus2DateString}T08:30:00.000Z`,
|
||||||
|
endTime: `${plus2DateString}T08:29:59.999Z`,
|
||||||
|
status: "ACCEPTED" as BookingStatus,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userId: 101,
|
||||||
|
eventTypeId: 2,
|
||||||
|
startTime: `${plus2DateString}T08:30:00.000Z`,
|
||||||
|
endTime: `${plus2DateString}T08:29:59.999Z`,
|
||||||
|
status: "ACCEPTED" as BookingStatus,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
await createBookingScenario(scenarioData);
|
||||||
|
|
||||||
|
const thisUserAvailabilityBookingLimitOne = await getSchedule({
|
||||||
|
input: {
|
||||||
|
eventTypeId: 1,
|
||||||
|
eventTypeSlug: "",
|
||||||
|
startTime: `${plus1DateString}T00:00:00.000Z`,
|
||||||
|
endTime: `${plus3DateString}T23:59:59.999Z`,
|
||||||
|
timeZone: Timezones["+5:30"],
|
||||||
|
isTeamEvent: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const thisUserAvailabilityBookingLimitTwo = await getSchedule({
|
||||||
|
input: {
|
||||||
|
eventTypeId: 2,
|
||||||
|
eventTypeSlug: "",
|
||||||
|
startTime: `${plus1DateString}T00:00:00.000Z`,
|
||||||
|
endTime: `${plus3DateString}T23:59:59.999Z`,
|
||||||
|
timeZone: Timezones["+5:30"],
|
||||||
|
isTeamEvent: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let countSlotsOnDayWithBooking = 0;
|
||||||
|
for (const date in thisUserAvailabilityBookingLimitOne.slots) {
|
||||||
|
for (const timeObj of thisUserAvailabilityBookingLimitOne.slots[date]) {
|
||||||
|
if (dayjs(timeObj.time).tz(Timezones["+5:30"]).format().startsWith(plus2DateString)) {
|
||||||
|
countSlotsOnDayWithBooking++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(countSlotsOnDayWithBooking).toBe(0); // 1 booking per day as limit
|
||||||
|
|
||||||
|
countSlotsOnDayWithBooking = 0;
|
||||||
|
for (const date in thisUserAvailabilityBookingLimitTwo.slots) {
|
||||||
|
for (const timeObj of thisUserAvailabilityBookingLimitTwo.slots[date]) {
|
||||||
|
if (dayjs(timeObj.time).tz(Timezones["+5:30"]).format().startsWith(plus2DateString)) {
|
||||||
|
countSlotsOnDayWithBooking++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(countSlotsOnDayWithBooking).toBe(23); // 2 booking per day as limit
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Team Event", () => {
|
describe("Team Event", () => {
|
||||||
|
|
|
@ -101,6 +101,9 @@ export type InputEventType = {
|
||||||
requiresConfirmation?: boolean;
|
requiresConfirmation?: boolean;
|
||||||
destinationCalendar?: Prisma.DestinationCalendarCreateInput;
|
destinationCalendar?: Prisma.DestinationCalendarCreateInput;
|
||||||
schedule?: InputUser["schedules"][number];
|
schedule?: InputUser["schedules"][number];
|
||||||
|
bookingLimits?: {
|
||||||
|
PER_DAY?: number;
|
||||||
|
};
|
||||||
} & Partial<Omit<Prisma.EventTypeCreateInput, "users" | "schedule">>;
|
} & Partial<Omit<Prisma.EventTypeCreateInput, "users" | "schedule">>;
|
||||||
|
|
||||||
type WhiteListedBookingProps = {
|
type WhiteListedBookingProps = {
|
||||||
|
@ -199,6 +202,7 @@ async function addEventTypes(eventTypes: InputEventType[], usersStore: InputUser
|
||||||
timeZone: null,
|
timeZone: null,
|
||||||
beforeEventBuffer: 0,
|
beforeEventBuffer: 0,
|
||||||
afterEventBuffer: 0,
|
afterEventBuffer: 0,
|
||||||
|
bookingLimits: {},
|
||||||
schedulingType: null,
|
schedulingType: null,
|
||||||
length: 15,
|
length: 15,
|
||||||
//TODO: What is the purpose of periodStartDate and periodEndDate? Test these?
|
//TODO: What is the purpose of periodStartDate and periodEndDate? Test these?
|
||||||
|
|
|
@ -205,7 +205,11 @@ export const stringOrNumber = z.union([
|
||||||
z.number().int(),
|
z.number().int(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const stringToDayjs = z.string().transform((val) => dayjs(val));
|
export const stringToDayjs = z.string().transform((val) => {
|
||||||
|
const matches = val.match(/([+-]\d{2}:\d{2})$/)[1];
|
||||||
|
const timezone = matches ? matches[1] : "+00:00";
|
||||||
|
return dayjs(val).utcOffset(timezone);
|
||||||
|
});
|
||||||
|
|
||||||
export const bookingCreateBodySchema = z.object({
|
export const bookingCreateBodySchema = z.object({
|
||||||
end: z.string().optional(),
|
end: z.string().optional(),
|
||||||
|
|
Loading…
Reference in New Issue