Files
calendar/packages/features/calendars/lib/CalendarManager.test.ts
T
RomitGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
4291a59b2c fix: add missing vi.mock() calls to prevent vitest worker shutdown flakiness (#28459)
* fix: add missing vi.mock() calls to prevent vitest worker shutdown flakiness

Add vi.mock() calls for modules that trigger background network requests
or database connections during import. These transitive imports can cause
the vitest worker RPC to shut down while pending fetch/network operations
are still in flight, resulting in flaky test failures with:
  Error: [vitest-worker]: Closing rpc while "fetch" was pending

The primary modules mocked are:
- @calcom/app-store/delegationCredential (triggers credential lookups)
- @calcom/prisma (triggers database initialization)
- @calcom/features/calendars/lib/CalendarManager (triggers calendar API calls)
- @calcom/features/auth/lib/verifyEmail (triggers email service)
- @calcom/lib/domainManager/organization (triggers domain lookups)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: remove conflicting empty prisma mocks from files with prismock/prismaMock setups

- Remove vi.mock('@calcom/prisma', () => ({ default: {}, prisma: {} })) from 28 files
  that already have prismock/prismaMock test doubles. Vitest hoists all vi.mock() calls
  and the last one wins, so these empty mocks were overriding the functional test doubles.
- Fix CalendarSubscriptionService.test.ts to reuse the shared mock from
  __mocks__/delegationCredential instead of creating a new unconfigured vi.fn()
- Remove DelegationCredentialRepository.test.ts empty prisma mock (different pattern)
- Remove vi.mock from inside beforeEach in intentToCreateOrg.handler.test.ts

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add comprehensive delegationCredential mock exports to prevent CI test failures

The vi.mock blocks for @calcom/app-store/delegationCredential were missing
exports that the code under test transitively imports (e.g.
enrichUsersWithDelegationCredentials, enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
buildAllCredentials, getFirstDelegationConferencingCredentialAppLocation).

Added all exports with passthrough implementations so the booking flow
works correctly without triggering real network requests.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: correct credential mock return shapes to match real module API

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: revert unintended yarn.lock changes

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-17 09:55:37 +05:30

611 lines
18 KiB
TypeScript

import { prisma } from "@calcom/prisma/__mocks__/prisma";
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
deduplicateCredentialsBasedOnSelectedCalendars,
deleteEvent,
getCalendarCredentials,
processEvent,
} from "./CalendarManager";
vi.mock("@calcom/prisma", () => ({
prisma,
}));
vi.mock("@calcom/app-store/_utils/getCalendar", () => ({
getCalendar: vi.fn(),
}));
vi.mock("@calcom/lib/constants", () => ({
ORGANIZER_EMAIL_EXEMPT_DOMAINS: "",
IS_PRODUCTION: false,
}));
vi.mock("@calcom/app-store/locations", () => ({
MeetLocationType: "integrations:google:meet",
}));
vi.mock("@calcom/lib/CalEventParser", () => ({
getRichDescription: vi.fn(() => "Test description"),
}));
vi.mock("@calcom/app-store/delegationCredential", () => ({
enrichHostsWithDelegationCredentials: vi.fn(),
getUsersCredentialsIncludeServiceAccountKey: vi.fn(),
getCredentialForSelectedCalendar: vi.fn(),
findUniqueDelegationCalendarCredential: vi.fn(),
getAllDelegationCredentialsForUserIncludeServiceAccountKey: vi.fn(),
getDelegationCredentialOrFindRegularCredential: vi.fn(),
}));
function buildCredential(data: {
type: string;
appId: string;
id: number;
delegatedToId: string | null;
user: { email: string } | null;
}) {
return {
...data,
teamId: null,
invalid: false,
key: { access_token: "DONT_MATTER" },
userId: 10000,
delegatedTo: {
serviceAccountKey: {
client_email: "DONT_MATTER",
tenant_id: "DONT_MATTER",
client_id: "DONT_MATTER",
private_key: "DONT_MATTER",
},
},
};
}
function buildCalendarEvent(overrides = {}) {
return {
type: "test-event",
title: "Test Event",
startTime: "2024-01-01T10:00:00Z",
endTime: "2024-01-01T11:00:00Z",
organizer: {
name: "Organizer",
email: "organizer@example.com",
timeZone: "UTC",
language: { translate: (x: string) => x, locale: "en" },
},
attendees: [
{
name: "Attendee 1",
email: "attendee1@example.com",
timeZone: "UTC",
language: { translate: (x: string) => x, locale: "en" },
},
{
name: "Attendee 2",
email: "attendee2@example.com",
timeZone: "UTC",
language: { translate: (x: string) => x, locale: "en" },
},
],
destinationCalendar: null,
hideOrganizerEmail: false,
location: null,
...overrides,
};
}
describe("CalendarManager tests", () => {
describe("fn: processEvent", () => {
it("should clear attendees when hideOrganizerEmail is true and no Zoho Calendar destination", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
destinationCalendar: [
{
integration: "google_calendar",
externalId: "calendar-1",
},
],
});
const result = processEvent(calEvent as any);
expect(result.attendees).toEqual([]);
});
it("should NOT clear attendees when hideOrganizerEmail is true and destination is Zoho Calendar", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
destinationCalendar: [
{
integration: "zoho_calendar",
externalId: "calendar-1",
},
],
});
const result = processEvent(calEvent as any);
// Zoho Calendar requires at least one attendee, so attendees should NOT be cleared
expect(result.attendees).toHaveLength(2);
expect(result.attendees[0].email).toBe("attendee1@example.com");
expect(result.attendees[1].email).toBe("attendee2@example.com");
});
it("should NOT clear attendees when hideOrganizerEmail is true and one of multiple destinations is Zoho Calendar", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
destinationCalendar: [
{
integration: "google_calendar",
externalId: "google-calendar-1",
},
{
integration: "zoho_calendar",
externalId: "zoho-calendar-1",
},
],
});
const result = processEvent(calEvent as any);
// Zoho Calendar is in the list, so attendees should NOT be cleared
expect(result.attendees).toHaveLength(2);
});
it("should NOT clear attendees when hideOrganizerEmail is false", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: false,
destinationCalendar: [
{
integration: "google_calendar",
externalId: "calendar-1",
},
],
});
const result = processEvent(calEvent as any);
expect(result.attendees).toHaveLength(2);
});
it("should NOT clear attendees when location is MeetLocationType even with hideOrganizerEmail true", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
location: "integrations:google:meet",
destinationCalendar: [
{
integration: "google_calendar",
externalId: "calendar-1",
},
],
});
const result = processEvent(calEvent as any);
expect(result.attendees).toHaveLength(2);
});
it("should handle null destinationCalendar with hideOrganizerEmail true", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
destinationCalendar: null,
});
const result = processEvent(calEvent as any);
expect(result.attendees).toEqual([]);
});
it("should handle empty destinationCalendar array with hideOrganizerEmail true", () => {
const calEvent = buildCalendarEvent({
hideOrganizerEmail: true,
destinationCalendar: [],
});
const result = processEvent(calEvent as any);
expect(result.attendees).toEqual([]);
});
it("should include calendarDescription from getRichDescription", () => {
const calEvent = buildCalendarEvent();
const result = processEvent(calEvent as any);
expect(result.calendarDescription).toBe("Test description");
});
it("should clear responses for seatsPerTimeSlot events", () => {
const calEvent = buildCalendarEvent({
seatsPerTimeSlot: 5,
responses: { field1: { label: "Field 1", value: "test" } },
userFieldsResponses: { field1: { label: "Field 1", value: "test" } },
additionalNotes: "Test notes",
customInputs: { input1: "value1" },
});
const result = processEvent(calEvent as any);
expect(result.responses).toBeNull();
expect(result.userFieldsResponses).toBeNull();
expect(result.additionalNotes).toBeNull();
expect(result.customInputs).toBeNull();
});
});
describe("fn: getCalendarCredentials", () => {
it("should only return credentials for calendar apps", async () => {
const googleCalendarCredentials = {
id: "1",
appId: "google-calendar",
type: "google_calendar",
userId: "3",
key: {
access_token: "google_calendar_key",
},
invalid: false,
delegatedTo: null,
};
const credentials = [
googleCalendarCredentials,
{
id: "2",
appId: "office365-video",
type: "office365_video",
userId: "4",
key: {
access_token: "office365_video_key",
},
invalid: false,
},
];
const calendarCredentials = getCalendarCredentials(credentials);
expect(calendarCredentials).toHaveLength(1);
expect(calendarCredentials[0].credential).toEqual(googleCalendarCredentials);
});
});
describe("fn: deduplicateCredentialsBasedOnSelectedCalendars", () => {
it("should remove a regular credential for which a delegation credential exists i.e. both are fetching events for same externalId", () => {
const calcomUser = {
email: "owner@hariombalhara.net",
};
const externalIdSameAsCalcomUserEmail = calcomUser.email;
const externalIdDifferentFromCalcomUserEmail = "hariombalhara@gmail.com";
// Delegation Credential(Calendar)
const delegationCredentialCalendarForCalcomEmail = buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: -1,
delegatedToId: "45fa8f04-e891-417b-98e1-abf48e8ae18a",
user: calcomUser,
});
// Delegation Credential(Conferencing)
const delegationCredentialConferencingForCalcomEmail = buildCredential({
type: "google_video",
appId: "google-meet",
id: -1,
delegatedToId: "45fa8f04-e891-417b-98e1-abf48e8ae18a",
user: calcomUser,
});
// Regular Credential for owner@hariombalhara.net
const regularCredentialForCalcomEmail = buildCredential({
id: 2,
appId: "google-calendar",
type: "google_calendar",
delegatedToId: null,
user: calcomUser,
});
// Regular Credential for hariombalhara@gmail.com
const regularCredentialForSomeOtherEmail = buildCredential({
id: 3,
appId: "google-calendar",
type: "google_calendar",
delegatedToId: null,
user: calcomUser,
});
const credentials = [
delegationCredentialCalendarForCalcomEmail,
delegationCredentialConferencingForCalcomEmail,
// This one is duplicate
regularCredentialForCalcomEmail,
// Regular Credential for hariombalhara@gmail.com
regularCredentialForSomeOtherEmail,
];
const selectedCalendars = [
{
id: "62f4f3b7-c65b-4199-8052-25b91ee25ff2",
userId: 23,
integration: "google_calendar",
externalId: externalIdDifferentFromCalcomUserEmail,
credentialId: regularCredentialForSomeOtherEmail.id,
delegationCredentialId: null,
eventTypeId: null,
},
{
id: "418e1bd0-7bde-4ea6-b03a-b2b6de6af497",
userId: 23,
integration: "google_calendar",
externalId: externalIdSameAsCalcomUserEmail,
credentialId: regularCredentialForCalcomEmail.id,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials,
selectedCalendars,
});
expect(uniqueCredentials).toHaveLength(3);
expect(uniqueCredentials).toEqual([
delegationCredentialCalendarForCalcomEmail,
delegationCredentialConferencingForCalcomEmail,
regularCredentialForSomeOtherEmail,
]);
});
it("should not remove a regular credential for which a delegation credential exists i.e. both are fetching events for same externalId if integration is different", () => {
const calcomUser = {
email: "owner@hariombalhara.net",
};
const externalIdSameAsCalcomUserEmail = calcomUser.email;
const externalIdDifferentFromCalcomUserEmail = "hariombalhara@gmail.com";
// Delegation Credential(Calendar) - wrong integration type
const delegationCredentialCalendarForCalcomEmail = buildCredential({
type: "google_calendar_wrong_type",
appId: "google-calendar",
id: -1,
delegatedToId: "45fa8f04-e891-417b-98e1-abf48e8ae18a",
user: calcomUser,
});
// Delegation Credential(Conferencing)
const delegationCredentialConferencingForCalcomEmail = buildCredential({
type: "google_video",
appId: "google-meet",
id: -1,
delegatedToId: "45fa8f04-e891-417b-98e1-abf48e8ae18a",
user: calcomUser,
});
// Regular Credential for owner@hariombalhara.net
const regularCredentialForCalcomEmail = buildCredential({
id: 2,
appId: "google-calendar",
type: "google_calendar",
delegatedToId: null,
user: calcomUser,
});
// Regular Credential for hariombalhara@gmail.com
const regularCredentialForSomeOtherEmail = buildCredential({
id: 3,
appId: "google-calendar",
type: "google_calendar",
delegatedToId: null,
user: calcomUser,
});
const credentials = [
delegationCredentialCalendarForCalcomEmail,
delegationCredentialConferencingForCalcomEmail,
// This one won't be removed as integration is different
regularCredentialForCalcomEmail,
// Regular Credential for hariombalhara@gmail.com
regularCredentialForSomeOtherEmail,
];
const selectedCalendars = [
{
id: "62f4f3b7-c65b-4199-8052-25b91ee25ff2",
userId: 23,
integration: "google_calendar",
externalId: externalIdDifferentFromCalcomUserEmail,
credentialId: regularCredentialForSomeOtherEmail.id,
delegationCredentialId: null,
eventTypeId: null,
},
{
id: "418e1bd0-7bde-4ea6-b03a-b2b6de6af497",
userId: 23,
integration: "google_calendar",
externalId: externalIdSameAsCalcomUserEmail,
credentialId: regularCredentialForCalcomEmail.id,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials,
selectedCalendars,
});
expect(uniqueCredentials).toHaveLength(4);
expect(uniqueCredentials).toEqual([
delegationCredentialCalendarForCalcomEmail,
delegationCredentialConferencingForCalcomEmail,
regularCredentialForCalcomEmail,
regularCredentialForSomeOtherEmail,
]);
});
it("should return empty array when credentials array is empty", () => {
const selectedCalendars = [
{
id: "calendar-1",
userId: 23,
integration: "google_calendar",
externalId: "test@example.com",
credentialId: 1,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials: [],
selectedCalendars,
});
expect(uniqueCredentials).toHaveLength(0);
});
it("should return original credentials when user email is not present", () => {
const credentialsWithoutUserEmail = [
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: 1,
delegatedToId: null,
user: null,
}),
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: -1,
delegatedToId: "delegation-1",
user: null,
}),
];
const selectedCalendars = [
{
id: "calendar-1",
userId: 23,
integration: "google_calendar",
externalId: "test@example.com",
credentialId: 1,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials: credentialsWithoutUserEmail,
selectedCalendars,
});
expect(uniqueCredentials).toEqual(credentialsWithoutUserEmail);
});
it("should return original credentials when no delegation credentials exist", () => {
const regularCredentials = [
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: 1,
delegatedToId: null,
user: { email: "test@example.com" },
}),
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: 2,
delegatedToId: null,
user: { email: "test@example.com" },
}),
];
const selectedCalendars = [
{
id: "calendar-1",
userId: 23,
integration: "google_calendar",
externalId: "test@example.com",
credentialId: 1,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials: regularCredentials,
selectedCalendars,
});
expect(uniqueCredentials).toEqual(regularCredentials);
});
it("should return original credentials when no matching selected calendars exist", () => {
const credentials = [
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: 1,
delegatedToId: "delegation-1",
user: { email: "test@example.com" },
}),
buildCredential({
type: "google_calendar",
appId: "google-calendar",
id: 2,
delegatedToId: null,
user: { email: "test@example.com" },
}),
];
const selectedCalendars = [
{
id: "calendar-1",
userId: 23,
integration: "google_calendar",
externalId: "different@example.com", // Different email than the credentials
credentialId: 1,
delegationCredentialId: null,
eventTypeId: null,
},
];
const uniqueCredentials = deduplicateCredentialsBasedOnSelectedCalendars({
credentials,
selectedCalendars,
});
expect(uniqueCredentials).toEqual(credentials);
});
});
describe("fn: deleteEvent", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("should return early when bookingRefUid is empty string", async () => {
vi.mocked(getCalendar).mockResolvedValue({ deleteEvent: vi.fn() } as any);
const credential = {
id: 1,
type: "google_calendar",
key: { access_token: "test_token" },
encryptedKey: null,
userId: 1,
user: { email: "test@example.com" },
teamId: null,
appId: "google-calendar",
invalid: false,
delegationCredentialId: null,
delegatedTo: null,
};
const result = await deleteEvent({
credential,
bookingRefUid: "",
event: buildCalendarEvent(),
externalCalendarId: "calendar-id",
});
expect(result).toEqual({});
});
});
});