fix: Allow zero routingFormResponseId in API v2 available endpoint (#21301)

* Allow zero routingFormResponseId

* fix: conditionally validate routingFormResponseId to allow 0 only for dry run operations

Co-Authored-By: hariom@cal.com <hariom@cal.com>

* fix: pass _isDryRun parameter to API v2 available endpoint

Co-Authored-By: hariom@cal.com <hariom@cal.com>

* fix runtime error and improve message

* Add e2e test to verify the constraint works

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: hariom@cal.com <hariom@cal.com>
This commit is contained in:
Hariom Balhara
2025-05-16 12:23:11 +05:30
committed by GitHub
co-authored by hariom@cal.com <hariom@cal.com> hariom@cal.com <hariom@cal.com> Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> hariom@cal.com <hariom@cal.com>
parent 5bc9d71a88
commit fab364f084
3 changed files with 115 additions and 1 deletions
@@ -685,6 +685,86 @@ describe("Slots 2024-04-15 Endpoints", () => {
await bookingsRepositoryFixture.deleteById(booking.id);
});
describe("routingFormResponseId and _isDryRun validation", () => {
const baseUrl = "/api/v2/slots/available";
const baseParams = {
startTime: "2050-09-05",
endTime: "2050-09-10",
};
it("should allow routingFormResponseId=0 in dry-run mode", async () => {
return request(app.getHttpServer())
.get(baseUrl)
.query({
...baseParams,
eventTypeId,
routingFormResponseId: 0,
_isDryRun: true,
})
.expect(200)
.expect((res) => {
expect(res.body.status).toEqual(SUCCESS_STATUS);
});
});
it("should reject routingFormResponseId=1 in dry-run mode", async () => {
return request(app.getHttpServer())
.get(baseUrl)
.query({
...baseParams,
eventTypeId,
routingFormResponseId: 1,
_isDryRun: true,
})
.expect(400)
.expect((res) => {
expect(res.body.error.details.errors[0].constraints.routingFormResponseIdValidator).toContain("routingFormResponseId must be 0 for dry run");
});
});
it("should allow routingFormResponseId=1 in non-dry-run mode", async () => {
return request(app.getHttpServer())
.get(baseUrl)
.query({
...baseParams,
eventTypeId,
routingFormResponseId: 1,
})
.expect(200)
.expect((res) => {
expect(res.body.status).toEqual(SUCCESS_STATUS);
});
});
it("should reject routingFormResponseId=0 in non-dry-run mode", async () => {
return request(app.getHttpServer())
.get(baseUrl)
.query({
...baseParams,
eventTypeId,
routingFormResponseId: 0,
})
.expect(400)
.expect((res) => {
expect(res.body.error.details.errors[0].constraints.routingFormResponseIdValidator).toContain("routingFormResponseId must be a positive number");
});
});
it("should reject routingFormResponseId=-1 in non-dry-run mode", async () => {
return request(app.getHttpServer())
.get(baseUrl)
.query({
...baseParams,
eventTypeId,
routingFormResponseId: -1,
})
.expect(400)
.expect((res) => {
expect(res.body.error.details.errors[0].constraints.routingFormResponseIdValidator).toContain("routingFormResponseId must be a positive number");
});
});
});
afterAll(async () => {
await userRepositoryFixture.deleteByEmail(user.email);
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlotUid);