Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 28 additions & 42 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

120 changes: 120 additions & 0 deletions src/server/plugins/SummaryPageWithConfirmationEmailController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ControllerType,
type PageSummaryWithConfirmationEmail
} from '@defra/forms-model'
import { type ResponseObject } from '@hapi/hapi'

import {
SummaryPageWithConfirmationEmailController,
Expand Down Expand Up @@ -129,6 +130,125 @@ describe('SummaryPageWithConfirmationEmailController', () => {
})
})

describe('persists userConfirmationEmailAddress to state', () => {
const responseStub = {} as ResponseObject

it('should mergeState with the email when payload provides it', async () => {
const state: FormSubmissionState = {
$$__referenceNumber: 'foobar',
licenceLength: 365,
fullName: 'John Smith'
}
const mergedState: FormSubmissionState = {
$$__referenceNumber: 'foobar',
licenceLength: 365,
fullName: 'John Smith',
userConfirmationEmailAddress: 'cya@example.com'
}
const request = {
...requestPage,
method: 'post',
payload: {
action: 'send',
userConfirmationEmailAddress: 'cya@example.com'
}
} as unknown as FormRequestPayload

const context = model.getFormContext(request, state)

const mergeStateSpy = jest
.spyOn(controller, 'mergeState')
.mockResolvedValue(mergedState)
jest.spyOn(controller, 'handleFormSubmit').mockResolvedValue(responseStub)

const postHandler = controller.makePostRouteHandler()
await postHandler(request, context, h)

expect(mergeStateSpy).toHaveBeenCalledWith(request, expect.any(Object), {
userConfirmationEmailAddress: 'cya@example.com'
})
expect(context.state.userConfirmationEmailAddress).toBe('cya@example.com')
})

it('should not mergeState when payload omits the email', async () => {
const state: FormSubmissionState = {
$$__referenceNumber: 'foobar',
licenceLength: 365,
fullName: 'John Smith'
}
const request = {
...requestPage,
method: 'post',
payload: { action: 'send' }
} as unknown as FormRequestPayload

const context = model.getFormContext(request, state)

const mergeStateSpy = jest
.spyOn(controller, 'mergeState')
.mockResolvedValue(state)
jest.spyOn(controller, 'handleFormSubmit').mockResolvedValue(responseStub)

const postHandler = controller.makePostRouteHandler()
await postHandler(request, context, h)

expect(mergeStateSpy).not.toHaveBeenCalled()
})

it('should not mergeState when payload provides an empty email', async () => {
const state: FormSubmissionState = {
$$__referenceNumber: 'foobar',
licenceLength: 365,
fullName: 'John Smith'
}
const request = {
...requestPage,
method: 'post',
payload: { action: 'send', userConfirmationEmailAddress: '' }
} as unknown as FormRequestPayload

const context = model.getFormContext(request, state)

const mergeStateSpy = jest
.spyOn(controller, 'mergeState')
.mockResolvedValue(state)
jest.spyOn(controller, 'handleFormSubmit').mockResolvedValue(responseStub)

const postHandler = controller.makePostRouteHandler()
await postHandler(request, context, h)

expect(mergeStateSpy).not.toHaveBeenCalled()
})

it('should propagate the error when mergeState rejects', async () => {
const state: FormSubmissionState = {
$$__referenceNumber: 'foobar',
licenceLength: 365,
fullName: 'John Smith'
}
const request = {
...requestPage,
method: 'post',
payload: {
action: 'send',
userConfirmationEmailAddress: 'cya@example.com'
}
} as unknown as FormRequestPayload

const context = model.getFormContext(request, state)

const cacheError = new Error('cache unavailable')
jest.spyOn(controller, 'mergeState').mockRejectedValue(cacheError)
const handleFormSubmitSpy = jest
.spyOn(controller, 'handleFormSubmit')
.mockResolvedValue(responseStub)

const postHandler = controller.makePostRouteHandler()
await expect(postHandler(request, context, h)).rejects.toBe(cacheError)
expect(handleFormSubmitSpy).not.toHaveBeenCalled()
})
})

describe('getUserConfirmationEmailAddress', () => {
test('should get confirmation email', () => {
const field = getUserConfirmationEmailAddress()
Expand Down
13 changes: 13 additions & 0 deletions src/server/plugins/SummaryPageWithConfirmationEmailController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ export class SummaryPageWithConfirmationEmailController extends SummaryPageContr
return h.view(viewName, viewModel)
}

const userConfirmationEmailAddress =
request.payload[CONFIRMATION_EMAIL_FIELD_NAME]
if (
typeof userConfirmationEmailAddress === 'string' &&
userConfirmationEmailAddress
) {
context.state = await (
this as unknown as QuestionPageController
).mergeState(request, context.state, {
[CONFIRMATION_EMAIL_FIELD_NAME]: userConfirmationEmailAddress
})
}

// Should not have to coerce the type - ticket to resolve later https://eaflood.atlassian.net/browse/DF-555
return (this as unknown as SummaryPageController).handleFormSubmit(
request,
Expand Down
18 changes: 7 additions & 11 deletions src/server/services/outputService.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,16 @@ describe('OutputService', () => {
data: mockItems
}

const mockRequestWithEmail = /** @type {FormRequestPayload} */ (
/** @type {unknown} */ ({
...mockRequest,
payload: {
userConfirmationEmailAddress: 'my-email@test123.com'
}
})
)
const mockContextWithEmail = {
...mockContext,
state: { userConfirmationEmailAddress: 'my-email@test123.com' }
}

mockFormatter.mockReturnValue(JSON.stringify(mockPayload))

await outputService.submit(
mockContext,
mockRequestWithEmail,
mockContextWithEmail,
mockRequest,
mockModel,
'test@example.com',
mockItems,
Expand All @@ -201,7 +197,7 @@ describe('OutputService', () => {
expect(checkFormStatus).toHaveBeenCalledWith(mockRequest.params)
expect(getFormatter).toHaveBeenCalledWith('adapter', '1')
expect(mockFormatter).toHaveBeenCalledWith(
mockContext,
mockContextWithEmail,
mockItems,
mockModel,
mockSubmitResponse,
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/outputService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class OutputService implements IOutputService {

// Add user confirmation email if supplied
const userConfirmationEmailAddress =
request.payload.userConfirmationEmailAddress
context.state.userConfirmationEmailAddress
if (typeof userConfirmationEmailAddress === 'string') {
customMeta.userConfirmationEmail = userConfirmationEmailAddress
}
Expand Down
Loading