From cacd0cc832b989dfadbe2b8d9cd3b04047855299 Mon Sep 17 00:00:00 2001 From: Dave Samojlenko Date: Thu, 12 Dec 2024 10:54:04 -0500 Subject: [PATCH 1/2] Replace update with simple delete for removeDeliveryOption --- .../form-builder/actions.ts | 13 +++--- app/api/templates/[formID]/route.ts | 6 --- lib/templates.ts | 43 ++----------------- 3 files changed, 10 insertions(+), 52 deletions(-) diff --git a/app/(gcforms)/[locale]/(form administration)/form-builder/actions.ts b/app/(gcforms)/[locale]/(form administration)/form-builder/actions.ts index 21103652f4..065a2c4480 100644 --- a/app/(gcforms)/[locale]/(form administration)/form-builder/actions.ts +++ b/app/(gcforms)/[locale]/(form administration)/form-builder/actions.ts @@ -348,20 +348,19 @@ export const sendResponsesToVault = async ({ }: { id: string; }): Promise<{ - formRecord: FormRecord | null; + success?: boolean; error?: string; }> => { try { const { ability } = await authCheckAndThrow(); - const response = await removeDeliveryOption(ability, formID); - if (!response) { - throw new Error(`Template API response was null. Request information: { ${formID} }`); - } + await removeDeliveryOption(ability, formID); - return { formRecord: response }; + return { + success: true, + }; } catch (error) { - return { formRecord: null, error: (error as Error).message }; + return { success: false, error: (error as Error).message }; } }; diff --git a/app/api/templates/[formID]/route.ts b/app/api/templates/[formID]/route.ts index 48760a41a3..0c7714567b 100644 --- a/app/api/templates/[formID]/route.ts +++ b/app/api/templates/[formID]/route.ts @@ -201,12 +201,6 @@ export const PUT = middleware( return NextResponse.json(response); } else if (sendResponsesToVault) { const response = await removeDeliveryOption(ability, formID); - if (!response) - throw new Error( - `Template API response was null. Request information: method = ${ - req.method - } ; query = ${JSON.stringify(props.params)} ; body = ${JSON.stringify(props.body)}` - ); return NextResponse.json(response); } throw new MalformedAPIRequest( diff --git a/lib/templates.ts b/lib/templates.ts index 482d972e3f..a260a13e60 100644 --- a/lib/templates.ts +++ b/lib/templates.ts @@ -1145,61 +1145,26 @@ export async function updateResponseDeliveryOption( * @param formID The unique identifier of the form you want to modify * @returns The updated form template or null if the record does not exist */ -export async function removeDeliveryOption( - ability: UserAbility, - formID: string -): Promise { +export async function removeDeliveryOption(ability: UserAbility, formID: string): Promise { try { await authorization.canEditForm(ability, formID); - const updatedTemplate = await prisma.template - .update({ + await prisma.deliveryOption + .deleteMany({ where: { - id: formID, - isPublished: false, - deliveryOption: { - isNot: null, - }, - }, - data: { - deliveryOption: { - delete: true, - }, - }, - select: { - id: true, - created_at: true, - updated_at: true, - name: true, - jsonConfig: true, - isPublished: true, - deliveryOption: true, - securityAttribute: true, - formPurpose: true, - publishReason: true, - publishFormType: true, - publishDesc: true, + templateId: formID, }, }) .catch((e) => { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - if (e.code === "P2025") { - throw new TemplateAlreadyPublishedError(); - } - } return prismaErrors(e, null); }); - if (updatedTemplate === null) return updatedTemplate; - logEvent( ability.userID, { type: "Form", id: formID }, "ChangeDeliveryOption", "Delivery Option set to the Vault" ); - - return _parseTemplate(updatedTemplate); } catch (e) { if (e instanceof AccessControlError) logEvent( From 23fdc13d806c66e6013cbadddab2520f2ea8bf69 Mon Sep 17 00:00:00 2001 From: Dave Samojlenko Date: Thu, 12 Dec 2024 12:39:06 -0500 Subject: [PATCH 2/2] Check for isPublished first. Update tests --- lib/templates.ts | 30 ++++++++++++++++++++---------- lib/tests/templates.test.ts | 29 ++++++----------------------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/lib/templates.ts b/lib/templates.ts index a260a13e60..7f0b46019e 100644 --- a/lib/templates.ts +++ b/lib/templates.ts @@ -1143,21 +1143,31 @@ export async function updateResponseDeliveryOption( /** * Remove DeliveryOption from template. Form responses will be sent to the Vault. * @param formID The unique identifier of the form you want to modify - * @returns The updated form template or null if the record does not exist + * @returns void */ export async function removeDeliveryOption(ability: UserAbility, formID: string): Promise { try { await authorization.canEditForm(ability, formID); - await prisma.deliveryOption - .deleteMany({ - where: { - templateId: formID, - }, - }) - .catch((e) => { - return prismaErrors(e, null); - }); + // Don't change delivery option if the form is published + const template = await prisma.template.findFirstOrThrow({ + where: { + id: formID, + }, + select: { + isPublished: true, + }, + }); + + if (!template) throw new TemplateNotFoundError(); + + if (template.isPublished) throw new TemplateAlreadyPublishedError(); + + await prisma.deliveryOption.deleteMany({ + where: { + templateId: formID, + }, + }); logEvent( ability.userID, diff --git a/lib/tests/templates.test.ts b/lib/tests/templates.test.ts index 9341303725..3e9701d4ea 100644 --- a/lib/tests/templates.test.ts +++ b/lib/tests/templates.test.ts @@ -522,37 +522,20 @@ describe("Template CRUD functions", () => { }); it("Remove DeliveryOption from template", async () => { - (prismaMock.template.update as jest.MockedFunction).mockResolvedValue( - buildPrismaResponse("formtestID", formConfiguration) - ); + (prismaMock.template.findFirstOrThrow as jest.MockedFunction).mockResolvedValue({ + isPublished: false, + }); - const updatedTemplate = await removeDeliveryOption(user1Ability, "formtestID"); + await removeDeliveryOption(user1Ability, "formtestID"); - expect(prismaMock.template.update).toHaveBeenCalledWith( + expect(prismaMock.deliveryOption.deleteMany).toHaveBeenCalledWith( expect.objectContaining({ where: { - id: "formtestID", - isPublished: false, - deliveryOption: { - isNot: null, - }, - }, - data: { - deliveryOption: { - delete: true, - }, + templateId: "formtestID", }, }) ); - expect(updatedTemplate).toEqual( - expect.objectContaining({ - id: "formtestID", - form: formConfiguration, - isPublished: false, - securityAttribute: "Unclassified", - }) - ); expect(mockedLogEvent).toHaveBeenCalledWith( user1Ability.userID, { id: "formtestID", type: "Form" },