From ae4e0f8893051675f347e30fd2d50d3c6968dc29 Mon Sep 17 00:00:00 2001 From: Amit Sharma <74371312+Amit91848@users.noreply.github.com> Date: Fri, 17 May 2024 19:26:17 +0530 Subject: [PATCH] chore: Add test for booking cancelled webhook (#14940) * chore: Add test for booking cancelled webhook * added unit test * assertions to check booking created successfully * remove booking cancelled e2e * test: add webhook cancelled test * chore: remove old test --------- Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Udit Takkar --- .../web/test/utils/bookingScenario/expects.ts | 19 +-- .../handleCancelBooking/test/webhook.test.ts | 133 ++++++++++++++++++ 2 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 packages/features/bookings/lib/handleCancelBooking/test/webhook.test.ts diff --git a/apps/web/test/utils/bookingScenario/expects.ts b/apps/web/test/utils/bookingScenario/expects.ts index 17af1c6d1a..3f9bf23445 100644 --- a/apps/web/test/utils/bookingScenario/expects.ts +++ b/apps/web/test/utils/bookingScenario/expects.ts @@ -290,12 +290,16 @@ export function expectWebhookToHaveBeenCalledWith( if (parsedBody.payload) { if (data.payload) { - if (data.payload.metadata !== undefined) { + if (!!data.payload.metadata) { expect(parsedBody.payload.metadata).toEqual(expect.objectContaining(data.payload.metadata)); } - if (data.payload.responses !== undefined) + if (!!data.payload.responses) expect(parsedBody.payload.responses).toEqual(expect.objectContaining(data.payload.responses)); - const { responses: _1, metadata: _2, ...remainingPayload } = data.payload; + + if (!!data.payload.organizer) + expect(parsedBody.payload.organizer).toEqual(expect.objectContaining(data.payload.organizer)); + + const { responses: _1, metadata: _2, organizer: _3, ...remainingPayload } = data.payload; expect(parsedBody.payload).toEqual(expect.objectContaining(remainingPayload)); } } @@ -989,20 +993,17 @@ export function expectBookingCancelledWebhookToHaveBeenFired({ ...payload, metadata: null, responses: { - booker: { - label: "your_name", + name: { + label: "name", value: booker.name, - isHidden: false, }, email: { - label: "email_address", + label: "email", value: booker.email, - isHidden: false, }, location: { label: "location", value: { optionValue: "", value: location }, - isHidden: false, }, }, }, diff --git a/packages/features/bookings/lib/handleCancelBooking/test/webhook.test.ts b/packages/features/bookings/lib/handleCancelBooking/test/webhook.test.ts new file mode 100644 index 0000000000..a9eda5e152 --- /dev/null +++ b/packages/features/bookings/lib/handleCancelBooking/test/webhook.test.ts @@ -0,0 +1,133 @@ +import { describe } from "vitest"; + +import { BookingStatus } from "@calcom/prisma/enums"; +import { test } from "@calcom/web/test/fixtures/fixtures"; +import { + BookingLocations, + createBookingScenario, + getBooker, + getGoogleCalendarCredential, + getOrganizer, + getScenarioData, + mockCalendarToHaveNoBusySlots, + mockSuccessfulVideoMeetingCreation, + TestData, + getDate, +} from "@calcom/web/test/utils/bookingScenario/bookingScenario"; +import { createMockNextJsRequest } from "@calcom/web/test/utils/bookingScenario/createMockNextJsRequest"; +import { expectBookingCancelledWebhookToHaveBeenFired } from "@calcom/web/test/utils/bookingScenario/expects"; +import { setupAndTeardown } from "@calcom/web/test/utils/bookingScenario/setupAndTeardown"; + +describe("Cancel Booking", () => { + setupAndTeardown(); + + test("Should trigger BOOKING_CANCELLED webhook", async () => { + const handleCancelBooking = (await import("@calcom/features/bookings/lib/handleCancelBooking")).default; + + const booker = getBooker({ + email: "booker@example.com", + name: "Booker", + }); + + const organizer = getOrganizer({ + name: "Organizer", + email: "organizer@example.com", + id: 101, + schedules: [TestData.schedules.IstWorkHours], + credentials: [getGoogleCalendarCredential()], + selectedCalendars: [TestData.selectedCalendars.google], + }); + + const uidOfBookingToBeCancelled = "h5Wv3eHgconAED2j4gcVhP"; + const idOfBookingToBeCancelled = 1020; + const { dateString: plus1DateString } = getDate({ dateIncrement: 1 }); + + await createBookingScenario( + getScenarioData({ + webhooks: [ + { + userId: organizer.id, + eventTriggers: ["BOOKING_CANCELLED"], + subscriberUrl: "http://my-webhook.example.com", + active: true, + eventTypeId: 1, + appId: null, + }, + ], + eventTypes: [ + { + id: 1, + slotInterval: 30, + length: 30, + users: [ + { + id: 101, + }, + ], + }, + ], + bookings: [ + { + id: idOfBookingToBeCancelled, + uid: uidOfBookingToBeCancelled, + eventTypeId: 1, + userId: 101, + responses: { + email: booker.email, + name: booker.name, + location: { optionValue: "", value: BookingLocations.CalVideo }, + }, + status: BookingStatus.ACCEPTED, + startTime: `${plus1DateString}T05:00:00.000Z`, + endTime: `${plus1DateString}T05:15:00.000Z`, + metadata: { + videoCallUrl: "https://existing-daily-video-call-url.example.com", + }, + }, + ], + organizer, + apps: [TestData.apps["daily-video"]], + }) + ); + mockSuccessfulVideoMeetingCreation({ + metadataLookupKey: "dailyvideo", + videoMeetingData: { + id: "MOCK_ID", + password: "MOCK_PASS", + url: `http://mock-dailyvideo.example.com/meeting-1`, + }, + }); + + mockCalendarToHaveNoBusySlots("googlecalendar", { + create: { + id: "MOCKED_GOOGLE_CALENDAR_EVENT_ID", + }, + }); + + const { req } = createMockNextJsRequest({ + method: "POST", + body: { + id: idOfBookingToBeCancelled, + uid: uidOfBookingToBeCancelled, + }, + }); + + await handleCancelBooking(req); + + expectBookingCancelledWebhookToHaveBeenFired({ + booker, + organizer, + location: BookingLocations.CalVideo, + subscriberUrl: "http://my-webhook.example.com", + payload: { + organizer: { + id: organizer.id, + username: organizer.username, + email: organizer.email, + name: organizer.name, + timeZone: organizer.timeZone, + }, + }, + }); + }); +});