diff --git a/CHANGELOG.md b/CHANGELOG.md index 186b3383..578441b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ Another example [here](https://co-pilot.dev/changelog) - Fix unit tests where mocked req doesn't match new CustomRequest type ([#122](https://github.com/chingu-x/chingu-dashboard-be/pull/122)) - Fix bug with reading roles after reseeding causes the db to not recognize the tokens stored by the user's browser ([#134](https://github.com/chingu-x/chingu-dashboard-be/pull/134)) - Fix form responses giving error and not inserting values when the boolean value is false ([#156](https://github.com/chingu-x/chingu-dashboard-be/pull/156)) +- Fix a bug for check on voyageTeamMemberId ([#159](https://github.com/chingu-x/chingu-dashboard-be/pull/159)) ### Removed diff --git a/src/pipes/voyage-team-member-validation.ts b/src/pipes/voyage-team-member-validation.ts new file mode 100644 index 00000000..319d86aa --- /dev/null +++ b/src/pipes/voyage-team-member-validation.ts @@ -0,0 +1,31 @@ +import { + BadRequestException, + Injectable, + PipeTransform, + Scope, + Inject, +} from "@nestjs/common"; +import { REQUEST } from "@nestjs/core"; +import { CustomRequest } from "src/global/types/CustomRequest"; + +@Injectable({ scope: Scope.REQUEST }) +export class VoyageTeamMemberValidationPipe implements PipeTransform { + constructor(@Inject(REQUEST) private request: CustomRequest) {} + transform(value: any): any { + const voyageTeamMemberId: number = value.voyageTeamMemberId; + + const voyageTeams = this.request.user.voyageTeams; + + const isTeamMember = voyageTeams.some( + (teams) => teams.memberId === voyageTeamMemberId, + ); + + if (!isTeamMember) { + throw new BadRequestException( + "User is not in the specified team, check voyageTeamId or voyageTeamMemberId is correct.", + ); + } + + return value; + } +} diff --git a/src/sprints/sprints.controller.ts b/src/sprints/sprints.controller.ts index 6c4679e3..6a259380 100644 --- a/src/sprints/sprints.controller.ts +++ b/src/sprints/sprints.controller.ts @@ -35,6 +35,7 @@ import { } from "../global/responses/errors"; import { FormResponse, ResponseResponse } from "../forms/forms.response"; import { CreateCheckinFormDto } from "./dto/create-checkin-form.dto"; +import { VoyageTeamMemberValidationPipe } from "../pipes/voyage-team-member-validation"; @Controller() @ApiTags("Voyage - Sprints") @@ -530,7 +531,7 @@ export class SprintsController { type: ConflictErrorResponse, }) addCheckinFormResponse( - @Body(new FormInputValidationPipe()) + @Body(new FormInputValidationPipe(), VoyageTeamMemberValidationPipe) createCheckinFormResponse: CreateCheckinFormDto, ) { return this.sprintsService.addCheckinFormResponse( diff --git a/test/sprints.e2e-spec.ts b/test/sprints.e2e-spec.ts index 2ddb37b9..ce52a991 100644 --- a/test/sprints.e2e-spec.ts +++ b/test/sprints.e2e-spec.ts @@ -855,7 +855,7 @@ describe("Sprints Controller (e2e)", () => { .post(sprintCheckinUrl) .set("Cookie", accessToken) .send({ - voyageTeamMemberId: 2, // voyageTeamMemberId 1 is already in the seed + voyageTeamMemberId: 4, // voyageTeamMemberId 1 is already in the seed sprintId: 1, responses: [ { @@ -1045,7 +1045,7 @@ describe("Sprints Controller (e2e)", () => { .post(sprintCheckinUrl) .set("Cookie", accessToken) .send({ - voyageTeamMemberId: 1, + voyageTeamMemberId: 4, sprintId: 1, responses: [ { @@ -1062,7 +1062,7 @@ describe("Sprints Controller (e2e)", () => { .post(sprintCheckinUrl) .set("Cookie", accessToken) .send({ - voyageTeamMemberId: 1, + voyageTeamMemberId: 4, sprintId: 1, responses: [ { @@ -1081,5 +1081,21 @@ describe("Sprints Controller (e2e)", () => { expect(responseGroupAfter).toEqual(responseGroupBefore); expect(checkinsAfter).toEqual(checkinsBefore); }); + it("should return 400 if the user doesnot belong to the voyage team", async () => { + await request(app.getHttpServer()) + .post(sprintCheckinUrl) + .set("Cookie", accessToken) + .send({ + voyageTeamMemberId: 5, + sprintId: 1, + responses: [ + { + questionId: questions[0].id, + text: "Text input value", + }, + ], + }) + .expect(400); + }); }); });