From 00f2848c9de7ad22bcea84f122d57457ea7895d2 Mon Sep 17 00:00:00 2001 From: "Tejas G." Date: Fri, 24 Jan 2025 15:51:07 +0800 Subject: [PATCH] feat: Attachment support in email responses for storage mode forms (#8053) * feat: send attachment to mail service * test: add test case for submitEncryptModeForm * test: add attachments to mail service tests * test: add test for case where there are no attachments --- .../encrypt-submission.controller.spec.ts | 123 +++++++++++++++++- .../encrypt-submission.controller.ts | 2 +- .../mail/__tests__/mail.service.spec.ts | 8 +- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/src/app/modules/submission/encrypt-submission/__tests__/encrypt-submission.controller.spec.ts b/src/app/modules/submission/encrypt-submission/__tests__/encrypt-submission.controller.spec.ts index 022285be5e..84c3eb42c4 100644 --- a/src/app/modules/submission/encrypt-submission/__tests__/encrypt-submission.controller.spec.ts +++ b/src/app/modules/submission/encrypt-submission/__tests__/encrypt-submission.controller.spec.ts @@ -29,7 +29,11 @@ import { SpVerifiedContent, } from 'src/app/modules/verified-content/verified-content.types' import MailService from 'src/app/services/mail/mail.service' -import { FormFieldSchema, IPopulatedEncryptedForm } from 'src/types' +import { + FormFieldSchema, + IAttachmentInfo, + IPopulatedEncryptedForm, +} from 'src/types' import { EncryptSubmissionDto, FormCompleteDto } from 'src/types/api' import { SubmissionEmailObj } from '../../email-submission/email-submission.util' @@ -1330,4 +1334,121 @@ describe('encrypt-submission.controller', () => { ) }) }) + + describe('submitEncryptModeForm', () => { + beforeEach(() => { + jest.clearAllMocks() + MockMailService.sendSubmissionToAdmin.mockReturnValue(okAsync(true)) + }) + + it('should call sendSubmissionToAdmin with no attachments', async () => { + // Arrange + jest + .spyOn(MailService, 'sendSubmissionToAdmin') + .mockReturnValue(okAsync(true)) + + const mockFormId = new ObjectId() + const mockForm = { + _id: mockFormId, + title: 'Test Form', + authType: FormAuthType.NIL, + form_fields: [] as FormFieldSchema[], + emails: ['test@example.com'], + getUniqueMyInfoAttrs: () => [] as MyInfoAttribute[], + } as IPopulatedEncryptedForm + + const mockAttachments: IAttachmentInfo[] = [] + + const mockReq = merge( + expressHandler.mockRequest({ + params: { formId: mockFormId.toHexString() }, + body: { + responses: [], + attachments: mockAttachments, + }, + }), + { + formsg: { + encryptedPayload: { + encryptedContent: 'mockEncryptedContent', + version: 1, + }, + formDef: {}, + encryptedFormDef: mockForm, + unencryptedAttachments: mockAttachments, + } as unknown as EncryptSubmissionDto, + } as unknown as FormCompleteDto, + ) as unknown as SubmitEncryptModeFormHandlerRequest + + const mockRes = expressHandler.mockResponse() + + // Act + await submitEncryptModeFormForTest(mockReq, mockRes) + + // Assert (done) + expect(MockMailService.sendSubmissionToAdmin).toHaveBeenCalledWith( + expect.objectContaining({ + attachments: mockAttachments, + }), + ) + }) + + it('should call sendSubmissionToAdmin with the attachments', async () => { + // Arrange + jest + .spyOn(MailService, 'sendSubmissionToAdmin') + .mockReturnValue(okAsync(true)) + + const mockFormId = new ObjectId() + const mockForm = { + _id: mockFormId, + title: 'Test Form', + authType: FormAuthType.NIL, + form_fields: [] as FormFieldSchema[], + emails: ['test@example.com'], + getUniqueMyInfoAttrs: () => [] as MyInfoAttribute[], + } as IPopulatedEncryptedForm + + const mockAttachments: IAttachmentInfo[] = [ + { + filename: 'test.pdf', + content: Buffer.from('this is a test file'), + fieldId: 'test-field-id', + }, + ] + + const mockReq = merge( + expressHandler.mockRequest({ + params: { formId: mockFormId.toHexString() }, + body: { + responses: [], + attachments: mockAttachments, + }, + }), + { + formsg: { + encryptedPayload: { + encryptedContent: 'mockEncryptedContent', + version: 1, + }, + formDef: {}, + encryptedFormDef: mockForm, + unencryptedAttachments: mockAttachments, + } as unknown as EncryptSubmissionDto, + } as unknown as FormCompleteDto, + ) as unknown as SubmitEncryptModeFormHandlerRequest + + const mockRes = expressHandler.mockResponse() + + // Act + await submitEncryptModeFormForTest(mockReq, mockRes) + + // Assert (done) + expect(MockMailService.sendSubmissionToAdmin).toHaveBeenCalledWith( + expect.objectContaining({ + attachments: mockAttachments, + }), + ) + }) + }) }) diff --git a/src/app/modules/submission/encrypt-submission/encrypt-submission.controller.ts b/src/app/modules/submission/encrypt-submission/encrypt-submission.controller.ts index 1597502a23..f61b94d36f 100644 --- a/src/app/modules/submission/encrypt-submission/encrypt-submission.controller.ts +++ b/src/app/modules/submission/encrypt-submission/encrypt-submission.controller.ts @@ -802,7 +802,7 @@ const _createSubmission = async ({ created: createdTime, id: submission.id, }, - attachments: undefined, // Don't send attachments in the email notifications + attachments: unencryptedAttachments, formData: emailData.formData, }) } diff --git a/src/app/services/mail/__tests__/mail.service.spec.ts b/src/app/services/mail/__tests__/mail.service.spec.ts index 052c83ae9a..e5bebb769f 100644 --- a/src/app/services/mail/__tests__/mail.service.spec.ts +++ b/src/app/services/mail/__tests__/mail.service.spec.ts @@ -379,7 +379,13 @@ describe('mail.service', () => { id: 'mockSubmissionId', created: new Date(), }, - attachments: [], + attachments: [ + { + filename: 'test.pdf', + content: Buffer.from('this is a test file'), + fieldId: 'test-field-id', + }, + ], dataCollationData: [ { question: 'some question',