Files
Benny JooGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
73f51920c5 refactor: move Booker hooks from packages/features to apps/web/modules (#27343)
* refactor: move Booker hooks from packages/features to apps/web/modules

Migrate the following Booker hooks:
- useOverlayCalendar
- useSkipConfirmStep
- useInitializeWeekStart
- useIsQuickAvailabilityCheckFeatureEnabled
- useDecoyBooking

These hooks are only imported by apps/web files, making them safe to move
without creating circular dependencies.

Part of the tRPC-driven UI migration from packages/features to apps/web/modules.

Co-Authored-By: [email protected] <[email protected]>

* fix: revert useIsQuickAvailabilityCheckFeatureEnabled move and fix import paths

- Reverted useIsQuickAvailabilityCheckFeatureEnabled.ts back to packages/features since it's imported by useSlots.ts in packages/features (would create circular dependency)
- Fixed import paths in useOverlayCalendar.ts to use @calcom/features paths
- Fixed import paths in useSkipConfirmStep.ts to use @calcom/features paths
- Updated Booker.tsx to import useIsQuickAvailabilityCheckFeatureEnabled from original location

Co-Authored-By: [email protected] <[email protected]>

* fix: use @calcom/web alias for hook imports to fix vitest resolution

Co-Authored-By: [email protected] <[email protected]>

* refactor

* migrate more hooks

* fix

* mv types

* fix

* fix

* fix

* fix

* revert: remove formatting-only changes to make PR easier to review

Co-Authored-By: [email protected] <[email protected]>

* fix

* fix

* fix

* revert: restore original import ordering in moved hooks

Co-Authored-By: [email protected] <[email protected]>

* fix imports

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* fix: add isBrowser guard to useSlotsViewOnSmallScreen hook

Address Cubic AI review feedback (confidence 9/10) by adding the isBrowser
guard to the useSlotsViewOnSmallScreen hook to follow the file's client-only
contract and avoid executing during SSR/prerendering.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-31 07:33:33 -03:00

224 lines
6.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { QuickAvailabilityCheck } from "../types";
import { isTimeSlotAvailable } from "./isTimeslotAvailable";
describe("isTimeSlotAvailable", () => {
// Test when a slot is unavailable according to quick availability checks
it("should return false when slot is unavailable according to quick availability checks", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [
{
utcStartIso: slotToCheckInIso,
status: "unavailable",
},
];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: slotToCheckInIso }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(false);
});
it("should return true when scheduleData is null", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: null,
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(true);
});
it("should return true when the date doesn't exist in the schedule data", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-09": [{ time: "2024-02-09T10:30:00.000Z" }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(false);
});
describe("Different day due to timezone", () => {
it("should correctly lookup on appropriate date when the day in which to show the slot is before the date in the ISO string", () => {
const slotToCheckInIso1 = "2024-02-08T10:30:00.000Z";
const dateToShowSlot1 = "2024-02-07";
const quickAvailabilityChecks1: QuickAvailabilityCheck[] = [];
const result1 = isTimeSlotAvailable({
scheduleData: {
slots: {
[dateToShowSlot1]: [{ time: slotToCheckInIso1 }],
},
},
slotToCheckInIso: slotToCheckInIso1,
quickAvailabilityChecks: quickAvailabilityChecks1,
});
expect(result1).toBe(true);
const slotToCheckInIso2 = "2024-02-01T10:30:00.000Z";
const dateToShowSlot2 = "2024-01-31";
const quickAvailabilityChecks2: QuickAvailabilityCheck[] = [];
const result2 = isTimeSlotAvailable({
scheduleData: {
slots: {
[dateToShowSlot2]: [{ time: slotToCheckInIso2 }],
},
},
slotToCheckInIso: slotToCheckInIso2,
quickAvailabilityChecks: quickAvailabilityChecks2,
});
expect(result2).toBe(true);
});
it("should correctly lookup on appropriate date when the day in which to show the slot is after the date in the ISO string", () => {
const slotToCheckInIso1 = "2024-02-08T10:30:00.000Z";
const dateToShowSlot1 = "2024-02-09";
const quickAvailabilityChecks1: QuickAvailabilityCheck[] = [];
const result1 = isTimeSlotAvailable({
scheduleData: {
slots: {
[dateToShowSlot1]: [{ time: slotToCheckInIso1 }],
},
},
slotToCheckInIso: slotToCheckInIso1,
quickAvailabilityChecks: quickAvailabilityChecks1,
});
expect(result1).toBe(true);
const slotToCheckInIso2 = "2024-02-01T10:30:00.000Z";
const dateToShowSlot2 = "2024-01-31";
const quickAvailabilityChecks2: QuickAvailabilityCheck[] = [];
const result2 = isTimeSlotAvailable({
scheduleData: {
slots: {
[dateToShowSlot2]: [{ time: slotToCheckInIso2 }],
},
},
slotToCheckInIso: slotToCheckInIso2,
quickAvailabilityChecks: quickAvailabilityChecks2,
});
expect(result2).toBe(true);
});
});
it("should return true when the slot exists in the schedule data", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: slotToCheckInIso }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(true);
});
// Test when the slot doesn't exist in the schedule data
it("should return false when the slot doesn't exist in the schedule data", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const differentSlotTime = "2024-02-08T11:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: differentSlotTime }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(false);
});
// Test when the slot is available according to quick availability checks
it("should check schedule data when slot is available according to quick availability checks", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [
{
utcStartIso: slotToCheckInIso,
status: "available",
},
];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: slotToCheckInIso }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(true);
});
// Test with seconds difference in time slots
it("should return true when slots differ only by seconds", () => {
const slotToCheckInIso = "2024-02-08T10:30:00.000Z";
const slotWithSeconds = "2024-02-08T10:30:45.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: slotWithSeconds }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(true);
});
it("should return true(give a false positive) when the date string is not in the expected format", () => {
// Invalid ISO format -> Correct is "2024-02-08T10:30:00.000Z"
const slotToCheckInIso = "2024-02-8T10:30:00.000Z";
const quickAvailabilityChecks: QuickAvailabilityCheck[] = [];
const result = isTimeSlotAvailable({
scheduleData: {
slots: {
"2024-02-08": [{ time: "2024-02-08T12:00:00.000Z" }],
},
},
slotToCheckInIso,
quickAvailabilityChecks,
});
expect(result).toBe(true);
});
});