Files
Udit TakkarGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f2a44279fe refactor: evt calendar event builder (#27203)
* refactor: evt creation

* refactor: evt creation

* refactor: evt creation

* fix: type

* test: update unit tests

* chore: add comments

* fix: handle undefined in withConditional to match NonNullable<T> type

Co-Authored-By: unknown <>

* refactor: evt

* fix: type err

* refactor: remove add videoCallData

* refactor: use error with code

* test: update unit test

* refactor: feedback

* refactor: remove conditional

* refactor: more strict types

* fix: type err

* chor: remove un used

* refactor:  improve recurring event handling in RegularBookingService

Removed unnecessary whitespace and clarified comments regarding the attachment of recurring configurations in the booking handler. Adjusted logic to ensure that recurring settings are only applied when relevant.

* refactor: test

* fix: type error

* refactor: improve code

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-19 03:50:48 +09:00

177 lines
5.7 KiB
TypeScript

import { vi, describe, it, expect, beforeEach } from "vitest";
import { SchedulingType } from "@calcom/prisma/enums";
import { computeTeamData } from "../../service/RegularBookingService";
vi.mock("@calcom/i18n/server", () => ({
getTranslation: vi.fn().mockResolvedValue((key: string) => key),
}));
vi.mock("@calcom/prisma", () => {
return {
default: vi.fn(),
prisma: {},
};
});
vi.mock("@calcom/app-store/_utils/calendars/processExternalId", () => ({
default: vi.fn((dc) => `external-${dc?.externalId ?? "id"}`),
}));
const baseUser = (overrides: Record<string, unknown> = {}) => ({
id: 1,
name: "Alice",
email: "[email protected]",
timeZone: "Europe/Paris",
locale: "fr",
destinationCalendar: {
id: 123,
integration: "google",
externalId: "ext-123",
primaryEmail: "[email protected]",
userId: 1,
eventTypeId: null,
credentialId: null,
delegationCredentialId: null,
domainWideDelegationCredentialId: null,
},
isFixed: true,
...overrides,
});
describe("computeTeamData", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("returns empty arrays if isTeamEventType is false", async () => {
const result = await computeTeamData({
isTeamEventType: false,
schedulingType: SchedulingType.COLLECTIVE,
users: [baseUser()],
organizerEmail: "[email protected]",
});
expect(result.teamMembers).toHaveLength(0);
expect(result.teamDestinationCalendars).toHaveLength(0);
});
it("returns empty arrays if schedulingType is null", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: null,
users: [baseUser()],
organizerEmail: "[email protected]",
});
expect(result.teamMembers).toHaveLength(0);
expect(result.teamDestinationCalendars).toHaveLength(0);
});
it("filters out the organizer from team members", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.COLLECTIVE,
users: [baseUser({ email: "[email protected]" }), baseUser({ id: 2, email: "[email protected]" })],
organizerEmail: "[email protected]",
});
const memberEmails = result.teamMembers.map((m) => m.email);
expect(memberEmails).not.toContain("[email protected]");
expect(memberEmails).toContain("[email protected]");
});
it("includes destinationCalendars for COLLECTIVE scheduling type", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.COLLECTIVE,
users: [baseUser({ id: 2, email: "[email protected]" })],
organizerEmail: "[email protected]",
});
expect(result.teamDestinationCalendars).toHaveLength(1);
expect(result.teamDestinationCalendars[0].externalId).toBe("external-ext-123");
});
it("does not include destinationCalendars for ROUND_ROBIN scheduling type", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.ROUND_ROBIN,
users: [baseUser({ id: 2, email: "[email protected]" })],
organizerEmail: "[email protected]",
});
expect(result.teamDestinationCalendars).toHaveLength(0);
});
it("includes both fixed and non-fixed users for ROUND_ROBIN", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.ROUND_ROBIN,
users: [
baseUser({ id: 2, isFixed: false, email: "[email protected]" }),
baseUser({ id: 3, isFixed: true, email: "[email protected]" }),
],
organizerEmail: "[email protected]",
});
const memberEmails = result.teamMembers.map((m) => m.email);
expect(memberEmails).toContain("[email protected]");
expect(memberEmails).toContain("[email protected]");
});
it("includes all non-fixed users for ROUND_ROBIN when multiple exist", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.ROUND_ROBIN,
users: [
baseUser({ id: 3, isFixed: true, email: "[email protected]" }),
baseUser({ id: 2, isFixed: false, email: "[email protected]" }),
baseUser({ id: 4, isFixed: false, email: "[email protected]" }),
],
organizerEmail: "[email protected]",
});
const memberEmails = result.teamMembers.map((m) => m.email);
expect(memberEmails).toContain("[email protected]");
expect(memberEmails).toContain("[email protected]");
expect(memberEmails).toContain("[email protected]");
});
it("returns team members with correct structure", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.COLLECTIVE,
users: [baseUser({ id: 2, email: "[email protected]", name: "Member Name" })],
organizerEmail: "[email protected]",
});
expect(result.teamMembers).toHaveLength(1);
expect(result.teamMembers[0]).toEqual({
id: 2,
email: "[email protected]",
name: "Member Name",
firstName: "",
lastName: "",
timeZone: "Europe/Paris",
language: {
translate: expect.any(Function),
locale: "fr",
},
});
});
it("handles users without destinationCalendar for COLLECTIVE", async () => {
const result = await computeTeamData({
isTeamEventType: true,
schedulingType: SchedulingType.COLLECTIVE,
users: [baseUser({ id: 2, email: "[email protected]", destinationCalendar: null })],
organizerEmail: "[email protected]",
});
expect(result.teamMembers).toHaveLength(1);
expect(result.teamDestinationCalendars).toHaveLength(0);
});
});