fix: fallback to cal video when Google Meet used without Google Calendar as default app (#27630)

* fallback to daily video

* add tests
This commit is contained in:
Anik Dhabal Babu
2026-02-06 09:29:26 -03:00
committed by GitHub
parent c6125f359d
commit 617cdea683
2 changed files with 201 additions and 9 deletions
@@ -13,6 +13,7 @@ import {
createBookingScenario,
getDate,
getGoogleCalendarCredential,
getGoogleMeetCredential,
getAppleCalendarCredential,
TestData,
getOrganizer,
@@ -1339,6 +1340,191 @@ describe("handleNewBooking", () => {
},
timeout
);
test(
`should fallback to Cal Video when organizer's default conferencing app is Google Meet but destination calendar is NOT Google Calendar`,
async ({ emails }) => {
const handleNewBooking = getNewBookingHandler();
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: [getGoogleMeetCredential()],
selectedCalendars: [TestData.selectedCalendars.office365],
destinationCalendar: {
integration: "office365_calendar",
externalId: "organizer@outlook.com",
},
metadata: {
defaultConferencingApp: {
appSlug: "google-meet",
},
},
});
const scenarioData = getScenarioData({
webhooks: [
{
userId: organizer.id,
eventTriggers: ["BOOKING_CREATED"],
subscriberUrl: "http://my-webhook.example.com",
active: true,
eventTypeId: 1,
appId: null,
},
],
eventTypes: [
{
id: 1,
slotInterval: 30,
length: 30,
users: [
{
id: 101,
},
],
},
],
organizer,
apps: [TestData.apps["google-meet"], TestData.apps["daily-video"], TestData.apps["office365-calendar"]],
});
mockSuccessfulVideoMeetingCreation({
metadataLookupKey: "dailyvideo",
videoMeetingData: {
id: "MOCK_ID",
password: "MOCK_PASS",
url: "http://mock-dailyvideo.example.com/meeting-1",
},
});
await createBookingScenario(scenarioData);
const mockedBookingData = getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
},
},
});
const createdBooking = await handleNewBooking({
bookingData: mockedBookingData,
});
// Should fallback to Cal Video instead of Google Meet
expect(createdBooking).toEqual(
expect.objectContaining({
location: BookingLocations.CalVideo,
})
);
},
timeout
);
test(
`should use Google Meet when organizer's default conferencing app is Google Meet and destination calendar IS Google Calendar`,
async ({ emails }) => {
const handleNewBooking = getNewBookingHandler();
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(), getGoogleMeetCredential()],
selectedCalendars: [TestData.selectedCalendars.google],
destinationCalendar: {
integration: "google_calendar",
externalId: "organizer@google-calendar.com",
},
metadata: {
defaultConferencingApp: {
appSlug: "google-meet",
},
},
});
const scenarioData = getScenarioData({
webhooks: [
{
userId: organizer.id,
eventTriggers: ["BOOKING_CREATED"],
subscriberUrl: "http://my-webhook.example.com",
active: true,
eventTypeId: 1,
appId: null,
},
],
eventTypes: [
{
id: 1,
slotInterval: 30,
length: 30,
users: [
{
id: 101,
},
],
},
],
organizer,
apps: [TestData.apps["google-calendar"], TestData.apps["google-meet"], TestData.apps["daily-video"]],
});
mockSuccessfulVideoMeetingCreation({
metadataLookupKey: "googlevideo",
});
await mockCalendarToHaveNoBusySlots("googlecalendar", {
create: {
id: "GOOGLE_CALENDAR_EVENT_ID",
uid: "MOCK_ID",
appSpecificData: {
googleCalendar: {
hangoutLink: "https://meet.google.com/test-meeting",
},
},
},
});
await createBookingScenario(scenarioData);
const mockedBookingData = getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
},
},
});
const createdBooking = await handleNewBooking({
bookingData: mockedBookingData,
});
// Should use Google Meet since Google Calendar is the destination calendar
expect(createdBooking).toEqual(
expect.objectContaining({
location: BookingLocations.GoogleMeet,
})
);
},
timeout
);
});
describe("Video Meeting Creation", () => {
@@ -1350,22 +1350,28 @@ async function handler(
});
// use host default
if (locationBodyString == OrganizerDefaultConferencingAppType) {
if (locationBodyString === OrganizerDefaultConferencingAppType) {
const metadataParseResult = userMetadataSchema.safeParse(organizerUser.metadata);
const organizerMetadata = metadataParseResult.success ? metadataParseResult.data : undefined;
if (organizerMetadata?.defaultConferencingApp?.appSlug) {
const app = getAppFromSlug(organizerMetadata?.defaultConferencingApp?.appSlug);
const defaultApp = organizerMetadata?.defaultConferencingApp;
if (defaultApp?.appSlug) {
const app = getAppFromSlug(defaultApp.appSlug);
locationBodyString = app?.appData?.location?.type || locationBodyString;
if (isManagedEventType || isTeamEventType) {
organizerOrFirstDynamicGroupMemberDefaultLocationUrl =
organizerMetadata?.defaultConferencingApp?.appLink;
const mainHostCalendar = eventType.destinationCalendar || organizerUser.destinationCalendar;
if (locationBodyString === MeetLocationType && mainHostCalendar?.integration !== "google_calendar") {
locationBodyString = "integrations:daily";
organizerOrFirstDynamicGroupMemberDefaultLocationUrl = undefined;
} else if (isManagedEventType || isTeamEventType) {
organizerOrFirstDynamicGroupMemberDefaultLocationUrl = defaultApp?.appLink;
}
} else if (organizationDefaultLocation) {
locationBodyString = organizationDefaultLocation;
} else {
locationBodyString = "integrations:daily";
locationBodyString = organizationDefaultLocation || "integrations:daily";
}
}
const invitee: Invitee = [
{