mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
* refactor: rename SelectedSlotsRepository to PrismaSelectedSlotRepository - Rename class from SelectedSlotsRepository to PrismaSelectedSlotRepository for consistency - Update all imports and type references throughout the codebase - Update DI module bindings and variable names - Maintain type safety without breaking changes Co-Authored-By: [email protected] <[email protected]> * refactor: complete PrismaSelectedSlotRepository rename - Update DI module binding property name from selectedSlotsRepo to selectedSlotRepo - Update test mock to use PrismaSelectedSlotRepository class name - Ensure all references are consistently updated Co-Authored-By: [email protected] <[email protected]> * fix: rename file to prismaSelectedSlotRepository.ts and fix plural variable references - Rename apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts to prismaSelectedSlotRepository.ts - Update class name from PrismaSelectedSlotsRepository to PrismaSelectedSlotRepository - Fix plural variable reference selectedSlotsRepository to selectedSlotRepository in service - Update all import paths to reference the new file name - Maintain consistency with camelCase naming convention Co-Authored-By: [email protected] <[email protected]> * fix: rename SelectedSlotsRepositoryFixture to SelectedSlotRepositoryFixture for consistency - Rename test fixture class from SelectedSlotsRepositoryFixture to SelectedSlotRepositoryFixture (singular) - Update all import statements in test files to use the renamed class - Resolves naming mismatch between fixture class and variable declarations - Fixes TypeScript compilation errors in CI tests Co-Authored-By: [email protected] <[email protected]> * feat: add SelectedSlotRepositoryInterface and update DI to use interface Co-Authored-By: [email protected] <[email protected]> * refactor: rename selectedSlots.ts to selectedSlot.ts and update all imports Co-Authored-By: [email protected] <[email protected]> * fix: update test mock import path after file rename Co-Authored-By: [email protected] <[email protected]> * Update apps/api/v2/src/lib/modules/available-slots.module.ts * Update apps/api/v2/src/lib/modules/available-slots.module.ts * Implement DTO * dont declare dependencies locally, duplicating * Small DTO/token fix * chore: bump @calcom/platform-libraries from 0.0.266 to 0.0.267 * oops. * Update fixture names also * Omg these vscode actions preventing saves * Final fix, hopefully --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Somay Chauhan <[email protected]>
104 lines
3.8 KiB
TypeScript
104 lines
3.8 KiB
TypeScript
import { vi, describe, it, expect, afterEach } from "vitest";
|
|
|
|
// We want to test that the UID cookie set by reserveSlotHandler is configured with the correct
|
|
// SameSite and Secure attributes depending on the environment (http vs https).
|
|
// reserveSlotHandler relies on WEBAPP_URL being evaluated at import time, so we need to reset modules
|
|
// between tests after tweaking process.env to simulate different deployment environments.
|
|
//
|
|
// The handler also calls into Prisma and the SelectedSlotRepository, so we stub those parts out.
|
|
|
|
// We alias the module path once we know WEBAPP_URL has been configured.
|
|
const dynamicImportHandler = async () => await import("./reserveSlot.handler");
|
|
|
|
// The repository instance method is used to check for an existing reservation by someone else.
|
|
// To keep this unit test isolated from the database layer, we stub this to always resolve falsey.
|
|
vi.mock("@calcom/lib/server/repository/PrismaSelectedSlotRepository", () => ({
|
|
PrismaSelectedSlotRepository: vi.fn().mockImplementation(() => ({
|
|
findReservedByOthers: vi.fn().mockResolvedValue(null),
|
|
})),
|
|
}));
|
|
|
|
// A tiny helper to build a canned handler context with stubbed Prisma methods.
|
|
const buildContext = () => {
|
|
const prismaStub = {
|
|
eventType: {
|
|
// Return a minimal event type that will exercise the happy path.
|
|
findUnique: vi.fn().mockResolvedValue({ users: [{ id: 1 }], seatsPerTimeSlot: null }),
|
|
},
|
|
booking: {
|
|
findFirst: vi.fn().mockResolvedValue(null),
|
|
},
|
|
selectedSlots: {
|
|
upsert: vi.fn().mockResolvedValue(null),
|
|
},
|
|
} as unknown as any;
|
|
|
|
// Capture header values to assert on.
|
|
let cookieHeaderValue: string | null = null;
|
|
const resStub = {
|
|
setHeader: vi.fn((_name: string, value: string) => {
|
|
cookieHeaderValue = value;
|
|
}),
|
|
};
|
|
|
|
const reqStub = {
|
|
cookies: {},
|
|
};
|
|
|
|
return { prismaStub, resStub, reqStub, getCookieHeader: () => cookieHeaderValue };
|
|
};
|
|
|
|
describe("reserveSlotHandler cookie settings", () => {
|
|
const originalWebappUrl = process.env.NEXT_PUBLIC_WEBAPP_URL;
|
|
|
|
afterEach(() => {
|
|
// Reset the module registry and restore the WEBAPP_URL between tests.
|
|
vi.resetModules();
|
|
if (originalWebappUrl === undefined) {
|
|
delete process.env.NEXT_PUBLIC_WEBAPP_URL;
|
|
} else {
|
|
process.env.NEXT_PUBLIC_WEBAPP_URL = originalWebappUrl;
|
|
}
|
|
});
|
|
|
|
it("sets SameSite=None and Secure when WEBAPP_URL is https", async () => {
|
|
process.env.NEXT_PUBLIC_WEBAPP_URL = "https://example.com";
|
|
vi.resetModules();
|
|
const { reserveSlotHandler } = await dynamicImportHandler();
|
|
const { prismaStub, reqStub, resStub, getCookieHeader } = buildContext();
|
|
await reserveSlotHandler({
|
|
ctx: { prisma: prismaStub, req: reqStub, res: resStub },
|
|
input: {
|
|
slotUtcStartDate: new Date().toISOString(),
|
|
slotUtcEndDate: new Date(Date.now() + 15 * 60 * 1000).toISOString(),
|
|
eventTypeId: 1,
|
|
bookingUid: undefined,
|
|
_isDryRun: false,
|
|
},
|
|
});
|
|
const cookie = getCookieHeader();
|
|
expect(cookie).toMatch(/SameSite=None/);
|
|
expect(cookie).toMatch(/Secure/);
|
|
});
|
|
|
|
it("falls back to SameSite=Lax and no Secure for http WEBAPP_URL", async () => {
|
|
process.env.NEXT_PUBLIC_WEBAPP_URL = "http://localhost:3000";
|
|
vi.resetModules();
|
|
const { reserveSlotHandler } = await dynamicImportHandler();
|
|
const { prismaStub, reqStub, resStub, getCookieHeader } = buildContext();
|
|
await reserveSlotHandler({
|
|
ctx: { prisma: prismaStub, req: reqStub, res: resStub },
|
|
input: {
|
|
slotUtcStartDate: new Date().toISOString(),
|
|
slotUtcEndDate: new Date(Date.now() + 15 * 60 * 1000).toISOString(),
|
|
eventTypeId: 1,
|
|
bookingUid: undefined,
|
|
_isDryRun: false,
|
|
},
|
|
});
|
|
const cookie = getCookieHeader();
|
|
expect(cookie).toMatch(/SameSite=Lax/);
|
|
expect(cookie).not.toMatch(/Secure/);
|
|
});
|
|
});
|