Files
calendar/packages/lib/getBusyTimes.test.ts
T
+5
devin-ai-integration[bot]GitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>morgan@cal.com <morgan@cal.com>Anik Dhabal BabuBenny JooSahitya ChandraCarina WollendorferCarinaWollimintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>Ayush KumarSyed Ali ShahbazLauris Skraucissupalarryemrysal
ebeb008f9b refactor: convert findQualifiedHostsWithDelegationCredentials to service class with DI (#22974)
* refactor: convert findQualifiedHostsWithDelegationCredentials to service class with DI

- Create QualifiedHostsService class following UserAvailabilityService pattern
- Add IQualifiedHostsService interface with prisma and bookingRepo dependencies
- Create DI module and container for qualified hosts service
- Update filterHostsBySameRoundRobinHost to accept prisma as parameter
- Update all usage sites to use the new service:
  - loadAndValidateUsers.ts
  - slots/util.ts
  - test mocks in _post.test.ts
- Maintain backward compatibility with original function export
- Fix type issues in team properties (rrResetInterval, rrTimestampBasis)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update filterHostsBySameRoundRobinHost test to include prisma parameter

- Add missing prisma parameter to all test function calls
- Resolves unit test failure caused by function signature change

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: resolve type issues in FilterHostsService

- Import PrismaClient type instead of using unknown
- Fix type compatibility for BookingRepository constructor
- Update test mocks to use proper BookingRepository type
- Ensure all DI dependencies are properly typed

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: rename DI files to CamelCase and update imports

- Rename all files in packages/lib/di from kebab-case to CamelCase
- Update 22 external files with import statements to use new file names
- Update internal DI module files with corrected imports
- Maintain consistency with TypeScript naming conventions

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: bump platform libs

* chore: bump platform libs

* fix: remove obsolete vitest mock after service class refactoring

- Remove obsolete mock for old function module
- Keep correct mock for new DI container
- Resolves CI unit test failures

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: correct import path for calAIPhone zod-utils module

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: Booker active booking limit can't be switched off (#23005)

* refactor: Get rid of `getServerSideProps` for /getting-started pages (#23003)

* refactor

* fix type check

* fix: Remove Reporting page within Routing Forms (#22990)

* fix error in handleNewBooking (#23011)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Documentation edits made through Mintlify web editor (#23007)

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* fix: Contact support button position changed from absolute to fixed (#23002)

* feat: Add private links to API (#22943)

* --init

* address change requests

* adding further changes

* address feedback

* further changes

* further clean-up

* clean up

* fix module import and others

* add guards

* remove unnecessary comments

* remove unnecessary comments

* cleanup

* sort coderabbig suggestions

* improve check

* chore: bump platform libraries

---------

Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>

* chore: release v5.5.15

* chore: bump platform libs

* chore: bump platform libs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Ayush Kumar <kumarayushkumar@protonmail.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: emrysal <me@alexvanandel.com>
2025-08-11 12:24:15 +00:00

132 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import dayjs from "@calcom/dayjs";
import { getBusyTimesService } from "./di/containers/BusyTimes";
const startOfTomorrow = dayjs().add(1, "day").startOf("day");
const tomorrowDate = startOfTomorrow.format("YYYY-MM-DD");
const mockBookings = ({
beforeEventBuffer = 0,
afterEventBuffer = 0,
seatsPerTimeSlot,
}: {
beforeEventBuffer?: number;
afterEventBuffer?: number;
seatsPerTimeSlot?: number;
}) => [
{
id: 1,
startTime: startOfTomorrow.set("hour", 10).toDate(),
endTime: startOfTomorrow.set("hour", 11).toDate(),
title: "Booking Between X and Y",
userId: 1,
uid: "xxxx1",
eventType: {
id: 1,
beforeEventBuffer,
afterEventBuffer,
seatsPerTimeSlot: seatsPerTimeSlot ?? null,
},
_count: {
seatsReferences: 1,
},
},
{
id: 2,
startTime: startOfTomorrow.set("hour", 14).toDate(),
endTime: startOfTomorrow.set("hour", 15).toDate(),
title: "Booking Between X and Y",
userId: 1,
uid: "xxxx2",
eventType: {
id: 1,
beforeEventBuffer,
afterEventBuffer,
seatsPerTimeSlot: seatsPerTimeSlot ?? null,
},
...(seatsPerTimeSlot
? {
_count: {
seatsReferences: 1,
},
}
: {}),
},
];
describe("getBusyTimes", () => {
it("blocks a regular time slot", async () => {
const busyTimesService = getBusyTimesService();
const busyTimes = await busyTimesService.getBusyTimes({
credentials: [],
userId: 1,
userEmail: "exampleuser1@example.com",
username: "exampleuser1",
bypassBusyCalendarTimes: false,
selectedCalendars: [],
startTime: startOfTomorrow.format(),
endTime: startOfTomorrow.endOf("day").format(),
currentBookings: mockBookings({}),
});
expect(busyTimes).toEqual([
expect.objectContaining({
start: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 10).toDate(),
end: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 11).toDate(),
source: "eventType-1-booking-1",
title: "Booking Between X and Y",
}),
expect.objectContaining({
start: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 14).toDate(),
end: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 15).toDate(),
source: "eventType-1-booking-2",
title: "Booking Between X and Y",
}),
]);
});
it("should block before and after buffer times", async () => {
const busyTimesService = getBusyTimesService();
const busyTimes = await busyTimesService.getBusyTimes({
credentials: [],
userId: 1,
userEmail: "exampleuser1@example.com",
username: "exampleuser1",
bypassBusyCalendarTimes: false,
selectedCalendars: [],
startTime: startOfTomorrow.format(),
endTime: startOfTomorrow.endOf("day").format(),
currentBookings: [mockBookings({ beforeEventBuffer: 10 })[0]],
});
expect(busyTimes).toEqual([
expect.objectContaining({
start: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 9).set("minute", 50).toDate(),
end: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 11).toDate(),
source: "eventType-1-booking-1",
title: "Booking Between X and Y",
}),
]);
});
it("should have busy times only if seated with remaining seats when buffers exist", async () => {
const busyTimesService = getBusyTimesService();
const busyTimes = await busyTimesService.getBusyTimes({
credentials: [],
userId: 1,
eventTypeId: 1,
userEmail: "exampleuser1@example.com",
username: "exampleuser1",
bypassBusyCalendarTimes: false,
selectedCalendars: [],
startTime: startOfTomorrow.format(),
endTime: startOfTomorrow.endOf("day").format(),
currentBookings: [mockBookings({ beforeEventBuffer: 10, seatsPerTimeSlot: 10 })[0]],
});
expect(busyTimes).toEqual([
expect.objectContaining({
start: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 9).set("minute", 50).toDate(),
end: dayjs(`${tomorrowDate}`).startOf("day").set("hour", 10).toDate(),
}),
]);
});
});