* fix: event not created * Update CalendarManager.ts * Add tests: packages/features/calendars/lib/CalendarManager.ts Generated by Paragon from proposal for PR #27675 * Add tests: packages/features/calendars/lib/CalendarManager.test.ts Generated by Paragon from proposal for PR #27675 * Export processEvent for testing and refactor logic * Fix missing newline at end of CalendarManager.test.ts Add missing newline at the end of the file. * fix test
564 lines
17 KiB
TypeScript
564 lines
17 KiB
TypeScript
import { prisma } from "@calcom/prisma/__mocks__/prisma";
|
|
|
|
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
|
|
import {
|
|
getCalendarCredentials,
|
|
deduplicateCredentialsBasedOnSelectedCalendars,
|
|
processEvent,
|
|
} from "./CalendarManager";
|
|
|
|
vi.mock("@calcom/prisma", () => ({
|
|
prisma,
|
|
}));
|
|
|
|
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"),
|
|
}));
|
|
|
|
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);
|
|
});
|
|
});
|
|
});
|