feat: update recording, transcript endpoint and add tests #111
Conversation
Code Review by Qodo
1. getRecordings() missing await
|
| async getBookingRecordings(@Param("bookingUid") bookingUid: string): Promise<GetBookingRecordingsOutput> { | ||
| const recordings = await this.calVideoService.getRecordings(bookingUid); | ||
| const recordings = this.calVideoService.getRecordings(bookingUid); | ||
|
|
||
| return { | ||
| status: SUCCESS_STATUS, | ||
| data: recordings, | ||
| message: | ||
| "This endpoint will require authentication in a future release. Please update your integration to include valid credentials. See https://cal.com/docs/api-reference/v2/introduction#authentication for details.", | ||
| }; |
There was a problem hiding this comment.
1. getrecordings() missing await 📘 Rule violation ✓ Correctness
• The controller assigns recordings to the Promise returned by this.calVideoService.getRecordings(bookingUid) instead of awaiting it, then returns it in the response data field. • This creates an unhandled/incorrect async failure point where the endpoint can return a non-serializable Promise (or incorrect payload shape) rather than the expected recordings array, making failures harder to diagnose and breaking edge-case behavior. • This violates the requirement to identify and handle failure points/edge cases in request handling.
Agent prompt
## Issue description
`getBookingRecordings()` returns `data: recordings` where `recordings` is a Promise because `await` is missing. This can break the API response shape and makes async failures/edge cases harder to handle.
## Issue Context
`GetBookingRecordingsOutput.data` is expected to be a `RecordingItem[]`, not a Promise. The service call is a potential failure point that should be awaited and handled.
## Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts[226-232]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| describe("GET /v2/bookings/:bookingUid/recordings - Authorization", () => { | ||
| it("should allow booking organizer to access recordings", async () => { | ||
| const calVideoService = app.get(CalVideoService); | ||
| jest.spyOn(calVideoService, "getRecordings").mockResolvedValue([]); | ||
|
|
||
| const response = await request(app.getHttpServer()) | ||
| .get(`/v2/bookings/${testBooking.uid}/recordings`) | ||
| .set("Authorization", `Bearer ${ownerApiKey}`) | ||
| .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) | ||
| .expect(200); | ||
|
|
||
| expect(response.body.status).toEqual(SUCCESS_STATUS); | ||
| }); | ||
|
|
||
| it("should return 403 when unauthorized user tries to access recordings", async () => { | ||
| await request(app.getHttpServer()) | ||
| .get(`/v2/bookings/${testBooking.uid}/recordings`) | ||
| .set("Authorization", `Bearer ${unauthorizedApiKey}`) | ||
| .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) | ||
| .expect(403); | ||
| }); | ||
| }); | ||
|
|
||
| describe("GET /v2/bookings/:bookingUid/transcripts - Authorization", () => { | ||
| it("should allow booking organizer to access transcripts", async () => { | ||
| const calVideoService = app.get(CalVideoService); | ||
| jest.spyOn(calVideoService, "getTranscripts").mockResolvedValue([]); | ||
|
|
There was a problem hiding this comment.
2. jest.spyon used in tests 📘 Rule violation ⛯ Reliability
• The newly added e2e tests use Jest-specific APIs (jest.spyOn(...)) rather than Vitest (vi.spyOn(...)). • This violates the requirement to standardize on Vitest (and UTC timezone) for consistent test execution, and can cause test failures or inconsistent behavior in the repo’s expected test runner setup.
Agent prompt
## Issue description
The added tests use Jest-specific mocking (`jest.spyOn`) which violates the requirement that all tests use Vitest.
## Issue Context
The compliance rule explicitly disallows Jest-specific APIs in tests. These e2e tests should use `vi.spyOn` (and any other Vitest equivalents) and rely on the repo’s UTC timezone test configuration.
## Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-access-auth.e2e-spec.ts[188-215]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @Pbac(["booking.readRecordings"]) | ||
| @Permissions([BOOKING_READ]) | ||
| @UseGuards(BookingUidGuard) | ||
| // @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) | ||
| @UseGuards(BookingPbacGuard, ApiAuthGuard, BookingUidGuard) | ||
| @ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER) |
There was a problem hiding this comment.
3. Transcripts guards misordered 🐞 Bug ⛯ Reliability
• The transcripts route runs BookingPbacGuard before ApiAuthGuard. • BookingPbacGuard requires request.user and throws UnauthorizedException if absent, so the endpoint will 401 even with valid credentials. • This makes GET /v2/bookings/:bookingUid/transcripts effectively unusable.
Agent prompt
### Issue description
`GET /v2/bookings/:bookingUid/transcripts` has `@UseGuards(BookingPbacGuard, ApiAuthGuard, BookingUidGuard)`. `BookingPbacGuard` requires `request.user`, which is only populated after `ApiAuthGuard` runs.
### Issue Context
`BookingPbacGuard` throws `UnauthorizedException` when `request.user` is missing.
### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts[236-239]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @Pbac(["booking.readRecordings"]) | ||
| @Permissions([BOOKING_WRITE]) | ||
| @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) |
There was a problem hiding this comment.
4. Wrong permission for read 🐞 Bug ⛨ Security
• The recordings endpoint is a GET/read operation but now requires BOOKING_WRITE. • Platform permissions are independent bits; BOOKING_WRITE does not imply BOOKING_READ, so clients with only BOOKING_READ will start failing with 403. • This is inconsistent with other read endpoints (e.g., transcripts, conferencing-sessions) which require BOOKING_READ.
Agent prompt
### Issue description
`GET /v2/bookings/:bookingUid/recordings` requires `BOOKING_WRITE`, which will reject OAuth clients that only have `BOOKING_READ`.
### Issue Context
Permissions are checked via bitwise equality; WRITE does not include READ.
### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts[215-217]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Benchmark PR from agentic-review-benchmarks#16