Skip to content

Commit

Permalink
feat: add type property to the proposal document with database migration
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-trajanovski committed Nov 13, 2024
1 parent 382493e commit ca20bc5
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
12 changes: 12 additions & 0 deletions migrations/20241113130700-proposal-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
async up(db, client) {
db.collection("Proposal").updateMany(
{ type: { $exists: false } },
{ $set: { type: "Default Proposal" } },
);
},

async down(db, client) {
db.collection("Proposal").updateMany({}, { $unset: { type: 1 } });
},
};
17 changes: 17 additions & 0 deletions src/proposals/dto/update-proposal.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import {
IsArray,
IsDateString,
IsEmail,
IsEnum,
IsObject,
IsOptional,
IsString,
ValidateNested,
} from "class-validator";
import { OwnableDto } from "../../common/dto/ownable.dto";
import { ProposalType } from "../proposal-type.enum";
import { CreateMeasurementPeriodDto } from "./create-measurement-period.dto";

@ApiTags("proposals")
Expand Down Expand Up @@ -133,6 +135,21 @@ export class UpdateProposalDto extends OwnableDto {
@IsOptional()
@IsString()
readonly parentProposalId?: string;

@ApiProperty({
type: String,
required: false,
enum: [
ProposalType.DefaultProposal,
ProposalType.DOORProposal,
ProposalType.Beamtime,
],
description:
"Characterize type of proposal, either 'Default Proposal', 'DOOR Proposal' or 'Beamtime'",
})
@IsOptional()
@IsEnum(ProposalType)
readonly type?: string;
}

export class PartialUpdateProposalDto extends PartialType(UpdateProposalDto) {}
5 changes: 5 additions & 0 deletions src/proposals/proposal-type.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ProposalType {
DefaultProposal = "Default Proposal",
DOORProposal = "DOOR Proposal",
Beamtime = "Beamtime",
}
25 changes: 25 additions & 0 deletions src/proposals/schemas/proposal.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApiProperty } from "@nestjs/swagger";
import { Document } from "mongoose";

import { OwnableClass } from "src/common/schemas/ownable.schema";
import { ProposalType } from "../proposal-type.enum";
import {
MeasurementPeriodClass,
MeasurementPeriodSchema,
Expand Down Expand Up @@ -182,6 +183,30 @@ export class ProposalClass extends OwnableClass {
ref: "Proposal",
})
parentProposalId: string;

@ApiProperty({
type: String,
required: true,
enum: [
ProposalType.DefaultProposal,
ProposalType.DOORProposal,
ProposalType.Beamtime,
],
default: ProposalType.DefaultProposal,
description:
"Characterize type of proposal, either 'Default Proposal', 'DOOR Proposal' or 'Beamtime'",
})
@Prop({
type: String,
required: true,
enum: [
ProposalType.DefaultProposal,
ProposalType.DOORProposal,
ProposalType.Beamtime,
],
default: ProposalType.DefaultProposal,
})
type: string;
}

export const ProposalSchema = SchemaFactory.createForClass(ProposalClass);
Expand Down
41 changes: 41 additions & 0 deletions test/Proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ describe("1500: Proposal: Simple Proposal", () => {
.then((res) => {
res.body.should.have.property("createdBy").and.be.string;
res.body.should.have.property("updatedBy").and.be.string;
res.body.should.have.property("type").and.be.string;
res.body.type.should.be.equal("Default Proposal");
});
});

Expand Down Expand Up @@ -241,6 +243,45 @@ describe("1500: Proposal: Simple Proposal", () => {
});
});

it("0116: adds a new proposal with a type different than default", async () => {
const proposalType = "DOOR Proposal";
const proposalWithType = {
...TestData.ProposalCorrectComplete,
proposalId: faker.string.numeric(8),
type: proposalType,
};

return request(appUrl)
.post("/api/v3/Proposals")
.send(proposalWithType)
.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;
res.body.type.should.be.equal(proposalType);
});
});

it("0117: cannot add a new proposal with a type different than predefined proposal types", async () => {
const proposalType = "Incorrect type";
const proposalWithIncorrectType = {
...TestData.ProposalCorrectComplete,
proposalId: faker.string.numeric(8),
type: proposalType,
};

return request(appUrl)
.post("/api/v3/Proposals")
.send(proposalWithIncorrectType)
.set("Accept", "application/json")
.set({ Authorization: `Bearer ${accessTokenProposalIngestor}` })
.expect(TestData.BadRequestStatusCode)
.expect("Content-Type", /json/);
});

it("0120: updates a proposal with a new parent proposal", async () => {
return request(appUrl)
.patch("/api/v3/Proposals/" + proposalWithParentId)
Expand Down

0 comments on commit ca20bc5

Please sign in to comment.