mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
* feat: disable transcription setting in cal video * feat: add enable automatic recording feature * chore: only when organizer joins * chore: update name of variable * fix: improvements * chore: improvements * chore: add badge * refactor: cal video premium * tests: add tests for cal video * fix: use isOrganizer * Simplify type to remove 'as SessionUser' from new code --------- Co-authored-by: Benny Joo <[email protected]> Co-authored-by: Alex van Andel <[email protected]>
493 lines
18 KiB
TypeScript
493 lines
18 KiB
TypeScript
import type { DailyCall } from "@daily-co/daily-js";
|
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
import { BUTTONS } from "../button-states";
|
|
import { createCalVideoCallbacks } from "../cal-video-premium-features";
|
|
|
|
vi.mock("@calcom/lib/constants", () => ({
|
|
TRANSCRIPTION_STARTED_ICON: "/transcription-started-icon.svg",
|
|
RECORDING_IN_PROGRESS_ICON: "/recording-in-progress-icon.svg",
|
|
TRANSCRIPTION_STOPPED_ICON: "/transcription-stopped-icon.svg",
|
|
RECORDING_DEFAULT_ICON: "/recording-default-icon.svg",
|
|
}));
|
|
|
|
const mockDaily: DailyCall = {
|
|
startRecording: vi.fn(),
|
|
stopRecording: vi.fn(),
|
|
startTranscription: vi.fn(),
|
|
stopTranscription: vi.fn(),
|
|
updateCustomTrayButtons: vi.fn(),
|
|
} as unknown as DailyCall;
|
|
|
|
const createMockRecording = (isRecording = false) => ({
|
|
isRecording,
|
|
});
|
|
|
|
const createMockTranscription = (isTranscribing = false) => ({
|
|
isTranscribing,
|
|
});
|
|
|
|
describe("CalVideoPremiumFeatures - End-to-End Callback Tests", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("onMeetingJoined", () => {
|
|
it("should start transcription automatically when enabled and not already transcribing", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(false), // not transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: true,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onMeetingJoined();
|
|
|
|
expect(mockDaily.startTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("should start recording automatically when enabled and not already recording", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false), // not recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: true,
|
|
});
|
|
|
|
callbacks.onMeetingJoined();
|
|
|
|
expect(mockDaily.startRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).toHaveBeenCalledWith({
|
|
videoBitrate: 2000,
|
|
});
|
|
expect(mockDaily.startTranscription).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("should start both transcription and recording when both are enabled", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false),
|
|
transcription: createMockTranscription(false),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: true,
|
|
enableAutomaticRecordingForOrganizer: true,
|
|
});
|
|
|
|
callbacks.onMeetingJoined();
|
|
|
|
expect(mockDaily.startTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("should not start transcription when already transcribing", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(true), // already transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: true,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onMeetingJoined();
|
|
|
|
expect(mockDaily.startTranscription).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("should not start recording when already recording", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(true), // already recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: true,
|
|
});
|
|
|
|
callbacks.onMeetingJoined();
|
|
|
|
expect(mockDaily.startRecording).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("onCustomButtonClick - Recording Button", () => {
|
|
it("should start recording when click occurs on Recording button and recording is stopped", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false), // not recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.onCustomButtonClick({ button_id: "recording" });
|
|
|
|
expect(mockDaily.startRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).toHaveBeenCalledWith({
|
|
videoBitrate: 2000,
|
|
});
|
|
expect(mockDaily.stopRecording).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.WAIT_FOR_RECORDING_TO_START,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
|
|
it("should stop recording when click occurs on Recording button and recording is started", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(true), // currently recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.onCustomButtonClick({ button_id: "recording" });
|
|
|
|
expect(mockDaily.stopRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.WAIT_FOR_RECORDING_TO_STOP,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("onCustomButtonClick - Transcription Button", () => {
|
|
it("should start transcription when click occurs on Transcription button and transcription is stopped", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(false), // not transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.onCustomButtonClick({ button_id: "transcription" });
|
|
|
|
expect(mockDaily.startTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.stopTranscription).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.WAIT_FOR_TRANSCRIPTION_TO_START,
|
|
});
|
|
});
|
|
|
|
it("should stop transcription when click occurs on Transcription button and transcription is started", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(true), // currently transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.onCustomButtonClick({ button_id: "transcription" });
|
|
|
|
expect(mockDaily.stopTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startTranscription).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.WAIT_FOR_TRANSCRIPTION_TO_STOP,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("onRecordingStarted", () => {
|
|
it("should update custom tray buttons to show stop recording button", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onRecordingStarted();
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.STOP_RECORDING,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("onRecordingStopped", () => {
|
|
it("should update custom tray buttons to show start recording button", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onRecordingStopped();
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("onTranscriptionStarted", () => {
|
|
it("should update custom tray buttons to show stop transcription button", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onTranscriptionStarted();
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.STOP_TRANSCRIPTION,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("onTranscriptionStopped", () => {
|
|
it("should update custom tray buttons to show start transcription button", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.onTranscriptionStopped();
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.START_TRANSCRIPTION,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("toggleRecording", () => {
|
|
it("should start recording when not currently recording", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false), // not recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.toggleRecording();
|
|
|
|
expect(mockDaily.startRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).toHaveBeenCalledWith({
|
|
videoBitrate: 2000,
|
|
});
|
|
expect(mockDaily.stopRecording).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.WAIT_FOR_RECORDING_TO_START,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
|
|
it("should stop recording when currently recording", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(true), // currently recording
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.toggleRecording();
|
|
|
|
expect(mockDaily.stopRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.WAIT_FOR_RECORDING_TO_STOP,
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // current state included
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("toggleTranscription", () => {
|
|
it("should start transcription when not currently transcribing", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(false), // not transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.toggleTranscription();
|
|
|
|
expect(mockDaily.startTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.stopTranscription).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.WAIT_FOR_TRANSCRIPTION_TO_START,
|
|
});
|
|
});
|
|
|
|
it("should stop transcription when currently transcribing", async () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(true), // currently transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
await callbacks.toggleTranscription();
|
|
|
|
expect(mockDaily.stopTranscription).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startTranscription).not.toHaveBeenCalled();
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.START_RECORDING, // current state included
|
|
transcription: BUTTONS.WAIT_FOR_TRANSCRIPTION_TO_STOP,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("updateCustomTrayButtons", () => {
|
|
it("should update both recording and transcription buttons when both are shown", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false),
|
|
transcription: createMockTranscription(false),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.updateCustomTrayButtons({
|
|
recording: BUTTONS.STOP_RECORDING,
|
|
transcription: BUTTONS.STOP_TRANSCRIPTION,
|
|
});
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.STOP_RECORDING,
|
|
transcription: BUTTONS.STOP_TRANSCRIPTION,
|
|
});
|
|
});
|
|
|
|
it("should update only recording button when transcription button is not shown", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false),
|
|
transcription: createMockTranscription(false),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: false,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.updateCustomTrayButtons({
|
|
recording: BUTTONS.STOP_RECORDING,
|
|
});
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.STOP_RECORDING,
|
|
});
|
|
});
|
|
|
|
it("should update only transcription button when recording button is not shown", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(false),
|
|
transcription: createMockTranscription(false),
|
|
showRecordingButton: false,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.updateCustomTrayButtons({
|
|
transcription: BUTTONS.STOP_TRANSCRIPTION,
|
|
});
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
transcription: BUTTONS.STOP_TRANSCRIPTION,
|
|
});
|
|
});
|
|
|
|
it("should use current state when no override is provided", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(true), // currently recording
|
|
transcription: createMockTranscription(false), // not transcribing
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.updateCustomTrayButtons({});
|
|
|
|
expect(mockDaily.updateCustomTrayButtons).toHaveBeenCalledWith({
|
|
recording: BUTTONS.STOP_RECORDING, // because isRecording is true
|
|
transcription: BUTTONS.START_TRANSCRIPTION, // because isTranscribing is false
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("startRecording", () => {
|
|
it("should call daily.startRecording with correct parameters", () => {
|
|
const callbacks = createCalVideoCallbacks({
|
|
daily: mockDaily,
|
|
recording: createMockRecording(),
|
|
transcription: createMockTranscription(),
|
|
showRecordingButton: true,
|
|
showTranscriptionButton: true,
|
|
enableAutomaticTranscription: false,
|
|
enableAutomaticRecordingForOrganizer: false,
|
|
});
|
|
|
|
callbacks.startRecording();
|
|
|
|
expect(mockDaily.startRecording).toHaveBeenCalledTimes(1);
|
|
expect(mockDaily.startRecording).toHaveBeenCalledWith({
|
|
videoBitrate: 2000,
|
|
});
|
|
});
|
|
});
|
|
});
|