import { describe, expect, it, beforeEach, vi } from "vitest"; import type { PrismaClient } from "@calcom/prisma"; import { bulkUpdateEventsToDefaultLocation } from "./bulkUpdateEventsToDefaultLocation"; vi.mock("../utils", () => ({ getAppFromSlug: vi.fn((slug: string) => { if (slug === "google-meet") { return { slug: "google-meet", appData: { location: { type: "integrations:google:meet", }, }, }; } if (slug === "zoom") { return { slug: "zoom", appData: { location: { type: "integrations:zoom", }, }, }; } return null; }), })); type MockPrisma = { credential: { findFirst: ReturnType; }; eventType: { findMany: ReturnType; updateMany: ReturnType; }; }; const createMockPrisma = (): MockPrisma => ({ credential: { findFirst: vi.fn(), }, eventType: { findMany: vi.fn(), updateMany: vi.fn(), }, }); describe("bulkUpdateEventsToDefaultLocation", () => { let mockPrisma: MockPrisma; beforeEach(() => { mockPrisma = createMockPrisma(); vi.clearAllMocks(); }); it("should throw error when default conferencing app is not set", async () => { const user = { id: 1, metadata: {}, }; await expect( bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1, 2], user, prisma: mockPrisma as unknown as PrismaClient, }) ).rejects.toThrow("Default conferencing app not set"); }); it("should throw error when default conferencing app doesn't exist", async () => { const user = { id: 1, metadata: { defaultConferencingApp: { appSlug: "non-existent-app", appLink: "https://example.com", }, }, }; await expect( bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1, 2], user, prisma: mockPrisma as unknown as PrismaClient, }) ).rejects.toThrow("Default conferencing app 'non-existent-app' doesnt exist."); }); it("should update event types that are not child managed events", async () => { const user = { id: 1, metadata: { defaultConferencingApp: { appSlug: "google-meet", appLink: "https://meet.google.com", }, }, }; const credential = { id: 100 }; const eventTypes = [ { id: 1, parentId: null, metadata: {} }, { id: 2, parentId: null, metadata: {} }, ]; mockPrisma.credential.findFirst.mockResolvedValue(credential); mockPrisma.eventType.findMany.mockResolvedValue(eventTypes); mockPrisma.eventType.updateMany.mockResolvedValue({ count: 2 }); const result = await bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1, 2], user, prisma: mockPrisma as unknown as PrismaClient, }); expect(result.count).toBe(2); expect(mockPrisma.eventType.updateMany).toHaveBeenCalledWith({ where: { id: { in: [1, 2], }, userId: 1, }, data: { locations: [ { type: "integrations:google:meet", link: "https://meet.google.com", credentialId: 100, }, ], }, }); }); it("should filter out child managed event types with locked locations", async () => { const user = { id: 1, metadata: { defaultConferencingApp: { appSlug: "zoom", appLink: "https://zoom.us", }, }, }; const credential = { id: 200 }; const eventTypes = [ { id: 1, parentId: null, metadata: {} }, { id: 2, parentId: 100, metadata: { managedEventConfig: { unlockedFields: { }, }, }, }, { id: 3, parentId: 100, metadata: { managedEventConfig: { unlockedFields: { locations: true, // unlocked }, }, }, }, ]; mockPrisma.credential.findFirst.mockResolvedValue(credential); mockPrisma.eventType.findMany.mockResolvedValue(eventTypes); mockPrisma.eventType.updateMany.mockResolvedValue({ count: 2 }); const result = await bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1, 2, 3], user, prisma: mockPrisma as unknown as PrismaClient, }); expect(result.count).toBe(2); expect(mockPrisma.eventType.updateMany).toHaveBeenCalledWith({ where: { id: { in: [1, 3], }, userId: 1, }, data: { locations: [ { type: "integrations:zoom", link: "https://zoom.us", credentialId: 200, }, ], }, }); }); it("should return count 0 when all event types have locked locations", async () => { const user = { id: 1, metadata: { defaultConferencingApp: { appSlug: "google-meet", appLink: "https://meet.google.com", }, }, }; const credential = { id: 300 }; const eventTypes = [ { id: 1, parentId: 100, metadata: { managedEventConfig: { unlockedFields: { }, }, }, }, { id: 2, parentId: 100, metadata: { managedEventConfig: { unlockedFields: { locations: false, // explicitly locked }, }, }, }, ]; mockPrisma.credential.findFirst.mockResolvedValue(credential); mockPrisma.eventType.findMany.mockResolvedValue(eventTypes); const result = await bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1, 2], user, prisma: mockPrisma as unknown as PrismaClient, }); expect(result.count).toBe(0); expect(mockPrisma.eventType.updateMany).not.toHaveBeenCalled(); }); it("should work without credential when credential is not found", async () => { const user = { id: 1, metadata: { defaultConferencingApp: { appSlug: "google-meet", appLink: "https://meet.google.com", }, }, }; const eventTypes = [{ id: 1, parentId: null, metadata: {} }]; mockPrisma.credential.findFirst.mockResolvedValue(null); mockPrisma.eventType.findMany.mockResolvedValue(eventTypes); mockPrisma.eventType.updateMany.mockResolvedValue({ count: 1 }); const result = await bulkUpdateEventsToDefaultLocation({ eventTypeIds: [1], user, prisma: mockPrisma as unknown as PrismaClient, }); expect(result.count).toBe(1); expect(mockPrisma.eventType.updateMany).toHaveBeenCalledWith({ where: { id: { in: [1], }, userId: 1, }, data: { locations: [ { type: "integrations:google:meet", link: "https://meet.google.com", credentialId: undefined, }, ], }, }); }); it("should only query event types belonging to the user", async () => { const user = { id: 5, metadata: { defaultConferencingApp: { appSlug: "zoom", appLink: "https://zoom.us", }, }, }; const credential = { id: 400 }; const eventTypes = [{ id: 10, parentId: null, metadata: {} }]; mockPrisma.credential.findFirst.mockResolvedValue(credential); mockPrisma.eventType.findMany.mockResolvedValue(eventTypes); mockPrisma.eventType.updateMany.mockResolvedValue({ count: 1 }); await bulkUpdateEventsToDefaultLocation({ eventTypeIds: [10, 11, 12], user, prisma: mockPrisma as unknown as PrismaClient, }); expect(mockPrisma.eventType.findMany).toHaveBeenCalledWith({ where: { id: { in: [10, 11, 12], }, userId: 5, }, select: { id: true, metadata: true, parentId: true, }, }); expect(mockPrisma.eventType.updateMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ userId: 5, }), }) ); }); });