Files
calendar/apps/web/test/lib/checkDurationLimits.test.ts
T
Eunjae LeeGitHubClaude Opus 4.5Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
81e4241f85 refactor: apply biome formatting to apps/web (#27692)
* refactor: apply biome formatting to apps/web (batch 1)

Formats apps/web non-modules directories:
- apps/web/app
- apps/web/lib
- apps/web/pages
- apps/web/styles
- apps/web/server
- apps/web/test
- Root-level .ts and .mjs files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules (batch 2)

Formats smaller apps/web/modules directories:
- onboarding, data-table, users, apps, auth
- integration-attribute-sync, shell, availability
- feature-flags, team, webhooks, getting-started
- feature-opt-in, troubleshooter, schedules, notifications
- signup-view.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules (batch 3)

Formats medium apps/web/modules directories:
- bookings
- event-types
- insights
- embed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules/ee (batch 4)

Formats apps/web/modules/ee directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web (batch 5)

Formats remaining apps/web directories:
- apps/web/modules/settings
- apps/web/modules/booking-audit
- apps/web/playwright

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/components (batch 6)

Formats remaining apps/web/components files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to new apps/web files from main

Formats newly added/modified files from main merge:
- WorkflowStepContainer.tsx (resolved merge conflicts)
- Newly moved files (blocklist, form-builder, schedules, etc.)
- Other files modified in main

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to new apps/web files from main

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 23:25:24 +05:30

123 lines
3.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import dayjs from "@calcom/dayjs";
import { checkDurationLimit, checkDurationLimits } from "@calcom/features/bookings/lib/checkDurationLimits";
import { validateIntervalLimitOrder } from "@calcom/lib/intervalLimits/validateIntervalLimitOrder";
const mockGetTotalBookingDuration = vi.fn();
vi.mock("@calcom/features/bookings/repositories/BookingRepository", () => ({
BookingRepository: vi.fn().mockImplementation(function () {
return {
getTotalBookingDuration: mockGetTotalBookingDuration,
};
}),
}));
type MockData = {
id: number;
startDate: Date;
};
const MOCK_DATA: MockData = {
id: 1,
startDate: dayjs("2022-09-30T09:00:00+01:00").toDate(),
};
// Path: apps/web/test/lib/checkDurationLimits.ts
describe("Check Duration Limits Tests", () => {
it("Should return no errors if limit is not reached", async () => {
mockGetTotalBookingDuration.mockResolvedValue(0);
await expect(
checkDurationLimits({ PER_DAY: 60 }, MOCK_DATA.startDate, MOCK_DATA.id)
).resolves.toBeTruthy();
});
it("Should throw an error if limit is reached", async () => {
mockGetTotalBookingDuration.mockResolvedValue(60);
await expect(
checkDurationLimits({ PER_DAY: 60 }, MOCK_DATA.startDate, MOCK_DATA.id)
).rejects.toThrowError();
});
it("Should pass with multiple duration limits", async () => {
mockGetTotalBookingDuration.mockResolvedValue(30);
await expect(
checkDurationLimits(
{
PER_DAY: 60,
PER_WEEK: 120,
},
MOCK_DATA.startDate,
MOCK_DATA.id
)
).resolves.toBeTruthy();
});
it("Should pass with multiple duration limits with one undefined", async () => {
mockGetTotalBookingDuration.mockResolvedValue(30);
await expect(
checkDurationLimits(
{
PER_DAY: 60,
PER_WEEK: undefined,
},
MOCK_DATA.startDate,
MOCK_DATA.id
)
).resolves.toBeTruthy();
});
it("Should return no errors if limit is not reached with multiple bookings", async () => {
mockGetTotalBookingDuration.mockResolvedValue(60);
await expect(
checkDurationLimits(
{
PER_DAY: 90,
PER_WEEK: 120,
},
MOCK_DATA.startDate,
MOCK_DATA.id
)
).resolves.toBeTruthy();
});
it("Should throw an error if one of the limit is reached with multiple bookings", async () => {
mockGetTotalBookingDuration.mockResolvedValue(90);
await expect(
checkDurationLimits(
{
PER_DAY: 60,
PER_WEEK: 120,
},
MOCK_DATA.startDate,
MOCK_DATA.id
)
).rejects.toThrowError();
});
});
// Path: apps/web/test/lib/checkDurationLimits.ts
describe("Check Duration Limit Tests", () => {
it("Should return no busyTimes and no error if limit is not reached", async () => {
mockGetTotalBookingDuration.mockResolvedValue(60);
await expect(
checkDurationLimit({
key: "PER_DAY",
limitingNumber: 90,
eventStartDate: MOCK_DATA.startDate,
eventId: MOCK_DATA.id,
})
).resolves.toBeUndefined();
});
});
describe("Duration limit validation", () => {
it("Should validate limit where ranges have ascending values", () => {
expect(validateIntervalLimitOrder({ PER_DAY: 30, PER_MONTH: 60 })).toBe(true);
});
it("Should invalidate limit where ranges does not have a strict ascending values", () => {
expect(validateIntervalLimitOrder({ PER_DAY: 60, PER_WEEK: 30 })).toBe(false);
});
it("Should validate a correct limit with 'gaps'", () => {
expect(validateIntervalLimitOrder({ PER_DAY: 60, PER_YEAR: 120 })).toBe(true);
});
it("Should validate empty limit", () => {
expect(validateIntervalLimitOrder({})).toBe(true);
});
});