fix: time and timeUnit partial update workflows api v2 (#26503)
* test: add e2e test for workflow partial update time/timeUnit preservation Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: time and timeUnit partial update workflows api v2 --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
morgan@cal.com <morgan@cal.com>
Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
ac3699dcb4
commit
dbc6b15ffc
+54
@@ -905,6 +905,60 @@ describe("OrganizationsTeamsWorkflowsController (E2E)", () => {
|
||||
.send(partialUpdateDto)
|
||||
.expect(401);
|
||||
});
|
||||
|
||||
it("should preserve time and timeUnit when not provided in partial update", async () => {
|
||||
const workflowWithOffset = await request(app.getHttpServer())
|
||||
.post(basePath)
|
||||
.set({ Authorization: `Bearer cal_test_${apiKeyString}` })
|
||||
.send({
|
||||
name: `Workflow With Offset ${randomString()}`,
|
||||
activation: {
|
||||
isActiveOnAllEventTypes: true,
|
||||
activeOnEventTypeIds: [],
|
||||
},
|
||||
trigger: {
|
||||
type: BEFORE_EVENT,
|
||||
offset: {
|
||||
value: 2,
|
||||
unit: DAY,
|
||||
},
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
stepNumber: 1,
|
||||
action: "email_attendee",
|
||||
recipient: ATTENDEE,
|
||||
template: REMINDER,
|
||||
sender: "CalcomE2ETest",
|
||||
includeCalendarEvent: true,
|
||||
message: {
|
||||
subject: "Upcoming: {EVENT_NAME}",
|
||||
html: "<p>Reminder for your event {EVENT_NAME}.</p>",
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(201);
|
||||
|
||||
const workflowId = workflowWithOffset.body.data.id;
|
||||
expect(workflowWithOffset.body.data.trigger?.offset?.value).toEqual(2);
|
||||
expect(workflowWithOffset.body.data.trigger?.offset?.unit).toEqual(DAY);
|
||||
|
||||
const partialUpdateDto = {
|
||||
name: `Updated Workflow Name ${randomString()}`,
|
||||
};
|
||||
|
||||
const updatedWorkflow = await request(app.getHttpServer())
|
||||
.patch(`${basePath}/${workflowId}`)
|
||||
.set({ Authorization: `Bearer cal_test_${apiKeyString}` })
|
||||
.send(partialUpdateDto)
|
||||
.expect(200);
|
||||
|
||||
expect(updatedWorkflow.body.data.trigger?.offset?.value).toEqual(2);
|
||||
expect(updatedWorkflow.body.data.trigger?.offset?.unit).toEqual(DAY);
|
||||
|
||||
await workflowsRepositoryFixture.delete(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`DELETE ${basePath}/:workflowId`, () => {
|
||||
|
||||
@@ -129,27 +129,41 @@ export class WorkflowsInputService {
|
||||
teamId: number,
|
||||
workflowIdToUse: number
|
||||
) {
|
||||
const mappedSteps = updateDto?.steps
|
||||
? await Promise.all(
|
||||
updateDto.steps.map(async (stepDto: UpdateWorkflowStepDto, index: number) =>
|
||||
this.mapUpdateWorkflowStepToZodUpdateSchema(stepDto, index, teamId, workflowIdToUse)
|
||||
)
|
||||
// 1. Map Steps
|
||||
let mappedSteps;
|
||||
if (updateDto?.steps) {
|
||||
mappedSteps = await Promise.all(
|
||||
updateDto.steps.map(async (stepDto: UpdateWorkflowStepDto, index: number) =>
|
||||
this.mapUpdateWorkflowStepToZodUpdateSchema(stepDto, index, teamId, workflowIdToUse)
|
||||
)
|
||||
: currentData.steps.map((step) => ({ ...step, senderName: step.sender }));
|
||||
);
|
||||
} else {
|
||||
mappedSteps = currentData.steps.map((step) => ({
|
||||
...step,
|
||||
senderName: step.sender,
|
||||
}));
|
||||
}
|
||||
|
||||
const triggerForZod = updateDto?.trigger?.type
|
||||
? WORKFLOW_TRIGGER_TO_ENUM[updateDto?.trigger?.type]
|
||||
: currentData.trigger;
|
||||
// 2. Map Trigger
|
||||
let triggerForZod = currentData.trigger;
|
||||
if (updateDto?.trigger?.type) {
|
||||
triggerForZod = WORKFLOW_TRIGGER_TO_ENUM[updateDto.trigger.type];
|
||||
}
|
||||
|
||||
const timeUnitForZod = this._isOffsetTrigger(updateDto.trigger)
|
||||
? updateDto?.trigger?.offset?.unit ?? currentData.timeUnit ?? null
|
||||
: undefined;
|
||||
// 3. Map Time and TimeUnit (Keeping currentData if trigger is missing or not an offset)
|
||||
let timeUnitForZod = (currentData.timeUnit?.toLowerCase() ?? null) as "hour" | "minute" | "day" | null;
|
||||
let time = currentData.time ?? null;
|
||||
|
||||
const time = this._isOffsetTrigger(updateDto.trigger)
|
||||
? updateDto?.trigger?.offset?.value ?? currentData?.time ?? null
|
||||
: null;
|
||||
if (updateDto.trigger && this._isOffsetTrigger(updateDto.trigger)) {
|
||||
timeUnitForZod = updateDto.trigger.offset?.unit ?? timeUnitForZod ?? null;
|
||||
time = updateDto.trigger.offset?.value ?? currentData.time ?? null;
|
||||
}
|
||||
|
||||
const timeUnit = timeUnitForZod ? TIME_UNIT_TO_ENUM[timeUnitForZod] : null;
|
||||
// 4. Final Enum Conversion
|
||||
let timeUnit = null;
|
||||
if (timeUnitForZod) {
|
||||
timeUnit = TIME_UNIT_TO_ENUM[timeUnitForZod];
|
||||
}
|
||||
|
||||
return { mappedSteps, triggerForZod, time, timeUnit };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user