Files
calendar/apps/web/lib/daily-webhook/tests/recorded-daily-video.test.ts
T
884ccc9b48 feat: RECORDING_TRANSCRIPTION_GENERATED webhook (#15589)
* feat: RECORDING_TRANSCRIPTION_READY webhook

* refactor: split into diff files and restructuring

* feat: finish batch processor finished

* chore: types

* fix: type error

* chore: change name of triggger

* test: add unit test

* fix: type

* fix: type err

* chore: test

* feat: add booking reference repository and other imp

* chore: log

* fix: import

* chore: type error

* fix: update test

* fix: test

* fix: test

* fix: add timeout

* chore: move beforeEach

* Mock missing env variables to test. These vars are not set in CI

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
2024-07-05 07:39:23 +00:00

245 lines
6.8 KiB
TypeScript

import {
createBookingScenario,
getScenarioData,
TestData,
getDate,
getMockBookingAttendee,
getOrganizer,
getBooker,
} from "@calcom/web/test/utils/bookingScenario/bookingScenario";
import { expectWebhookToHaveBeenCalledWith } from "@calcom/web/test/utils/bookingScenario/expects";
import type { Request, Response } from "express";
import type { NextApiRequest, NextApiResponse } from "next";
import { createMocks } from "node-mocks-http";
import { describe, afterEach, test, vi, beforeEach, beforeAll } from "vitest";
import { appStoreMetadata } from "@calcom/app-store/apps.metadata.generated";
import { getRoomNameFromRecordingId, getBatchProcessorJobAccessLink } from "@calcom/app-store/dailyvideo/lib";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/core/videoClient";
import prisma from "@calcom/prisma";
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
import { BookingStatus } from "@calcom/prisma/enums";
import handler from "@calcom/web/pages/api/recorded-daily-video";
type CustomNextApiRequest = NextApiRequest & Request;
type CustomNextApiResponse = NextApiResponse & Response;
beforeAll(() => {
// Setup env vars
vi.stubEnv("SENDGRID_API_KEY", "FAKE_SENDGRID_API_KEY");
vi.stubEnv("SENDGRID_EMAIL", "FAKE_SENDGRID_EMAIL");
});
vi.mock("@calcom/app-store/dailyvideo/lib", () => {
return {
getRoomNameFromRecordingId: vi.fn(),
getBatchProcessorJobAccessLink: vi.fn(),
};
});
vi.mock("@calcom/core/videoClient", () => {
return {
getDownloadLinkOfCalVideoByRecordingId: vi.fn(),
};
});
const BATCH_PROCESSOR_JOB_FINSISHED_PAYLOAD = {
version: "1.1.0",
type: "batch-processor.job-finished",
id: "77b1cb9e-cd79-43cd-bad6-3ccaccba26be",
payload: {
id: "77b1cb9e-cd79-43cd-bad6-3ccaccba26be",
status: "finished",
input: {
sourceType: "recordingId",
recordingId: "eb9e84de-783e-4e14-875d-94700ee4b976",
},
output: {
transcription: [
{
format: "json",
s3Config: {
key: "transcript.json",
bucket: "daily-bucket",
region: "us-west-2",
},
},
{
format: "srt",
s3Config: {
key: "transcript.srt",
bucket: "daily-bucket",
region: "us-west-2",
},
},
{
format: "txt",
s3Config: {
key: "transcript.txt",
bucket: "daily-bucket",
region: "us-west-2",
},
},
{
format: "vtt",
s3Config: {
key: "transcript.vtt",
bucket: "daily-bucket",
region: "us-west-2",
},
},
],
},
},
event_ts: 1717688213.803,
};
const timeout = process.env.CI ? 5000 : 20000;
const TRANSCRIPTION_ACCESS_LINK = {
id: "MOCK_ID",
preset: "transcript",
status: "finished",
transcription: [
{
format: "json",
link: "https://download.json",
},
{
format: "srt",
link: "https://download.srt",
},
],
};
describe("Handler: /api/recorded-daily-video", () => {
beforeEach(() => {
fetchMock.resetMocks();
});
afterEach(() => {
vi.resetAllMocks();
fetchMock.resetMocks();
});
test(
`Batch Processor Job finished triggers RECORDING_TRANSCRIPTION_GENERATED webhooks`,
async () => {
const organizer = getOrganizer({
name: "Organizer",
email: "organizer@example.com",
id: 101,
schedules: [TestData.schedules.IstWorkHours],
});
const bookingUid = "n5Wv3eHgconAED2j4gcVhP";
const iCalUID = `${bookingUid}@Cal.com`;
const subscriberUrl = "http://my-webhook.example.com";
const recordingDownloadLink = "https://download-link.com";
const { dateString: plus1DateString } = getDate({ dateIncrement: 1 });
const booker = getBooker({
email: "booker@example.com",
name: "Booker",
});
await createBookingScenario(
getScenarioData({
webhooks: [
{
userId: organizer.id,
eventTriggers: [WebhookTriggerEvents.RECORDING_TRANSCRIPTION_GENERATED],
subscriberUrl,
active: true,
eventTypeId: 1,
appId: null,
},
],
eventTypes: [
{
id: 1,
slotInterval: 15,
length: 15,
users: [
{
id: 101,
},
],
},
],
bookings: [
{
uid: bookingUid,
eventTypeId: 1,
status: BookingStatus.ACCEPTED,
startTime: `${plus1DateString}T05:00:00.000Z`,
endTime: `${plus1DateString}T05:15:00.000Z`,
userId: organizer.id,
metadata: {
videoCallUrl: "https://existing-daily-video-call-url.example.com",
},
references: [
{
type: appStoreMetadata.dailyvideo.type,
uid: "MOCK_ID",
meetingId: "MOCK_ID",
meetingPassword: "MOCK_PASS",
meetingUrl: "http://mock-dailyvideo.example.com",
credentialId: null,
},
],
attendees: [
getMockBookingAttendee({
id: 2,
name: booker.name,
email: booker.email,
locale: "en",
timeZone: "Asia/Kolkata",
noShow: false,
}),
],
iCalUID,
},
],
organizer,
apps: [TestData.apps["daily-video"]],
})
);
vi.mocked(getRoomNameFromRecordingId).mockResolvedValue("MOCK_ID");
vi.mocked(getBatchProcessorJobAccessLink).mockResolvedValue(TRANSCRIPTION_ACCESS_LINK);
vi.mocked(getDownloadLinkOfCalVideoByRecordingId).mockResolvedValue({
download_link: recordingDownloadLink,
});
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "POST",
body: BATCH_PROCESSOR_JOB_FINSISHED_PAYLOAD,
prisma,
});
await handler(req, res);
await expectWebhookToHaveBeenCalledWith(subscriberUrl, {
triggerEvent: WebhookTriggerEvents.RECORDING_TRANSCRIPTION_GENERATED,
payload: {
type: "Test Booking Title",
uid: bookingUid,
downloadLinks: {
transcription: TRANSCRIPTION_ACCESS_LINK.transcription,
recording: recordingDownloadLink,
},
organizer: {
email: organizer.email,
name: organizer.name,
timeZone: organizer.timeZone,
language: { locale: "en" },
utcOffset: 330,
},
},
});
},
timeout
);
});