From 13e7d3d2f318f7e824b65975a02baa1445f79b93 Mon Sep 17 00:00:00 2001 From: Chinedu Olebu Date: Thu, 31 Oct 2024 10:14:19 -0700 Subject: [PATCH] chore(3314): enforce distinct PO and TL idir for edit requests --- .../products/_operations/update.test.ts | 1 + .../products/_operations/update.ts | 3 +- .../requests/[id]/decision/route.test.ts | 1 + .../products/_operations/update.ts | 2 +- .../requests/[id]/decision/route.test.ts | 2 + app/package-lock.json | 90 +++++++++++++++++++ app/validation-schemas/private-cloud.ts | 22 ++++- app/validation-schemas/public-cloud.ts | 23 ++++- 8 files changed, 136 insertions(+), 8 deletions(-) diff --git a/app/app/api/private-cloud/products/_operations/update.test.ts b/app/app/api/private-cloud/products/_operations/update.test.ts index 35b74122b..ee942cea1 100644 --- a/app/app/api/private-cloud/products/_operations/update.test.ts +++ b/app/app/api/private-cloud/products/_operations/update.test.ts @@ -37,6 +37,7 @@ async function makeBasicProductChange(extra = {}) { const response = await editPrivateCloudProject(requests.create.licencePlate, { ...requests.create.decisionData, developmentQuota: newDevelopmentQuota, + isAgMinistryChecked: true, ...extra, }); diff --git a/app/app/api/private-cloud/products/_operations/update.ts b/app/app/api/private-cloud/products/_operations/update.ts index 58ce346ef..8bd678e0b 100644 --- a/app/app/api/private-cloud/products/_operations/update.ts +++ b/app/app/api/private-cloud/products/_operations/update.ts @@ -28,7 +28,8 @@ export default async function updateOp({ return UnauthorizedResponse(); } - const { requestComment, quotaContactName, quotaContactEmail, quotaJustification, ...rest } = body; + const { requestComment, quotaContactName, quotaContactEmail, quotaJustification, isAgMinistryChecked, ...rest } = + body; if (!product._permissions.manageMembers) { rest.members = product.members; diff --git a/app/app/api/private-cloud/requests/[id]/decision/route.test.ts b/app/app/api/private-cloud/requests/[id]/decision/route.test.ts index 9704597bd..e0154e22d 100644 --- a/app/app/api/private-cloud/requests/[id]/decision/route.test.ts +++ b/app/app/api/private-cloud/requests/[id]/decision/route.test.ts @@ -136,6 +136,7 @@ describe('Review Private Cloud Update Request - Permissions', () => { const response = await editPrivateCloudProject(requests.main.licencePlate, { ...requests.main.decisionData, developmentQuota: newDevelopmentQuota, + isAgMinistryChecked: true, }); expect(response.status).toBe(200); diff --git a/app/app/api/public-cloud/products/_operations/update.ts b/app/app/api/public-cloud/products/_operations/update.ts index fca4f699d..c67b266c4 100644 --- a/app/app/api/public-cloud/products/_operations/update.ts +++ b/app/app/api/public-cloud/products/_operations/update.ts @@ -27,7 +27,7 @@ export default async function updateOp({ return UnauthorizedResponse(); } - const { requestComment, accountCoding, ...rest } = body; + const { requestComment, accountCoding, isAgMinistryChecked, isEaApproval, ...rest } = body; if (!product._permissions.manageMembers) { rest.members = product.members; diff --git a/app/app/api/public-cloud/requests/[id]/decision/route.test.ts b/app/app/api/public-cloud/requests/[id]/decision/route.test.ts index abdb77936..1cca9e3f2 100644 --- a/app/app/api/public-cloud/requests/[id]/decision/route.test.ts +++ b/app/app/api/public-cloud/requests/[id]/decision/route.test.ts @@ -188,7 +188,9 @@ describe('Review Public Cloud Update Request - Permissions', () => { ...requests.main.decisionData, accountCoding: requests.main.decisionData.billing.accountCoding, environmentsEnabled: newEnvironmentsEnabled, + isAgMinistryChecked: true, }); + expect(response.status).toBe(200); requests.main = await response.json(); diff --git a/app/package-lock.json b/app/package-lock.json index 79f1f7ce6..34efbe7d9 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -15156,6 +15156,96 @@ "peerDependencies": { "zod": "^3.18.0" } + }, + "node_modules/react-email/node_modules/@next/swc-darwin-arm64": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.2.tgz", + "integrity": "sha512-GK+8w88z+AFlmt+ondytZo2xpwlfAR8U6CRwXancHImh6EdGfHMIrTSCcx5sOSBei00GyLVL0ioo1JLKTfprgg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-darwin-x64": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.2.tgz", + "integrity": "sha512-KUpBVxIbjzFiUZhiLIpJiBoelqzQtVZbdNNsehhUn36e2YzKHphnK8eTUW1s/4aPy5kH/UTid8IuVbaOpedhpw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.2.tgz", + "integrity": "sha512-9J7TPEcHNAZvwxXRzOtiUvwtTD+fmuY0l7RErf8Yyc7kMpE47MIQakl+3jecmkhOoIyi/Rp+ddq7j4wG6JDskQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-arm64-musl": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.2.tgz", + "integrity": "sha512-BjH4ZSzJIoTTZRh6rG+a/Ry4SW0HlizcPorqNBixBWc3wtQtj4Sn9FnRZe22QqrPnzoaW0ctvSz4FaH4eGKMww==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.2.tgz", + "integrity": "sha512-JkXysDT0/hEY47O+Hvs8PbZAeiCQVxKfGtr4GUpNAhlG2E0Mkjibuo8ryGD29Qb5a3IOnKYNoZlh/MyKd2Nbww==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-win32-x64-msvc": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.2.tgz", + "integrity": "sha512-foaUL0NqJY/dX0Pi/UcZm5zsmSk5MtP/gxx3xOPyREkMFN+CTjctPfu3QaqrQHinaKdPnMWPJDKt4VjDfTBe/Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/app/validation-schemas/private-cloud.ts b/app/validation-schemas/private-cloud.ts index 0423efa1d..f5b2f6588 100644 --- a/app/validation-schemas/private-cloud.ts +++ b/app/validation-schemas/private-cloud.ts @@ -146,9 +146,25 @@ const _privateCloudEditRequestBodySchema = _privateCloudCreateRequestBodySchema. }), ); -export const privateCloudEditRequestBodySchema = _privateCloudEditRequestBodySchema.refine(isEmailUnique, { - message: 'Project Owner and Primary Technical Lead must not have the same email.', -}); +export const privateCloudEditRequestBodySchema = _privateCloudEditRequestBodySchema + .merge( + z.object({ + isAgMinistryChecked: z.boolean().optional(), + }), + ) + .refine( + (formData) => { + return AGMinistries.includes(formData.ministry) ? formData.isAgMinistryChecked : true; + }, + { + message: 'AG Ministry Checkbox should be checked.', + path: ['isAgMinistryChecked'], + }, + ) + .refine(isEmailUnique, { + message: 'Project Owner and Primary Technical Lead must not have the same email.', + path: ['primaryTechnicalLead'], + }); export const privateCloudRequestDecisionBodySchema = _privateCloudEditRequestBodySchema.merge( z.object({ diff --git a/app/validation-schemas/public-cloud.ts b/app/validation-schemas/public-cloud.ts index 39f140ef8..4fd6c71e8 100644 --- a/app/validation-schemas/public-cloud.ts +++ b/app/validation-schemas/public-cloud.ts @@ -102,9 +102,26 @@ const _publicCloudEditRequestBodySchema = _publicCloudCreateRequestBodySchema.me }), ); -export const publicCloudEditRequestBodySchema = _publicCloudEditRequestBodySchema.refine(isEmailUnique, { - message: 'Project Owner and Primary Technical Lead must not have the same email.', -}); +export const publicCloudEditRequestBodySchema = _publicCloudEditRequestBodySchema + .merge( + z.object({ + isAgMinistryChecked: z.boolean().optional(), + isEaApproval: z.boolean().optional(), + }), + ) + .refine( + (formData) => { + return AGMinistries.includes(formData.ministry) ? formData.isAgMinistryChecked : true; + }, + { + message: 'AG Ministry Checkbox should be checked.', + path: ['isAgMinistryChecked'], + }, + ) + .refine(isEmailUnique, { + message: 'Project Owner and Primary Technical Lead must not have the same email.', + path: ['primaryTechnicalLead'], + }); export const publicCloudRequestDecisionBodySchema = _publicCloudEditRequestBodySchema.merge( z.object({