Skip to content

Commit 300b9c9

Browse files
fix: preserve metadata fields during partial event type updates (calcom#25621)
* fix: preserve metadata fields during partial event type updates - Fix multipleDuration (lengthInMinutesOptions) being reset to undefined on partial updates - Fix bookerLayouts being reset to undefined on partial updates - Fix requiresConfirmationThreshold being reset to undefined on partial updates - Add e2e test for lengthInMinutesOptions preservation Co-Authored-By: morgan@cal.com <morgan@cal.com> * test: expand metadata preservation test to include bookerLayouts and confirmationPolicy Co-Authored-By: morgan@cal.com <morgan@cal.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 5ac3743 commit 300b9c9

2 files changed

Lines changed: 84 additions & 4 deletions

File tree

apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,16 @@ export class InputEventTypesService_2024_06_14 {
229229

230230
const metadata: EventTypeMetadata = {
231231
...metadataTransformed,
232-
bookerLayouts: this.transformInputBookerLayouts(bookerLayouts),
233-
requiresConfirmationThreshold:
234-
confirmationPolicyTransformed?.requiresConfirmationThreshold ?? undefined,
235-
multipleDuration: lengthInMinutesOptions,
232+
...(bookerLayouts !== undefined
233+
? { bookerLayouts: this.transformInputBookerLayouts(bookerLayouts) }
234+
: {}),
235+
...(confirmationPolicy !== undefined
236+
? {
237+
requiresConfirmationThreshold:
238+
confirmationPolicyTransformed?.requiresConfirmationThreshold ?? undefined,
239+
}
240+
: {}),
241+
...(lengthInMinutesOptions !== undefined ? { multipleDuration: lengthInMinutesOptions } : {}),
236242
};
237243

238244
const eventType = {

apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,80 @@ describe("Organizations Event Types Endpoints", () => {
12941294
expect(updatedEventType.bookingRequiresAuthentication).toEqual(false);
12951295
});
12961296

1297+
it("should preserve metadata fields when doing partial update", async () => {
1298+
const createBody: CreateTeamEventTypeInput_2024_06_14 = {
1299+
title: "Coding consultation with metadata",
1300+
slug: `organizations-event-types-metadata-${randomString()}`,
1301+
description: "Our team will review your codebase.",
1302+
lengthInMinutes: 30,
1303+
lengthInMinutesOptions: [15, 30, 60],
1304+
locations: [
1305+
{
1306+
type: "integration",
1307+
integration: "cal-video",
1308+
},
1309+
],
1310+
schedulingType: "COLLECTIVE",
1311+
hosts: [
1312+
{
1313+
userId: teammate1.id,
1314+
},
1315+
],
1316+
bookerLayouts: {
1317+
enabledLayouts: [
1318+
BookerLayoutsInputEnum_2024_06_14.column,
1319+
BookerLayoutsInputEnum_2024_06_14.month,
1320+
BookerLayoutsInputEnum_2024_06_14.week,
1321+
],
1322+
defaultLayout: BookerLayoutsInputEnum_2024_06_14.month,
1323+
},
1324+
confirmationPolicy: {
1325+
type: ConfirmationPolicyEnum.TIME,
1326+
noticeThreshold: {
1327+
count: 60,
1328+
unit: NoticeThresholdUnitEnum.MINUTES,
1329+
},
1330+
blockUnconfirmedBookingsInBooker: true,
1331+
},
1332+
};
1333+
1334+
const createResponse = await request(app.getHttpServer())
1335+
.post(`/v2/organizations/${org.id}/teams/${team.id}/event-types`)
1336+
.send(createBody)
1337+
.expect(201);
1338+
1339+
const createdEventType: TeamEventTypeOutput_2024_06_14 = createResponse.body.data;
1340+
1341+
// Verify all metadata fields are set correctly on creation
1342+
expect(createdEventType.lengthInMinutesOptions).toBeDefined();
1343+
expect(createdEventType.lengthInMinutesOptions).toEqual([15, 30, 60]);
1344+
expect(createdEventType.bookerLayouts).toBeDefined();
1345+
expect(createdEventType.bookerLayouts).toEqual(createBody.bookerLayouts);
1346+
expect(createdEventType.confirmationPolicy).toBeDefined();
1347+
expect(createdEventType.confirmationPolicy).toEqual(createBody.confirmationPolicy);
1348+
1349+
// Now do a partial update that only changes a different field (not metadata fields)
1350+
const updateBody: UpdateTeamEventTypeInput_2024_06_14 = {
1351+
bookingRequiresAuthentication: false,
1352+
};
1353+
1354+
const updateResponse = await request(app.getHttpServer())
1355+
.patch(`/v2/organizations/${org.id}/teams/${team.id}/event-types/${createdEventType.id}`)
1356+
.send(updateBody)
1357+
.expect(200);
1358+
1359+
const updatedEventType: TeamEventTypeOutput_2024_06_14 = updateResponse.body.data;
1360+
1361+
// Verify that all metadata fields are preserved and not reset to undefined
1362+
expect(updatedEventType.lengthInMinutesOptions).toBeDefined();
1363+
expect(updatedEventType.lengthInMinutesOptions).toEqual([15, 30, 60]);
1364+
expect(updatedEventType.bookerLayouts).toBeDefined();
1365+
expect(updatedEventType.bookerLayouts).toEqual(createBody.bookerLayouts);
1366+
expect(updatedEventType.confirmationPolicy).toBeDefined();
1367+
expect(updatedEventType.confirmationPolicy).toEqual(createBody.confirmationPolicy);
1368+
expect(updatedEventType.bookingRequiresAuthentication).toEqual(false);
1369+
});
1370+
12971371
function evaluateHost(expected: Host, received: Host | undefined) {
12981372
expect(expected.userId).toEqual(received?.userId);
12991373
expect(expected.mandatory).toEqual(received?.mandatory);

0 commit comments

Comments
 (0)