Skip to content

Commit

Permalink
feat: add tc for delete form fields controller and service
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin9foong committed Dec 30, 2024
1 parent 89a3f1c commit 37e0940
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,58 @@ describe('admin-form.assistance.service', () => {
expect(calledNewFields[0].description).toBeTruthy()
expect(calledNewFields[0].description.trim()).not.toBe('')
})

it('should return created field ids provided by return value of AdminFormService.createFormFields', async () => {
// Arrange
const VALID_ALL_FIELDS_INCLUDED_RESPONSE =
'[{"title":"Cat Information","fieldType":"Section","required":false},{"title":"Please provide the name of your cat.","fieldType":"Statement","required":true,"description":"This information is needed to identify your pet."},{"title":"Your Email Address","fieldType":"Email","required":true},{"title":"Your Mobile Number","fieldType":"Mobile","required":true},{"title":"Your Home Phone Number","fieldType":"HomeNo","required":false},{"title":"How many cats do you have?","fieldType":"Number","required":true},{"title":"How much do you spend on cat care monthly?","fieldType":"Decimal","required":true},{"title":"Cat\'s Name (Short)","fieldType":"ShortText","required":true},{"title":"Tell us more about your cat (Long)","fieldType":"LongText","required":false},{"title":"Select your favorite cat breed","fieldType":"Dropdown","required":true,"fieldOptions":["Siamese","Persian","Maine Coon","Bengal","Sphynx"]},{"title":"Country/Region","fieldType":"CountryRegion","required":true},{"title":"Do you agree to share your cat\'s name for our records?","fieldType":"YesNo","required":true},{"title":"Do you want to receive updates about cat care?","fieldType":"Checkbox","required":false,"fieldOptions":["Yes, send me emails","No, thank you"]},{"title":"Select your preferred communication method","fieldType":"Radio","required":true,"fieldOptions":["Email","Phone","SMS"]},{"title":"Upload a picture of your cat","fieldType":"Attachment","required":false},{"title":"Select the date of your cat\'s birthday","fieldType":"Date","required":true},{"title":"Rate your satisfaction with our cat services (1-5)","fieldType":"Rating","required":true},{"title":"Your NRIC Number","fieldType":"Nric","required":true},{"title":"Your Business UEN (if applicable)","fieldType":"Uen","required":false},{"title":"Cat Care Records","fieldType":"Table","required":true,"columns":["Date","Activity","Notes"],"minimumRows":1,"addMoreRows":true}]'

MockedAiModel.sendUserTextPrompt = jest
.fn()
.mockReturnValue(okAsync(VALID_ALL_FIELDS_INCLUDED_RESPONSE))

const CREATED_FIELD_SCHEMAS = [
{ _id: '507f1f77bcf86cd799439011' },
{ _id: '507f1f77bcf86cd799439012' },
{ _id: '507f1f77bcf86cd799439013' },
{ _id: '507f1f77bcf86cd799439014' },
{ _id: '507f1f77bcf86cd799439015' },
{ _id: '507f1f77bcf86cd799439016' },
{ _id: '507f1f77bcf86cd799439017' },
{ _id: '507f1f77bcf86cd799439018' },
{ _id: '507f1f77bcf86cd799439019' },
{ _id: '507f1f77bcf86cd799439020' },
{ _id: '507f1f77bcf86cd799439021' },
{ _id: '507f1f77bcf86cd799439022' },
{ _id: '507f1f77bcf86cd799439023' },
{ _id: '507f1f77bcf86cd799439024' },
{ _id: '507f1f77bcf86cd799439025' },
{ _id: '507f1f77bcf86cd799439026' },
{ _id: '507f1f77bcf86cd799439027' },
{ _id: '507f1f77bcf86cd799439028' },
{ _id: '507f1f77bcf86cd799439029' },
{ _id: '507f1f77bcf86cd799439030' },
]

const mockedCreateFormFields =
AdminFormService.createFormFields as jest.Mock
mockedCreateFormFields.mockReturnValueOnce(
okAsync(CREATED_FIELD_SCHEMAS as FormFieldSchema[]),
)

// Act
const createdFieldIds = await createFormFieldsUsingTextPrompt({
form: mockForm,
userPrompt: mockUserPrompt,
})

// Assert
expect(AdminFormService.createFormFields).toHaveBeenCalledTimes(1)
expect(createdFieldIds.isOk()).toBe(true)
expect(createdFieldIds._unsafeUnwrap()).toEqual(
CREATED_FIELD_SCHEMAS.map((field) => field._id),
)
})
})

describe('model errors', () => {
Expand Down
126 changes: 126 additions & 0 deletions src/app/modules/form/admin-form/__tests__/admin-form.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { CreatePresignedPostError } from 'src/app/utils/aws-s3'
import { formatErrorRecoveryMessage } from 'src/app/utils/handle-mongo-error'
import { EditFieldActions } from 'src/shared/constants'
import {
FormFieldSchema,
FormLogicSchema,
IEmailFormSchema,
IFormDocument,
Expand Down Expand Up @@ -2428,6 +2429,131 @@ describe('admin-form.service', () => {
})
})

describe('deleteFormFields', () => {
const deleteFormFieldsSpy = jest.spyOn(FormModel, 'deleteFormFieldsByIds')

it('should return updated form when all fields to delete are found and deleted successfully', async () => {
// Arrange
const fieldsToDelete = [
generateDefaultField(BasicField.Mobile),
generateDefaultField(BasicField.Image),
]

const mockUpdatedForm = {
title: 'some mock form',
form_fields: [generateDefaultField(BasicField.Nric)],
} as IFormSchema

const mockForm = {
...mockUpdatedForm,
form_fields: [
...fieldsToDelete,
...(mockUpdatedForm.form_fields as FormFieldSchema[]),
],
} as unknown as IPopulatedForm

deleteFormFieldsSpy.mockResolvedValueOnce(mockUpdatedForm)

// Act
const actual = await AdminFormService.deleteFormFields(
mockForm,
fieldsToDelete.map((f) => String(f._id)),
)

// Assert
expect(actual._unsafeUnwrap()).toEqual(mockUpdatedForm)
expect(deleteFormFieldsSpy).toHaveBeenCalledWith(
mockForm._id,
fieldsToDelete.map((f) => f._id),
)
})

it('should return FormNotFoundError when form cannot be found', async () => {
// Arrange
const mockForm = {
_id: new ObjectId(),
form_fields: [generateDefaultField(BasicField.Mobile)],
} as unknown as IPopulatedForm

deleteFormFieldsSpy.mockResolvedValueOnce(null)

// Act
const actual = await AdminFormService.deleteFormFields(mockForm, [
mockForm.form_fields[0]._id,
])

// Assert
expect(actual._unsafeUnwrapErr()).toEqual(new FormNotFoundError())
expect(deleteFormFieldsSpy).toHaveBeenCalledWith(mockForm._id, [
mockForm.form_fields[0]._id,
])
})

it('should return updated form when some fields to delete are found and some are not found', async () => {
// Arrange
const fieldsToDelete = [
generateDefaultField(BasicField.Mobile),
generateDefaultField(BasicField.Image),
]

const mockUpdatedForm = {
title: 'some mock form',
form_fields: [generateDefaultField(BasicField.Nric)],
} as IFormSchema

const mockForm = {
...mockUpdatedForm,
form_fields: [
...fieldsToDelete,
...(mockUpdatedForm.form_fields as FormFieldSchema[]),
],
} as unknown as IPopulatedForm

deleteFormFieldsSpy.mockResolvedValueOnce(mockUpdatedForm)

// Act
const actual = await AdminFormService.deleteFormFields(
mockForm,
fieldsToDelete.map((f) => String(f._id)),
)

// Assert
expect(actual._unsafeUnwrap()).toEqual(mockUpdatedForm)
expect(deleteFormFieldsSpy).toHaveBeenCalledWith(
mockForm._id,
fieldsToDelete.map((f) => f._id),
)
})

it('should return unchanged form when no fields to delete are found', async () => {
// Arrange
const mockForm = {
title: 'some mock form',
form_fields: [generateDefaultField(BasicField.Nric)],
_id: new ObjectId(),
} as unknown as IPopulatedForm

const mockUpdatedForm = {
...mockForm,
} as IFormSchema

deleteFormFieldsSpy.mockResolvedValueOnce(mockUpdatedForm)

const nonExistentFieldId = new ObjectId().toHexString()

// Act
const actual = await AdminFormService.deleteFormFields(mockForm, [
nonExistentFieldId,
])

// Assert
expect(actual._unsafeUnwrap()).toEqual(mockUpdatedForm)
expect(deleteFormFieldsSpy).toHaveBeenCalledWith(mockForm._id, [
nonExistentFieldId,
])
})
})

describe('updateEndPage', () => {
const updateSpy = jest.spyOn(FormModel, 'updateEndPageById')
const MOCK_FORM_ID = new ObjectId().toHexString()
Expand Down

0 comments on commit 37e0940

Please sign in to comment.