Skip to content

Commit

Permalink
feat: add parent proposal to the proposal document
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-trajanovski committed Nov 12, 2024
1 parent 8e26958 commit 6c8fb79
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/proposals/dto/update-proposal.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ export class UpdateProposalDto extends OwnableDto {
@IsOptional()
@IsObject()
readonly metadata?: Record<string, unknown>;

@ApiProperty({
type: String,
required: false,
description: "Parent proposal id.",
})
@IsOptional()
@IsString()
readonly parentProposalId?: string;
}

export class PartialUpdateProposalDto extends PartialType(UpdateProposalDto) {}
6 changes: 5 additions & 1 deletion src/proposals/proposals.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
BadRequestException,
Logger,
InternalServerErrorException,
NotFoundException,
} from "@nestjs/common";
import { Request } from "express";
import { ProposalsService } from "./proposals.service";
Expand Down Expand Up @@ -578,7 +579,10 @@ export class ProposalsController {
const proposal = await this.proposalsService.findOne({
proposalId,
});
if (!proposal) return { canAccess: false };

if (!proposal) {
throw new NotFoundException(`Proposal with ${proposalId} not found`);
}

const canAccess = await this.permissionChecker(
Action.ProposalsRead,
Expand Down
15 changes: 15 additions & 0 deletions src/proposals/schemas/proposal.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,21 @@ export class ProposalClass extends OwnableClass {
})
@Prop({ type: Object, required: false, default: {} })
metadata?: Record<string, unknown>;

@ApiProperty({
type: String,
required: false,
description: "Parent proposal id",
default: null,
nullable: true,
})
@Prop({
type: String,
required: false,
default: null,
ref: "Proposal",
})
parentProposalId: string;
}

export const ProposalSchema = SchemaFactory.createForClass(ProposalClass);
Expand Down
49 changes: 45 additions & 4 deletions test/Proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ let accessTokenProposalIngestor = null,
accessTokenAdminIngestor = null,
accessTokenArchiveManager = null,
defaultProposalId = null,
minimalProposalId = null,
proposalId = null,
proposalWithParentId = null,
attachmentId = null;

describe("1500: Proposal: Simple Proposal", () => {
before(() => {
db.collection("Proposal").deleteMany({});
});
beforeEach(async() => {
beforeEach(async () => {
accessTokenProposalIngestor = await utils.getToken(appUrl, {
username: "proposalIngestor",
password: TestData.Accounts["proposalIngestor"]["password"],
Expand Down Expand Up @@ -89,7 +91,7 @@ describe("1500: Proposal: Simple Proposal", () => {
res.body.should.have.property("ownerGroup").and.be.string;
res.body.should.have.property("proposalId").and.be.string;
defaultProposalId = res.body["proposalId"];
proposalId = encodeURIComponent(res.body["proposalId"]);
minimalProposalId = encodeURIComponent(res.body["proposalId"]);
});
});

Expand Down Expand Up @@ -216,7 +218,46 @@ describe("1500: Proposal: Simple Proposal", () => {
});
});

it("0120: should delete this proposal attachment", async () => {
it("0120: adds a new proposal with parent proposal", async () => {
const proposalWithParentProposal = {
...TestData.ProposalCorrectComplete,
proposalId: "20170268",
parentProposalId: proposalId,
};

return request(appUrl)
.post("/api/v3/Proposals")
.send(proposalWithParentProposal)
.set("Accept", "application/json")
.set({ Authorization: `Bearer ${accessTokenProposalIngestor}` })
.expect(TestData.EntryCreatedStatusCode)
.expect("Content-Type", /json/)
.then((res) => {
res.body.should.have.property("ownerGroup").and.be.string;
res.body.should.have.property("proposalId").and.be.string;
proposalWithParentId = res.body.proposalId;
res.body.should.have.property("parentProposalId").and.be.string;
res.body.parentProposalId.should.be.equal(proposalId);
});
});

it("0120: updates a proposal with a new parent proposal", async () => {
return request(appUrl)
.patch("/api/v3/Proposals/" + proposalWithParentId)
.send({ parentProposalId: minimalProposalId })
.set("Accept", "application/json")
.set({ Authorization: `Bearer ${accessTokenAdminIngestor}` })
.expect(TestData.SuccessfulPatchStatusCode)
.expect("Content-Type", /json/)
.then((res) => {
res.body.should.have.property("ownerGroup").and.be.string;
res.body.should.have.property("proposalId").and.be.string;
res.body.should.have.property("parentProposalId").and.be.string;
res.body.parentProposalId.should.be.equal(minimalProposalId);
});
});

it("0130: should delete this proposal attachment", async () => {
return request(appUrl)
.delete(
"/api/v3/Proposals/" + proposalId + "/attachments/" + attachmentId,
Expand All @@ -226,7 +267,7 @@ describe("1500: Proposal: Simple Proposal", () => {
.expect(TestData.SuccessfulDeleteStatusCode);
});

it("0130: admin can remove all existing proposals", async () => {
it("0140: admin can remove all existing proposals", async () => {
return await request(appUrl)
.get("/api/v3/Proposals")
.set("Accept", "application/json")
Expand Down
20 changes: 19 additions & 1 deletion test/RawDataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("1900: RawDataset: Raw Datasets", () => {
db.collection("Dataset").deleteMany({});
db.collection("Proposals").deleteMany({});
});
beforeEach(async() => {
beforeEach(async () => {
accessProposalToken = await utils.getToken(appUrl, {
username: "proposalIngestor",
password: TestData.Accounts["proposalIngestor"]["password"],
Expand Down Expand Up @@ -46,6 +46,8 @@ describe("1900: RawDataset: Raw Datasets", () => {
.then((res) => {
res.body.should.have.property("ownerGroup").and.be.string;
res.body.should.have.property("proposalId").and.be.string;
// NOTE: Add real proposal in the testdata instead of fixed (non-existing) one
TestData.RawCorrect.proposalId = res.body["proposalId"];
proposalId = encodeURIComponent(res.body["proposalId"]);
});
});
Expand Down Expand Up @@ -280,6 +282,22 @@ describe("1900: RawDataset: Raw Datasets", () => {
);
});

it("01250: adds a new proposal for pattching in the existing dataset", async () => {
return request(appUrl)
.post("/api/v3/Proposals")
.send(TestData.ProposalCorrectComplete)
.set("Accept", "application/json")
.set({ Authorization: `Bearer ${accessProposalToken}` })
.expect(TestData.EntryCreatedStatusCode)
.expect("Content-Type", /json/)
.then((res) => {
res.body.should.have.property("ownerGroup").and.be.string;
res.body.should.have.property("proposalId").and.be.string;
// NOTE: Add real proposal in the testdata instead of fixed (non-existing) one
TestData.PatchProposal1.proposalId = res.body["proposalId"];
});
});

it("0125: should update proposal of the dataset", async () => {
return request(appUrl)
.patch("/api/v3/datasets/" + pid)
Expand Down
4 changes: 2 additions & 2 deletions test/TestData.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ const TestData = {
isPublished: false,
ownerGroup: "p13388",
accessGroups: [],
proposalId: "10.540.16635/20110123",
proposalId: "",
runNumber: "123456",
instrumentId: "1f016ec4-7a73-11ef-ae3e-439013069377",
sampleId: "20c32b4e-7a73-11ef-9aec-5b9688aa3791i",
Expand Down Expand Up @@ -838,7 +838,7 @@ const TestData = {
},

PatchProposal1: {
proposalId: "10.540.16635/20240124",
proposalId: "",
},

PatchInstrument1: {
Expand Down

0 comments on commit 6c8fb79

Please sign in to comment.