fix: bookings made via API don't include the specified location (#15067)
* fix booking via api not picking default location when unspecified * test:add tests for default location of event for booking * fix:failing tests --------- Co-authored-by: Shaik-Sirajuddin <sirajudddinshaik30@gmail.com> Co-authored-by: Alex van Andel <me@alexvanandel.com>
This commit is contained in:
co-authored by
Shaik-Sirajuddin
Alex van Andel
parent
5e09281974
commit
219b13d053
@@ -30,7 +30,7 @@ export function getMockRequestDataForBooking({
|
||||
responses: {
|
||||
email: string;
|
||||
name: string;
|
||||
location: { optionValue: ""; value: string };
|
||||
location?: { optionValue: ""; value: string };
|
||||
smsReminderNumber?: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1453,15 +1453,26 @@ async function handler(
|
||||
|
||||
const isManagedEventType = !!eventType.parentId;
|
||||
|
||||
// If location passed is empty , use default location of event
|
||||
// If location of event is not set , use host default
|
||||
if (locationBodyString.trim().length == 0) {
|
||||
if (eventType.locations.length > 0) {
|
||||
locationBodyString = eventType.locations[0].type;
|
||||
} else {
|
||||
locationBodyString = OrganizerDefaultConferencingAppType;
|
||||
}
|
||||
}
|
||||
// use host default
|
||||
if ((isManagedEventType || isTeamEventType) && 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);
|
||||
locationBodyString = app?.appData?.location?.type || locationBodyString;
|
||||
organizerOrFirstDynamicGroupMemberDefaultLocationUrl =
|
||||
organizerMetadata?.defaultConferencingApp?.appLink;
|
||||
if (isManagedEventType || isTeamEventType) {
|
||||
organizerOrFirstDynamicGroupMemberDefaultLocationUrl =
|
||||
organizerMetadata?.defaultConferencingApp?.appLink;
|
||||
}
|
||||
} else {
|
||||
locationBodyString = "integrations:daily";
|
||||
}
|
||||
@@ -1601,6 +1612,12 @@ async function handler(
|
||||
organizerEmail = eventType.secondaryEmail.email;
|
||||
}
|
||||
|
||||
//udpate cal event responses with latest location value , later used by webhook
|
||||
if (reqBody.calEventResponses)
|
||||
reqBody.calEventResponses["location"].value = {
|
||||
value: platformBookingLocation ?? bookingLocation,
|
||||
optionValue: "",
|
||||
};
|
||||
let evt: CalendarEvent = {
|
||||
bookerUrl,
|
||||
type: eventType.slug,
|
||||
|
||||
@@ -1010,6 +1010,273 @@ describe("handleNewBooking", () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe("Event's first location should be used when location is unspecied", () => {
|
||||
test(
|
||||
`should create a successful booking with right location app when event has location option as video client`,
|
||||
async ({ emails }) => {
|
||||
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).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: [getZoomAppCredential()],
|
||||
selectedCalendars: [TestData.selectedCalendars.google],
|
||||
});
|
||||
|
||||
const { req } = createMockNextJsRequest({
|
||||
method: "POST",
|
||||
body: getMockRequestDataForBooking({
|
||||
data: {
|
||||
eventTypeId: 1,
|
||||
responses: {
|
||||
email: booker.email,
|
||||
name: booker.name,
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
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,
|
||||
},
|
||||
],
|
||||
locations: [
|
||||
{
|
||||
type: BookingLocations.ZoomVideo,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
organizer,
|
||||
apps: [TestData.apps["zoomvideo"]],
|
||||
});
|
||||
mockSuccessfulVideoMeetingCreation({
|
||||
metadataLookupKey: "zoomvideo",
|
||||
});
|
||||
await createBookingScenario(scenarioData);
|
||||
const createdBooking = await handleNewBooking(req);
|
||||
expect(createdBooking).toContain({
|
||||
location: BookingLocations.ZoomVideo,
|
||||
});
|
||||
const iCalUID = expectICalUIDAsString(createdBooking.iCalUID);
|
||||
expectSuccessfulBookingCreationEmails({
|
||||
booking: {
|
||||
uid: createdBooking.uid!,
|
||||
},
|
||||
booker,
|
||||
organizer,
|
||||
emails,
|
||||
iCalUID,
|
||||
});
|
||||
expectBookingCreatedWebhookToHaveBeenFired({
|
||||
booker,
|
||||
organizer,
|
||||
location: BookingLocations.ZoomVideo,
|
||||
subscriberUrl: "http://my-webhook.example.com",
|
||||
videoCallUrl: "http://mock-zoomvideo.example.com",
|
||||
});
|
||||
},
|
||||
timeout
|
||||
);
|
||||
test(
|
||||
`should create a successful booking with right location when event's location is not a conferencing app
|
||||
`,
|
||||
//test with inPerson event type
|
||||
async ({ emails }) => {
|
||||
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).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: [],
|
||||
selectedCalendars: [TestData.selectedCalendars.google],
|
||||
});
|
||||
|
||||
const { req } = createMockNextJsRequest({
|
||||
method: "POST",
|
||||
body: getMockRequestDataForBooking({
|
||||
data: {
|
||||
eventTypeId: 1,
|
||||
responses: {
|
||||
email: booker.email,
|
||||
name: booker.name,
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
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,
|
||||
},
|
||||
],
|
||||
locations: [{ type: "inPerson", address: "Seoul" }],
|
||||
},
|
||||
],
|
||||
organizer,
|
||||
apps: [TestData.apps["daily-video"]],
|
||||
});
|
||||
await createBookingScenario(scenarioData);
|
||||
const createdBooking = await handleNewBooking(req);
|
||||
expect(createdBooking).toContain({
|
||||
location: "Seoul",
|
||||
});
|
||||
const iCalUID = expectICalUIDAsString(createdBooking.iCalUID);
|
||||
expectSuccessfulBookingCreationEmails({
|
||||
booking: {
|
||||
uid: createdBooking.uid!,
|
||||
},
|
||||
booker,
|
||||
organizer,
|
||||
emails,
|
||||
iCalUID,
|
||||
});
|
||||
expectBookingCreatedWebhookToHaveBeenFired({
|
||||
booker,
|
||||
organizer,
|
||||
location: "Seoul",
|
||||
subscriberUrl: "http://my-webhook.example.com",
|
||||
});
|
||||
},
|
||||
timeout
|
||||
);
|
||||
test(
|
||||
`should create a successful booking with organizer default conferencing app when event's location is not set`,
|
||||
async ({ emails }) => {
|
||||
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).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: [getZoomAppCredential()],
|
||||
selectedCalendars: [TestData.selectedCalendars.google],
|
||||
metadata: {
|
||||
defaultConferencingApp: {
|
||||
appSlug: "zoom",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { req } = createMockNextJsRequest({
|
||||
method: "POST",
|
||||
body: getMockRequestDataForBooking({
|
||||
data: {
|
||||
eventTypeId: 1,
|
||||
responses: {
|
||||
email: booker.email,
|
||||
name: booker.name,
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
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["zoomvideo"], TestData.apps["daily-video"]],
|
||||
});
|
||||
mockSuccessfulVideoMeetingCreation({
|
||||
metadataLookupKey: "zoomvideo",
|
||||
});
|
||||
await createBookingScenario(scenarioData);
|
||||
const createdBooking = await handleNewBooking(req);
|
||||
expect(createdBooking).toContain({
|
||||
location: BookingLocations.ZoomVideo,
|
||||
});
|
||||
const iCalUID = expectICalUIDAsString(createdBooking.iCalUID);
|
||||
expectSuccessfulBookingCreationEmails({
|
||||
booking: {
|
||||
uid: createdBooking.uid!,
|
||||
},
|
||||
booker,
|
||||
organizer,
|
||||
emails,
|
||||
iCalUID,
|
||||
});
|
||||
expectBookingCreatedWebhookToHaveBeenFired({
|
||||
booker,
|
||||
organizer,
|
||||
location: BookingLocations.ZoomVideo,
|
||||
subscriberUrl: "http://my-webhook.example.com",
|
||||
videoCallUrl: "http://mock-zoomvideo.example.com",
|
||||
});
|
||||
},
|
||||
timeout
|
||||
);
|
||||
});
|
||||
|
||||
describe("Video Meeting Creation", () => {
|
||||
test(
|
||||
`should create a successful booking with Zoom if used`,
|
||||
|
||||
+1
-1
@@ -1287,7 +1287,7 @@ describe("handleNewBooking", () => {
|
||||
expectBookingCreatedWebhookToHaveBeenFired({
|
||||
booker,
|
||||
organizer,
|
||||
location: OrganizerDefaultConferencingAppType,
|
||||
location: BookingLocations.CalVideo,
|
||||
subscriberUrl: "http://my-webhook.example.com",
|
||||
videoCallUrl: `${WEBAPP_URL}/video/${createdBooking.uid}`,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user