From a9f9439156caf3df7db8cb4b8dd0d1f52602b5ee Mon Sep 17 00:00:00 2001 From: seaerchin Date: Tue, 4 May 2021 17:47:42 +0800 Subject: [PATCH 1/8] style(form/errors): fixed typo --- src/app/modules/form/form.errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/modules/form/form.errors.ts b/src/app/modules/form/form.errors.ts index 38b9382d6e..2ef6c2f07c 100644 --- a/src/app/modules/form/form.errors.ts +++ b/src/app/modules/form/form.errors.ts @@ -81,7 +81,7 @@ export class AuthTypeMismatchError extends ApplicationError { export class FormAuthNoEsrvcIdError extends ApplicationError { constructor(formId: string) { super( - `Attempted to validate form ${formId} whhich did not have an eServiceId`, + `Attempted to validate form ${formId} which did not have an eServiceId`, ) } } From 87306d98cd442f156ecebbdadec25bef3fd0a606 Mon Sep 17 00:00:00 2001 From: seaerchin Date: Tue, 4 May 2021 17:48:13 +0800 Subject: [PATCH 2/8] feat(admin-form/service): adds new method to retrieve formfield --- .../form/admin-form/admin-form.service.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/app/modules/form/admin-form/admin-form.service.ts b/src/app/modules/form/admin-form/admin-form.service.ts index 5237d03d16..9a524bc7f9 100644 --- a/src/app/modules/form/admin-form/admin-form.service.ts +++ b/src/app/modules/form/admin-form/admin-form.service.ts @@ -1,7 +1,7 @@ import { PresignedPost } from 'aws-sdk/clients/s3' import { assignIn, last, omit } from 'lodash' import mongoose from 'mongoose' -import { errAsync, okAsync, ResultAsync } from 'neverthrow' +import { err, errAsync, ok, okAsync, Result, ResultAsync } from 'neverthrow' import { Except, Merge } from 'type-fest' import { @@ -880,3 +880,24 @@ export const updateEndPage = ( return okAsync(updatedForm.endPage) }) } + +/** + * Retrieves a form field from the given form. + * @param form The form to retrieve the specified form field for + * @param fieldId the id of the form field + * @returns ok(form field) on success + * @returns err(FieldNotFoundError) if the fieldId does not exist in form's fields + */ +export const getFormField = ( + form: IPopulatedForm, + fieldId: string, +): Result => { + const formField = getFormFieldById(form.form_fields, fieldId) + if (!formField) + return err( + new FieldNotFoundError( + `Attempted to retrieve field ${fieldId} from ${form._id} but field was not present`, + ), + ) + return ok(formField) +} From e84596bbdf484b30efed1b0d0a9a58b23c655ed3 Mon Sep 17 00:00:00 2001 From: seaerchin Date: Tue, 4 May 2021 17:48:55 +0800 Subject: [PATCH 3/8] feat(admin-form/controller): added new handler for GET /field/:fieldId --- .../form/admin-form/admin-form.controller.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/app/modules/form/admin-form/admin-form.controller.ts b/src/app/modules/form/admin-form/admin-form.controller.ts index 21802dd058..241fdee47b 100644 --- a/src/app/modules/form/admin-form/admin-form.controller.ts +++ b/src/app/modules/form/admin-form/admin-form.controller.ts @@ -1950,3 +1950,56 @@ export const handleUpdateEndPage = [ }), _handleUpdateEndPage, ] as RequestHandler[] + +/** + * Handler for GET /admin/forms/:formId/fields/:fieldId + * @security session + * + * @returns 200 with form field + * @returns 403 when current user does not have permissions to retrieve form field + * @returns 404 when form cannot be found + * @returns 404 when form field cannot be found + * @returns 410 when retrieving form field of an archived form + * @returns 422 when user in session cannot be retrieved from the database + * @returns 500 when database error occurs + */ +export const handleGetFormField: RequestHandler< + { + formId: string + fieldId: string + }, + ErrorDto | FormFieldDto +> = (req, res) => { + const { formId, fieldId } = req.params + const sessionUserId = (req.session as Express.AuthedSession).user._id + + return ( + // Step 1: Retrieve currently logged in user. + UserService.getPopulatedUserById(sessionUserId) + .andThen((user) => + // Step 2: Retrieve form with read permission check. + AuthService.getFormAfterPermissionChecks({ + user, + formId, + level: PermissionLevel.Read, + }), + ) + .andThen((form) => AdminFormService.getFormField(form, fieldId)) + .map((formField) => res.status(StatusCodes.OK).json(formField)) + .mapErr((error) => { + logger.error({ + message: 'Error occurred when retrieving form field', + meta: { + action: 'handleGetFormField', + ...createReqMeta(req), + userId: sessionUserId, + formId, + fieldId, + }, + error, + }) + const { errorMessage, statusCode } = mapRouteError(error) + return res.status(statusCode).json({ message: errorMessage }) + }) + ) +} From 3c228254bfdcfc01a83e240b364b203371b4a3b7 Mon Sep 17 00:00:00 2001 From: seaerchin Date: Tue, 4 May 2021 17:49:31 +0800 Subject: [PATCH 4/8] feat(admin-forms/form/routes): added new route for GET /field/:fieldId --- .../api/v3/admin/forms/admin-forms.form.routes.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts index 35f15a4b58..42ef85ab19 100644 --- a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts +++ b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts @@ -128,6 +128,20 @@ AdminFormsFormRouter.route( * @returns 500 when database error occurs during deletion */ .delete(AdminFormController.handleDeleteFormField) + /** + * Retrives the form field using the fieldId from the specified form + * @route GET /admin/forms/:formId/fields/:fieldId + * @security session + * + * @returns 200 with form field + * @returns 403 when current user does not have permissions to retrieve form field + * @returns 404 when form cannot be found + * @returns 404 when form field cannot be found + * @returns 410 when retrieving form field of an archived form + * @returns 422 when user in session cannot be retrieved from the database + * @returns 500 when database error occurs + */ + .get(AdminFormController.handleGetFormField) AdminFormsFormRouter.post( '/:formId([a-fA-F0-9]{24})/fields/:fieldId([a-fA-F0-9]{24})/reorder', From 4a02dab43753b64c89ab54f2c9877eb97104e64f Mon Sep 17 00:00:00 2001 From: seaerchin Date: Tue, 4 May 2021 17:53:38 +0800 Subject: [PATCH 5/8] feat(adminformservice): added new methoid to get single form field --- src/public/services/AdminFormService.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/public/services/AdminFormService.ts b/src/public/services/AdminFormService.ts index 39b6bb022e..5485837c89 100644 --- a/src/public/services/AdminFormService.ts +++ b/src/public/services/AdminFormService.ts @@ -23,6 +23,15 @@ export const updateFormSettings = async ( .then(({ data }) => data) } +export const getSingleFormField = async ( + formId: string, + fieldId: string, +): Promise => { + return axios + .get(`${ADMIN_FORM_ENDPOINT}/${formId}/fields/${fieldId}`) + .then(({ data }) => data) +} + export const updateSingleFormField = async ( formId: string, fieldId: string, From f43e2f059d394b92f43c42ee46b91ec53ffd1911 Mon Sep 17 00:00:00 2001 From: seaerchin Date: Wed, 5 May 2021 11:45:00 +0800 Subject: [PATCH 6/8] docs(admin-form): updated docs for get /fields/:fieldId --- src/app/modules/form/admin-form/admin-form.controller.ts | 2 +- src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/modules/form/admin-form/admin-form.controller.ts b/src/app/modules/form/admin-form/admin-form.controller.ts index 241fdee47b..02c58ee8f2 100644 --- a/src/app/modules/form/admin-form/admin-form.controller.ts +++ b/src/app/modules/form/admin-form/admin-form.controller.ts @@ -1955,7 +1955,7 @@ export const handleUpdateEndPage = [ * Handler for GET /admin/forms/:formId/fields/:fieldId * @security session * - * @returns 200 with form field + * @returns 200 with form field when retrieval is successful * @returns 403 when current user does not have permissions to retrieve form field * @returns 404 when form cannot be found * @returns 404 when form field cannot be found diff --git a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts index 42ef85ab19..bdf822be16 100644 --- a/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts +++ b/src/app/routes/api/v3/admin/forms/admin-forms.form.routes.ts @@ -133,7 +133,7 @@ AdminFormsFormRouter.route( * @route GET /admin/forms/:formId/fields/:fieldId * @security session * - * @returns 200 with form field + * @returns 200 with form field when retrieval is successful * @returns 403 when current user does not have permissions to retrieve form field * @returns 404 when form cannot be found * @returns 404 when form field cannot be found From 07386aabb09b95459f91b23f2bdb56acf9ae2841 Mon Sep 17 00:00:00 2001 From: seaerchin Date: Wed, 5 May 2021 11:46:04 +0800 Subject: [PATCH 7/8] refactor(generate-form-data): added extra case statement for generation of Rating field --- tests/unit/backend/helpers/generate-form-data.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/backend/helpers/generate-form-data.ts b/tests/unit/backend/helpers/generate-form-data.ts index 5be6395eac..2fcc97e109 100644 --- a/tests/unit/backend/helpers/generate-form-data.ts +++ b/tests/unit/backend/helpers/generate-form-data.ts @@ -31,6 +31,7 @@ import { IMobileFieldSchema, INumberField, IRatingField, + IRatingFieldSchema, IShortTextField, IShortTextFieldSchema, ISingleAnswerResponse, @@ -153,6 +154,15 @@ export const generateDefaultField = ( getQuestion: () => defaultParams.title, ...customParams, } as IHomenoFieldSchema + case BasicField.Rating: + return { + ...defaultParams, + ratingOptions: { + shape: 'Heart', + steps: 5, + }, + ...customParams, + } as IRatingFieldSchema default: return { ...defaultParams, From 5f12cab159de67b6cadbf0a3827babbc70deb77b Mon Sep 17 00:00:00 2001 From: seaerchin Date: Wed, 5 May 2021 11:47:52 +0800 Subject: [PATCH 8/8] test(admin-form): added unit and integration tests for GET /fields/:fieldId --- .../__tests__/admin-form.controller.spec.ts | 181 ++++++++++++++++++ .../__tests__/admin-form.service.spec.ts | 40 ++++ .../__tests__/admin-forms.form.routes.spec.ts | 159 ++++++++++++++- 3 files changed, 378 insertions(+), 2 deletions(-) diff --git a/src/app/modules/form/admin-form/__tests__/admin-form.controller.spec.ts b/src/app/modules/form/admin-form/__tests__/admin-form.controller.spec.ts index acb1097360..ee6eb5f4bb 100644 --- a/src/app/modules/form/admin-form/__tests__/admin-form.controller.spec.ts +++ b/src/app/modules/form/admin-form/__tests__/admin-form.controller.spec.ts @@ -8543,4 +8543,185 @@ describe('admin-form.controller', () => { }) }) }) + + describe('handleGetFormField', () => { + const MOCK_USER_ID = new ObjectId().toHexString() + const MOCK_FORM_ID = new ObjectId().toHexString() + const MOCK_USER = { + _id: MOCK_USER_ID, + email: 'somerandom@example.com', + } as IPopulatedUser + const MOCK_FIELDS = [ + generateDefaultField(BasicField.Rating), + generateDefaultField(BasicField.Table), + ] + const MOCK_FIELD_ID = String(MOCK_FIELDS[1]._id) + + const MOCK_FORM = { + admin: MOCK_USER, + _id: MOCK_FORM_ID, + form_fields: MOCK_FIELDS, + title: 'mock title', + } as IPopulatedForm + + const MOCK_REQ = expressHandler.mockRequest({ + params: { + formId: MOCK_FORM_ID, + fieldId: MOCK_FIELD_ID, + }, + session: { + user: { + _id: MOCK_USER_ID, + }, + }, + }) + + beforeEach(() => { + // Mock various services to return expected results. + MockUserService.getPopulatedUserById.mockReturnValue(okAsync(MOCK_USER)) + MockAuthService.getFormAfterPermissionChecks.mockReturnValue( + okAsync(MOCK_FORM), + ) + }) + + it('should return 200 when deletion is successful', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + MockAdminFormService.getFormField.mockReturnValueOnce(ok(MOCK_FIELDS[1])) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(200) + expect(mockRes.json).toHaveBeenCalledWith(MOCK_FIELDS[1]) + expect(MockAdminFormService.getFormField).toHaveBeenCalledWith( + MOCK_FORM, + MOCK_FIELD_ID, + ) + }) + + it('should return 403 when current user does not have permissions to retrieve form fields', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + const expectedErrorString = 'no write permissions' + MockAuthService.getFormAfterPermissionChecks.mockReturnValueOnce( + errAsync(new ForbiddenFormError(expectedErrorString)), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(403) + expect(mockRes.json).toHaveBeenCalledWith({ + message: expectedErrorString, + }) + expect(MockAdminFormService.deleteFormField).not.toHaveBeenCalled() + }) + + it('should return 404 when field to retrieve cannot be found', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + MockAdminFormService.getFormField.mockReturnValueOnce( + err(new FieldNotFoundError('Field to retrieve not found')), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(404) + expect(mockRes.json).toHaveBeenCalledWith({ + message: 'Field to retrieve not found', + }) + expect(MockAdminFormService.getFormField).toHaveBeenCalledWith( + MOCK_FORM, + MOCK_FIELD_ID, + ) + }) + + it('should return 404 when form to retrieve form field for cannot be found', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + + const expectedErrorString = 'nope' + MockAuthService.getFormAfterPermissionChecks.mockReturnValueOnce( + errAsync(new FormNotFoundError(expectedErrorString)), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(404) + expect(mockRes.json).toHaveBeenCalledWith({ + message: expectedErrorString, + }) + expect(MockAdminFormService.getFormField).not.toHaveBeenCalled() + }) + + it('should return 410 when form to retrieve form field for is already archived', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + + const expectedErrorString = 'already deleted' + MockAuthService.getFormAfterPermissionChecks.mockReturnValueOnce( + errAsync(new FormDeletedError(expectedErrorString)), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(410) + expect(mockRes.json).toHaveBeenCalledWith({ + message: expectedErrorString, + }) + expect(MockAdminFormService.getFormField).not.toHaveBeenCalled() + }) + + it('should return 422 when user in session cannot be retrieved from the database', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + + const expectedErrorString = 'user not in session??!!' + MockUserService.getPopulatedUserById.mockReturnValueOnce( + errAsync(new MissingUserError(expectedErrorString)), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(422) + expect(mockRes.json).toHaveBeenCalledWith({ + message: expectedErrorString, + }) + expect( + MockAuthService.getFormAfterPermissionChecks, + ).not.toHaveBeenCalled() + expect(MockAdminFormService.getFormField).not.toHaveBeenCalled() + }) + + it('should return 500 when generic database error occurs during form field retrieval', async () => { + // Arrange + const mockRes = expressHandler.mockResponse() + + const expectedErrorString = 'some database error bam' + MockUserService.getPopulatedUserById.mockReturnValueOnce( + errAsync(new DatabaseError(expectedErrorString)), + ) + + // Act + await AdminFormController.handleGetFormField(MOCK_REQ, mockRes, jest.fn()) + + // Assert + expect(mockRes.status).toHaveBeenCalledWith(500) + expect(mockRes.json).toHaveBeenCalledWith({ + message: expectedErrorString, + }) + expect(MockAdminFormService.getFormField).not.toHaveBeenCalled() + }) + }) }) diff --git a/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts b/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts index 08ab4e1e85..91eec37bee 100644 --- a/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts +++ b/src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts @@ -70,6 +70,7 @@ import { duplicateForm, editFormFields, getDashboardForms, + getFormField, reorderFormField, transferFormOwnership, updateEndPage, @@ -1808,4 +1809,43 @@ describe('admin-form.service', () => { expect(UPDATE_SPY).not.toHaveBeenCalled() }) }) + + describe('getFormField', () => { + it('should return the form field when retrieval is successful', async () => { + // Arrange + const MOCK_FIELD = generateDefaultField(BasicField.Image) + const MOCK_FORM = { + title: 'some mock form', + // Append created field to end of form_fields. + form_fields: [MOCK_FIELD], + _id: new ObjectId(), + } as IFormSchema + + // Act + const actual = await getFormField(MOCK_FORM, String(MOCK_FIELD._id)) + + // Assert + expect(actual._unsafeUnwrap()).toEqual(MOCK_FIELD) + }) + + it("should return FieldNotFoundError when the fieldId does not exist in the form's fields", async () => { + // Arrange + const MOCK_ID = new ObjectId().toHexString() + const MOCK_FORM = ({ + title: 'some mock form', + // Append created field to end of form_fields. + form_fields: [], + _id: new ObjectId(), + } as unknown) as IFormSchema + const expectedError = new FieldNotFoundError( + `Attempted to retrieve field ${MOCK_ID} from ${MOCK_FORM._id} but field was not present`, + ) + + // Act + const actual = await getFormField(MOCK_FORM, MOCK_ID) + + // Assert + expect(actual._unsafeUnwrapErr()).toEqual(expectedError) + }) + }) }) diff --git a/src/app/routes/api/v3/admin/forms/__tests__/admin-forms.form.routes.spec.ts b/src/app/routes/api/v3/admin/forms/__tests__/admin-forms.form.routes.spec.ts index bf9d51d15d..9f46dc0d82 100644 --- a/src/app/routes/api/v3/admin/forms/__tests__/admin-forms.form.routes.spec.ts +++ b/src/app/routes/api/v3/admin/forms/__tests__/admin-forms.form.routes.spec.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { ObjectId } from 'bson-ext' import mongoose from 'mongoose' -import { errAsync } from 'neverthrow' +import { err, errAsync } from 'neverthrow' import supertest, { Session } from 'supertest-session' import getFormModel, { @@ -13,7 +13,7 @@ import { DatabaseError, DatabasePayloadSizeError, } from 'src/app/modules/core/core.errors' -import { IUserSchema, ResponseMode, Status } from 'src/types' +import { BasicField, IUserSchema, ResponseMode, Status } from 'src/types' import { createAuthedSession, @@ -21,6 +21,7 @@ import { } from 'tests/integration/helpers/express-auth' import { setupApp } from 'tests/integration/helpers/express-setup' import { buildCelebrateError } from 'tests/unit/backend/helpers/celebrate' +import { generateDefaultField } from 'tests/unit/backend/helpers/generate-form-data' import dbHandler from 'tests/unit/backend/helpers/jest-db' import { jsonParseStringify } from 'tests/unit/backend/helpers/serialize-data' @@ -1274,4 +1275,158 @@ describe('admin-form.form.routes', () => { expect(response.body).toEqual({ message: 'User not found' }) }) }) + + describe('GET /admin/forms/:formId/fields/', () => { + it('should return 200 with success message when form field is successfully retrieved', async () => { + // Arrange + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + const MOCK_FORM = await EmailFormModel.create({ + title: 'Form to retrieve', + emails: [defaultUser.email], + admin: defaultUser._id, + form_fields: [MOCK_FIELD], + }) + + // Act + const response = await request.get( + `/admin/forms/${MOCK_FORM._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(200) + expect(response.body).toEqual(jsonParseStringify(MOCK_FIELD)) + }) + + it('should return 403 when user does not have permissions to retrieve form field', async () => { + // Arrange + // Create separate user + const collabUser = ( + await dbHandler.insertFormCollectionReqs({ + userId: new ObjectId(), + mailName: 'collab-user', + shortName: 'collabUser', + }) + ).user + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + const MOCK_FORM = await EncryptFormModel.create({ + title: 'form that user has no read access to', + admin: collabUser._id, + publicKey: 'some random key', + }) + + // Act + const response = await request.get( + `/admin/forms/${MOCK_FORM._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(403) + expect(response.body).toEqual({ + message: `User ${defaultUser.email} not authorized to perform read operation on Form ${MOCK_FORM._id} with title: ${MOCK_FORM.title}.`, + }) + }) + + it('should return 404 when form to retrieve cannot be found', async () => { + // Arrange + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + const invalidFormId = new ObjectId().toHexString() + + // Act + const response = await request.get( + `/admin/forms/${invalidFormId}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(404) + expect(response.body).toEqual({ message: 'Form not found' }) + }) + + it('should return 404 when form field to retrieve cannot be found', async () => { + // Arrange + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + const MOCK_FORM = await EmailFormModel.create({ + title: 'Form to retrieve', + emails: [defaultUser.email], + admin: defaultUser._id, + form_fields: [], + }) + + // Act + const response = await request.get( + `/admin/forms/${MOCK_FORM._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(404) + expect(response.body).toEqual({ + message: `Attempted to retrieve field ${MOCK_FIELD._id} from ${MOCK_FORM._id} but field was not present`, + }) + }) + + it('should return 410 when form is already archived', async () => { + // Arrange + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + const archivedForm = await EmailFormModel.create({ + title: 'Form already archived', + emails: [defaultUser.email], + admin: defaultUser._id, + status: Status.Archived, + }) + + // Act + const response = await request.get( + `/admin/forms/${archivedForm._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(410) + expect(response.body).toEqual({ message: 'Form has been archived' }) + }) + + it('should return 422 when user in session cannot be found in the database', async () => { + // Arrange + const MOCK_FORM = await EmailFormModel.create({ + title: 'Form to retrieve', + emails: [defaultUser.email], + admin: defaultUser._id, + }) + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + // Delete user after login. + await dbHandler.clearCollection(UserModel.collection.name) + + // Act + const response = await request.get( + `/admin/forms/${MOCK_FORM._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(422) + expect(response.body).toEqual({ message: 'User not found' }) + }) + + it('should return 500 when database error occurs whilst archiving form', async () => { + // Arrange + const MOCK_FORM = await EmailFormModel.create({ + title: 'Form to retrieve', + emails: [defaultUser.email], + admin: defaultUser._id, + }) + const MOCK_FIELD = generateDefaultField(BasicField.Rating) + // Mock database error during retrieval. + jest + .spyOn(AdminFormService, 'getFormField') + .mockReturnValueOnce(err(new DatabaseError())) + + // Act + const response = await request.get( + `/admin/forms/${MOCK_FORM._id}/fields/${MOCK_FIELD._id}`, + ) + + // Assert + expect(response.status).toEqual(500) + expect(response.body).toEqual({ + message: 'Something went wrong. Please try again.', + }) + }) + }) })