@defra/forms-engine-plugin 2.1.10 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.server/server/index.js +2 -1
- package/.server/server/index.js.map +1 -1
- package/.server/server/plugins/engine/README.md +2 -2
- package/.server/server/plugins/engine/configureEnginePlugin.d.ts +2 -1
- package/.server/server/plugins/engine/configureEnginePlugin.js +4 -4
- package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
- package/.server/server/plugins/engine/helpers.d.ts +7 -11
- package/.server/server/plugins/engine/helpers.js +2 -2
- package/.server/server/plugins/engine/helpers.js.map +1 -1
- package/.server/server/plugins/engine/models/FormModel.js +1 -1
- package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
- package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +1 -1
- package/.server/server/plugins/engine/models/SummaryViewModel.js +1 -1
- package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
- package/.server/server/plugins/engine/options.js +3 -6
- package/.server/server/plugins/engine/options.js.map +1 -1
- package/.server/server/plugins/engine/options.test.js +2 -8
- package/.server/server/plugins/engine/options.test.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +5 -6
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/PageController.d.ts +6 -6
- package/.server/server/plugins/engine/pageControllers/PageController.js +4 -4
- package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +13 -13
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +12 -20
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +7 -8
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +2 -2
- package/.server/server/plugins/engine/pageControllers/StartPageController.js +1 -1
- package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/StatusPageController.d.ts +3 -4
- package/.server/server/plugins/engine/pageControllers/StatusPageController.js +1 -1
- package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +5 -4
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +12 -1
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/TerminalPageController.d.ts +4 -4
- package/.server/server/plugins/engine/pageControllers/TerminalPageController.js +1 -1
- package/.server/server/plugins/engine/pageControllers/TerminalPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/__stubs__/server.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/__stubs__/server.js +2 -6
- package/.server/server/plugins/engine/pageControllers/__stubs__/server.js.map +1 -1
- package/.server/server/plugins/engine/plugin.js +7 -12
- package/.server/server/plugins/engine/plugin.js.map +1 -1
- package/.server/server/plugins/engine/routes/index.d.ts +5 -5
- package/.server/server/plugins/engine/routes/index.js.map +1 -1
- package/.server/server/plugins/engine/routes/questions.d.ts +4 -4
- package/.server/server/plugins/engine/routes/questions.js.map +1 -1
- package/.server/server/plugins/engine/routes/repeaters/item-delete.js.map +1 -1
- package/.server/server/plugins/engine/routes/repeaters/summary.js.map +1 -1
- package/.server/server/plugins/engine/types/index.d.ts +2 -2
- package/.server/server/plugins/engine/types/index.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +10 -11
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/views/partials/form.html +3 -3
- package/.server/server/plugins/engine/views/summary.html +21 -5
- package/.server/server/plugins/nunjucks/context.d.ts +5 -6
- package/.server/server/plugins/nunjucks/context.js +3 -3
- package/.server/server/plugins/nunjucks/context.js.map +1 -1
- package/.server/server/routes/types.d.ts +3 -2
- package/.server/server/routes/types.js +1 -1
- package/.server/server/routes/types.js.map +1 -1
- package/.server/server/schemas/index.js +1 -1
- package/.server/server/schemas/index.js.map +1 -1
- package/.server/server/services/cacheService.d.ts +11 -19
- package/.server/server/services/cacheService.js +9 -30
- package/.server/server/services/cacheService.js.map +1 -1
- package/.server/server/types.d.ts +4 -1
- package/.server/server/types.js.map +1 -1
- package/.server/typings/hapi/index.d.js.map +1 -1
- package/package.json +3 -1
- package/src/server/index.test.ts +0 -39
- package/src/server/index.ts +4 -1
- package/src/server/plugins/engine/README.md +2 -2
- package/src/server/plugins/engine/components/helpers/helpers.test.ts +1 -1
- package/src/server/plugins/engine/configureEnginePlugin.ts +15 -11
- package/src/server/plugins/engine/helpers.test.ts +3 -2
- package/src/server/plugins/engine/helpers.ts +6 -6
- package/src/server/plugins/engine/models/FormModel.test.ts +2 -2
- package/src/server/plugins/engine/models/FormModel.ts +1 -2
- package/src/server/plugins/engine/models/SummaryViewModel.test.ts +7 -7
- package/src/server/plugins/engine/models/SummaryViewModel.ts +1 -1
- package/src/server/plugins/engine/options.js +6 -6
- package/src/server/plugins/engine/options.test.js +2 -6
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +8 -10
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +9 -8
- package/src/server/plugins/engine/pageControllers/PageController.test.ts +11 -8
- package/src/server/plugins/engine/pageControllers/PageController.ts +9 -15
- package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +35 -102
- package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +24 -36
- package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +4 -6
- package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +8 -11
- package/src/server/plugins/engine/pageControllers/StartPageController.test.ts +4 -4
- package/src/server/plugins/engine/pageControllers/StartPageController.ts +1 -1
- package/src/server/plugins/engine/pageControllers/StatusPageController.test.ts +4 -4
- package/src/server/plugins/engine/pageControllers/StatusPageController.ts +6 -4
- package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -5
- package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +4 -4
- package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +7 -4
- package/src/server/plugins/engine/pageControllers/__stubs__/server.ts +5 -6
- package/src/server/plugins/engine/plugin.ts +7 -13
- package/src/server/plugins/engine/routes/index.ts +6 -11
- package/src/server/plugins/engine/routes/questions.test.ts +29 -53
- package/src/server/plugins/engine/routes/questions.ts +6 -8
- package/src/server/plugins/engine/routes/repeaters/item-delete.ts +5 -14
- package/src/server/plugins/engine/routes/repeaters/summary.ts +5 -14
- package/src/server/plugins/engine/types/index.ts +4 -1
- package/src/server/plugins/engine/types.ts +19 -13
- package/src/server/plugins/engine/views/partials/form.html +3 -3
- package/src/server/plugins/engine/views/summary.html +21 -5
- package/src/server/plugins/nunjucks/context.js +3 -3
- package/src/server/routes/types.ts +7 -2
- package/src/server/schemas/index.ts +1 -1
- package/src/server/services/cacheService.test.ts +1 -117
- package/src/server/services/cacheService.ts +22 -73
- package/src/server/types.ts +4 -1
- package/src/typings/hapi/index.d.ts +6 -7
- package/.server/server/plugins/engine/routes/exit.d.ts +0 -46
- package/.server/server/plugins/engine/routes/exit.js +0 -36
- package/.server/server/plugins/engine/routes/exit.js.map +0 -1
- package/src/server/plugins/engine/routes/exit.ts +0 -47
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type SubmitPayload
|
|
6
6
|
} from '@defra/forms-model'
|
|
7
7
|
import Boom from '@hapi/boom'
|
|
8
|
-
import { type
|
|
8
|
+
import { type RouteOptions } from '@hapi/hapi'
|
|
9
9
|
|
|
10
10
|
import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'
|
|
11
11
|
import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'
|
|
@@ -30,13 +30,16 @@ import {
|
|
|
30
30
|
type FormSubmissionState
|
|
31
31
|
} from '~/src/server/plugins/engine/types.js'
|
|
32
32
|
import {
|
|
33
|
+
FormAction,
|
|
33
34
|
type FormRequest,
|
|
34
35
|
type FormRequestPayload,
|
|
35
|
-
type FormRequestPayloadRefs
|
|
36
|
+
type FormRequestPayloadRefs,
|
|
37
|
+
type FormResponseToolkit
|
|
36
38
|
} from '~/src/server/routes/types.js'
|
|
37
39
|
|
|
38
40
|
export class SummaryPageController extends QuestionPageController {
|
|
39
41
|
declare pageDef: Page
|
|
42
|
+
allowSaveAndExit = true
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
45
|
* The controller which is used when Page["controller"] is defined as "./pages/summary.js"
|
|
@@ -69,7 +72,7 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
69
72
|
viewModel.feedbackLink = this.feedbackLink
|
|
70
73
|
viewModel.phaseTag = this.phaseTag
|
|
71
74
|
viewModel.components = components
|
|
72
|
-
viewModel.
|
|
75
|
+
viewModel.allowSaveAndExit = this.shouldShowSaveAndExit(request.server)
|
|
73
76
|
|
|
74
77
|
return viewModel
|
|
75
78
|
}
|
|
@@ -81,7 +84,7 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
81
84
|
return async (
|
|
82
85
|
request: FormRequest,
|
|
83
86
|
context: FormContext,
|
|
84
|
-
h:
|
|
87
|
+
h: FormResponseToolkit
|
|
85
88
|
) => {
|
|
86
89
|
const { viewName } = this
|
|
87
90
|
|
|
@@ -102,10 +105,17 @@ export class SummaryPageController extends QuestionPageController {
|
|
|
102
105
|
return async (
|
|
103
106
|
request: FormRequestPayload,
|
|
104
107
|
context: FormContext,
|
|
105
|
-
h:
|
|
108
|
+
h: FormResponseToolkit
|
|
106
109
|
) => {
|
|
107
110
|
const { model } = this
|
|
108
111
|
const { params } = request
|
|
112
|
+
|
|
113
|
+
// Check if this is a save-and-exit action
|
|
114
|
+
const { action } = request.payload
|
|
115
|
+
if (action === FormAction.SaveAndExit) {
|
|
116
|
+
return this.handleSaveAndExit(request, context, h)
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
const cacheService = getCacheService(request.server)
|
|
110
120
|
|
|
111
121
|
const { formsService } = this.model.services
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
|
|
2
2
|
import { TerminalPageController } from '~/src/server/plugins/engine/pageControllers/TerminalPageController.js'
|
|
3
|
-
import {
|
|
3
|
+
import { serverWithSaveAndExit } from '~/src/server/plugins/engine/pageControllers/__stubs__/server.js'
|
|
4
4
|
import definition from '~/test/form/definitions/basic.js'
|
|
5
5
|
|
|
6
6
|
describe('TerminalController', () => {
|
|
@@ -27,9 +27,9 @@ describe('TerminalController', () => {
|
|
|
27
27
|
})
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
-
describe('
|
|
31
|
-
it('should return false (TerminalPageController does not allow save and
|
|
32
|
-
expect(controller1.
|
|
30
|
+
describe('shouldShowSaveAndExit', () => {
|
|
31
|
+
it('should return false (TerminalPageController does not allow save and exit)', () => {
|
|
32
|
+
expect(controller1.shouldShowSaveAndExit(serverWithSaveAndExit)).toBe(
|
|
33
33
|
false
|
|
34
34
|
)
|
|
35
35
|
})
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { type PageTerminal } from '@defra/forms-model'
|
|
2
2
|
import Boom from '@hapi/boom'
|
|
3
|
-
import { type ResponseObject
|
|
3
|
+
import { type ResponseObject } from '@hapi/hapi'
|
|
4
4
|
|
|
5
5
|
import { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'
|
|
6
6
|
import { type FormContext } from '~/src/server/plugins/engine/types.js'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type FormRequestPayload,
|
|
9
|
+
type FormResponseToolkit
|
|
10
|
+
} from '~/src/server/routes/types.js'
|
|
8
11
|
|
|
9
12
|
export class TerminalPageController extends QuestionPageController {
|
|
10
13
|
declare pageDef: PageTerminal
|
|
11
|
-
|
|
14
|
+
allowSaveAndExit = false
|
|
12
15
|
|
|
13
16
|
makePostRouteHandler(): (
|
|
14
17
|
request: FormRequestPayload,
|
|
15
18
|
context: FormContext,
|
|
16
|
-
h:
|
|
19
|
+
h: FormResponseToolkit
|
|
17
20
|
) => Promise<ResponseObject> {
|
|
18
21
|
throw Boom.methodNotAllowed('POST method not allowed for terminal pages')
|
|
19
22
|
}
|
|
@@ -12,16 +12,15 @@ export const server: Server = {
|
|
|
12
12
|
}
|
|
13
13
|
} as Server // only mocking out properties we care about;
|
|
14
14
|
|
|
15
|
-
export const
|
|
15
|
+
export const serverWithSaveAndExit: Server = {
|
|
16
16
|
plugins: {
|
|
17
17
|
...server.plugins,
|
|
18
18
|
'forms-engine-plugin': {
|
|
19
19
|
...server.plugins['forms-engine-plugin'],
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} as Pick<PluginOptions, 'saveAndReturn'>
|
|
20
|
+
saveAndExit: jest.fn().mockReturnValue({}) as Pick<
|
|
21
|
+
PluginOptions,
|
|
22
|
+
'saveAndExit'
|
|
23
|
+
>
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
} as Server // only mocking out properties we care about
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
|
|
9
9
|
import { type FormModel } from '~/src/server/plugins/engine/models/index.js'
|
|
10
10
|
import { validatePluginOptions } from '~/src/server/plugins/engine/options.js'
|
|
11
|
-
import { getRoutes as getSaveAndReturnExitRoutes } from '~/src/server/plugins/engine/routes/exit.js'
|
|
12
11
|
import { getRoutes as getFileUploadStatusRoutes } from '~/src/server/plugins/engine/routes/file-upload.js'
|
|
13
12
|
import { makeLoadFormPreHandler } from '~/src/server/plugins/engine/routes/index.js'
|
|
14
13
|
import { getRoutes as getQuestionRoutes } from '~/src/server/plugins/engine/routes/questions.js'
|
|
@@ -31,28 +30,24 @@ export const plugin = {
|
|
|
31
30
|
|
|
32
31
|
const {
|
|
33
32
|
model,
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
cache,
|
|
34
|
+
saveAndExit,
|
|
36
35
|
nunjucks: nunjucksOptions,
|
|
37
36
|
viewContext,
|
|
38
37
|
preparePageEventRequestOptions
|
|
39
38
|
} = options
|
|
40
39
|
|
|
41
|
-
const cacheService =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
keyGenerator: saveAndReturn?.keyGenerator,
|
|
46
|
-
sessionHydrator: saveAndReturn?.sessionHydrator
|
|
47
|
-
}
|
|
48
|
-
})
|
|
40
|
+
const cacheService =
|
|
41
|
+
typeof cache === 'string'
|
|
42
|
+
? new CacheService({ server, cacheName: cache })
|
|
43
|
+
: cache
|
|
49
44
|
|
|
50
45
|
await registerVision(server, options)
|
|
51
46
|
|
|
52
47
|
server.expose('baseLayoutPath', nunjucksOptions.baseLayoutPath)
|
|
53
48
|
server.expose('viewContext', viewContext)
|
|
54
49
|
server.expose('cacheService', cacheService)
|
|
55
|
-
server.expose('
|
|
50
|
+
server.expose('saveAndExit', saveAndExit)
|
|
56
51
|
|
|
57
52
|
server.app.model = model
|
|
58
53
|
|
|
@@ -92,7 +87,6 @@ export const plugin = {
|
|
|
92
87
|
),
|
|
93
88
|
...getRepeaterSummaryRoutes(getRouteOptions, postRouteOptions),
|
|
94
89
|
...getRepeaterItemDeleteRoutes(getRouteOptions, postRouteOptions),
|
|
95
|
-
...getSaveAndReturnExitRoutes(getRouteOptions),
|
|
96
90
|
...getFileUploadStatusRoutes()
|
|
97
91
|
]
|
|
98
92
|
|
|
@@ -21,17 +21,18 @@ import { type PageControllerClass } from '~/src/server/plugins/engine/pageContro
|
|
|
21
21
|
import { generateUniqueReference } from '~/src/server/plugins/engine/referenceNumbers.js'
|
|
22
22
|
import * as defaultServices from '~/src/server/plugins/engine/services/index.js'
|
|
23
23
|
import {
|
|
24
|
+
type AnyFormRequest,
|
|
24
25
|
type FormContext,
|
|
25
26
|
type PluginOptions
|
|
26
27
|
} from '~/src/server/plugins/engine/types.js'
|
|
27
28
|
import {
|
|
28
29
|
type FormRequest,
|
|
29
|
-
type
|
|
30
|
+
type FormResponseToolkit
|
|
30
31
|
} from '~/src/server/routes/types.js'
|
|
31
32
|
|
|
32
33
|
export async function redirectOrMakeHandler(
|
|
33
|
-
request:
|
|
34
|
-
h:
|
|
34
|
+
request: AnyFormRequest,
|
|
35
|
+
h: FormResponseToolkit,
|
|
35
36
|
makeHandler: (
|
|
36
37
|
page: PageControllerClass,
|
|
37
38
|
context: FormContext
|
|
@@ -92,10 +93,7 @@ export function makeLoadFormPreHandler(server: Server, options: PluginOptions) {
|
|
|
92
93
|
|
|
93
94
|
const { formsService } = services
|
|
94
95
|
|
|
95
|
-
async function handler(
|
|
96
|
-
request: FormRequest | FormRequestPayload,
|
|
97
|
-
h: ResponseToolkit
|
|
98
|
-
) {
|
|
96
|
+
async function handler(request: AnyFormRequest, h: ResponseToolkit) {
|
|
99
97
|
if (server.app.model) {
|
|
100
98
|
request.app.model = server.app.model
|
|
101
99
|
|
|
@@ -181,10 +179,7 @@ export function makeLoadFormPreHandler(server: Server, options: PluginOptions) {
|
|
|
181
179
|
return handler
|
|
182
180
|
}
|
|
183
181
|
|
|
184
|
-
export function dispatchHandler(
|
|
185
|
-
request: FormRequest,
|
|
186
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
187
|
-
) {
|
|
182
|
+
export function dispatchHandler(request: FormRequest, h: FormResponseToolkit) {
|
|
188
183
|
const { model } = request.app
|
|
189
184
|
|
|
190
185
|
const servicePath = model ? `/${model.basePath}` : ''
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Boom from '@hapi/boom'
|
|
2
|
-
import { type ResponseObject
|
|
2
|
+
import { type ResponseObject } from '@hapi/hapi'
|
|
3
3
|
// eslint-disable-next-line n/no-unpublished-import
|
|
4
4
|
import nock from 'nock'
|
|
5
5
|
|
|
@@ -10,10 +10,14 @@ import {
|
|
|
10
10
|
makeGetHandler,
|
|
11
11
|
makePostHandler
|
|
12
12
|
} from '~/src/server/plugins/engine/routes/questions.js'
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
type AnyFormRequest,
|
|
15
|
+
type FormContext
|
|
16
|
+
} from '~/src/server/plugins/engine/types.js'
|
|
14
17
|
import {
|
|
15
18
|
type FormRequest,
|
|
16
|
-
type FormRequestPayload
|
|
19
|
+
type FormRequestPayload,
|
|
20
|
+
type FormResponseToolkit
|
|
17
21
|
} from '~/src/server/routes/types.js'
|
|
18
22
|
jest.mock('~/src/server/plugins/engine/models/SummaryViewModel', () => ({
|
|
19
23
|
SummaryViewModel: class {
|
|
@@ -35,7 +39,7 @@ jest.mock('~/src/server/plugins/engine/outputFormatters/machine/v1', () => ({
|
|
|
35
39
|
jest.mock('~/src/server/plugins/engine/routes/index')
|
|
36
40
|
|
|
37
41
|
describe('makeGetHandler', () => {
|
|
38
|
-
const hMock:
|
|
42
|
+
const hMock: FormResponseToolkit = {
|
|
39
43
|
redirect: jest.fn(),
|
|
40
44
|
view: jest.fn()
|
|
41
45
|
}
|
|
@@ -64,7 +68,7 @@ describe('makeGetHandler', () => {
|
|
|
64
68
|
(
|
|
65
69
|
_request: FormRequest,
|
|
66
70
|
context: FormContext,
|
|
67
|
-
_h:
|
|
71
|
+
_h: FormResponseToolkit
|
|
68
72
|
) => {
|
|
69
73
|
data = context.data
|
|
70
74
|
return Promise.resolve({} as unknown as ResponseObject)
|
|
@@ -80,12 +84,8 @@ describe('makeGetHandler', () => {
|
|
|
80
84
|
|
|
81
85
|
jest
|
|
82
86
|
.mocked(redirectOrMakeHandler)
|
|
83
|
-
.mockImplementation(
|
|
84
|
-
(
|
|
85
|
-
_req: FormRequest | FormRequestPayload,
|
|
86
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
87
|
-
fn
|
|
88
|
-
) => Promise.resolve(fn(pageMock, contextMock))
|
|
87
|
+
.mockImplementation((_req: AnyFormRequest, _h: FormResponseToolkit, fn) =>
|
|
88
|
+
Promise.resolve(fn(pageMock, contextMock))
|
|
89
89
|
)
|
|
90
90
|
|
|
91
91
|
await makeGetHandler()(requestMock, hMock)
|
|
@@ -108,7 +108,7 @@ describe('makeGetHandler', () => {
|
|
|
108
108
|
(
|
|
109
109
|
_request: FormRequest,
|
|
110
110
|
context: FormContext,
|
|
111
|
-
_h:
|
|
111
|
+
_h: FormResponseToolkit
|
|
112
112
|
) => {
|
|
113
113
|
data = context.data
|
|
114
114
|
return Promise.resolve({} as unknown as ResponseObject)
|
|
@@ -126,12 +126,8 @@ describe('makeGetHandler', () => {
|
|
|
126
126
|
|
|
127
127
|
jest
|
|
128
128
|
.mocked(redirectOrMakeHandler)
|
|
129
|
-
.mockImplementation(
|
|
130
|
-
(
|
|
131
|
-
_req: FormRequest | FormRequestPayload,
|
|
132
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
133
|
-
fn
|
|
134
|
-
) => Promise.resolve(fn(pageMock, contextMock))
|
|
129
|
+
.mockImplementation((_req: AnyFormRequest, _h: FormResponseToolkit, fn) =>
|
|
130
|
+
Promise.resolve(fn(pageMock, contextMock))
|
|
135
131
|
)
|
|
136
132
|
|
|
137
133
|
await makeGetHandler()(requestMock, hMock)
|
|
@@ -152,7 +148,7 @@ describe('makeGetHandler', () => {
|
|
|
152
148
|
(
|
|
153
149
|
_request: FormRequest,
|
|
154
150
|
_context: FormContext,
|
|
155
|
-
_h:
|
|
151
|
+
_h: FormResponseToolkit
|
|
156
152
|
) => {
|
|
157
153
|
return Promise.resolve({} as unknown as ResponseObject)
|
|
158
154
|
}
|
|
@@ -168,11 +164,7 @@ describe('makeGetHandler', () => {
|
|
|
168
164
|
jest
|
|
169
165
|
.mocked(redirectOrMakeHandler)
|
|
170
166
|
.mockImplementation(
|
|
171
|
-
async (
|
|
172
|
-
_req: FormRequest | FormRequestPayload,
|
|
173
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
174
|
-
fn
|
|
175
|
-
) => {
|
|
167
|
+
async (_req: AnyFormRequest, _h: FormResponseToolkit, fn) => {
|
|
176
168
|
try {
|
|
177
169
|
await fn(pageMock, contextMock)
|
|
178
170
|
} catch (err) {
|
|
@@ -190,7 +182,7 @@ describe('makeGetHandler', () => {
|
|
|
190
182
|
})
|
|
191
183
|
|
|
192
184
|
describe('makePostHandler', () => {
|
|
193
|
-
const hMock:
|
|
185
|
+
const hMock: FormResponseToolkit = {
|
|
194
186
|
redirect: jest.fn(),
|
|
195
187
|
view: jest.fn()
|
|
196
188
|
}
|
|
@@ -221,7 +213,7 @@ describe('makePostHandler', () => {
|
|
|
221
213
|
(
|
|
222
214
|
_request: FormRequest,
|
|
223
215
|
_context: FormContext,
|
|
224
|
-
_h:
|
|
216
|
+
_h: FormResponseToolkit
|
|
225
217
|
) => {
|
|
226
218
|
// do return a valid ResponseObject wrapped in Promise.resolve
|
|
227
219
|
return mockPostResponse
|
|
@@ -238,12 +230,8 @@ describe('makePostHandler', () => {
|
|
|
238
230
|
|
|
239
231
|
jest
|
|
240
232
|
.mocked(redirectOrMakeHandler)
|
|
241
|
-
.mockImplementation(
|
|
242
|
-
(
|
|
243
|
-
_req: FormRequest | FormRequestPayload,
|
|
244
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
245
|
-
fn
|
|
246
|
-
) => Promise.resolve(fn(pageMock, contextMock))
|
|
233
|
+
.mockImplementation((_req: AnyFormRequest, _h: FormResponseToolkit, fn) =>
|
|
234
|
+
Promise.resolve(fn(pageMock, contextMock))
|
|
247
235
|
)
|
|
248
236
|
|
|
249
237
|
const response = await makePostHandler()(requestMock, hMock)
|
|
@@ -263,7 +251,7 @@ describe('makePostHandler', () => {
|
|
|
263
251
|
(
|
|
264
252
|
_request: FormRequest,
|
|
265
253
|
_context: FormContext,
|
|
266
|
-
_h:
|
|
254
|
+
_h: FormResponseToolkit
|
|
267
255
|
) => {
|
|
268
256
|
return Promise.resolve({} as unknown as ResponseObject)
|
|
269
257
|
}
|
|
@@ -281,12 +269,8 @@ describe('makePostHandler', () => {
|
|
|
281
269
|
|
|
282
270
|
jest
|
|
283
271
|
.mocked(redirectOrMakeHandler)
|
|
284
|
-
.mockImplementation(
|
|
285
|
-
(
|
|
286
|
-
_req: FormRequest | FormRequestPayload,
|
|
287
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
288
|
-
fn
|
|
289
|
-
) => Promise.resolve(fn(pageMock, contextMock))
|
|
272
|
+
.mockImplementation((_req: AnyFormRequest, _h: FormResponseToolkit, fn) =>
|
|
273
|
+
Promise.resolve(fn(pageMock, contextMock))
|
|
290
274
|
)
|
|
291
275
|
|
|
292
276
|
await makePostHandler()(requestMock, hMock)
|
|
@@ -309,7 +293,7 @@ describe('makePostHandler', () => {
|
|
|
309
293
|
(
|
|
310
294
|
_request: FormRequest,
|
|
311
295
|
_context: FormContext,
|
|
312
|
-
_h:
|
|
296
|
+
_h: FormResponseToolkit
|
|
313
297
|
) => {
|
|
314
298
|
// do return a valid ResponseObject wrapped in Promise.resolve
|
|
315
299
|
return mockPostResponse
|
|
@@ -326,12 +310,8 @@ describe('makePostHandler', () => {
|
|
|
326
310
|
|
|
327
311
|
jest
|
|
328
312
|
.mocked(redirectOrMakeHandler)
|
|
329
|
-
.mockImplementation(
|
|
330
|
-
(
|
|
331
|
-
_req: FormRequest | FormRequestPayload,
|
|
332
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
333
|
-
fn
|
|
334
|
-
) => Promise.resolve(fn(pageMock, contextMock))
|
|
313
|
+
.mockImplementation((_req: AnyFormRequest, _h: FormResponseToolkit, fn) =>
|
|
314
|
+
Promise.resolve(fn(pageMock, contextMock))
|
|
335
315
|
)
|
|
336
316
|
|
|
337
317
|
await makePostHandler()(requestMock, hMock)
|
|
@@ -352,7 +332,7 @@ describe('makePostHandler', () => {
|
|
|
352
332
|
(
|
|
353
333
|
_request: FormRequest,
|
|
354
334
|
_context: FormContext,
|
|
355
|
-
_h:
|
|
335
|
+
_h: FormResponseToolkit
|
|
356
336
|
) => {
|
|
357
337
|
return Promise.resolve({} as unknown as ResponseObject)
|
|
358
338
|
}
|
|
@@ -369,11 +349,7 @@ describe('makePostHandler', () => {
|
|
|
369
349
|
jest
|
|
370
350
|
.mocked(redirectOrMakeHandler)
|
|
371
351
|
.mockImplementation(
|
|
372
|
-
async (
|
|
373
|
-
_req: FormRequest | FormRequestPayload,
|
|
374
|
-
_h: Pick<ResponseToolkit, 'redirect' | 'view'>,
|
|
375
|
-
fn
|
|
376
|
-
) => {
|
|
352
|
+
async (_req: AnyFormRequest, _h: FormResponseToolkit, fn) => {
|
|
377
353
|
try {
|
|
378
354
|
await fn(pageMock, contextMock)
|
|
379
355
|
} catch (err) {
|
|
@@ -395,7 +371,7 @@ function createMockPageController(
|
|
|
395
371
|
routeHandler: (
|
|
396
372
|
request: FormRequest,
|
|
397
373
|
context: FormContext,
|
|
398
|
-
h:
|
|
374
|
+
h: FormResponseToolkit
|
|
399
375
|
) => ResponseObject | Promise<ResponseObject>
|
|
400
376
|
): PageControllerClass {
|
|
401
377
|
return {
|
|
@@ -2,7 +2,6 @@ import { hasFormComponents, slugSchema, type Event } from '@defra/forms-model'
|
|
|
2
2
|
import Boom from '@hapi/boom'
|
|
3
3
|
import {
|
|
4
4
|
type ResponseObject,
|
|
5
|
-
type ResponseToolkit,
|
|
6
5
|
type RouteOptions,
|
|
7
6
|
type ServerRoute
|
|
8
7
|
} from '@hapi/hapi'
|
|
@@ -25,6 +24,7 @@ import {
|
|
|
25
24
|
redirectOrMakeHandler
|
|
26
25
|
} from '~/src/server/plugins/engine/routes/index.js'
|
|
27
26
|
import {
|
|
27
|
+
type AnyFormRequest,
|
|
28
28
|
type FormContext,
|
|
29
29
|
type PreparePageEventRequestOptions
|
|
30
30
|
} from '~/src/server/plugins/engine/types.js'
|
|
@@ -32,7 +32,8 @@ import {
|
|
|
32
32
|
type FormRequest,
|
|
33
33
|
type FormRequestPayload,
|
|
34
34
|
type FormRequestPayloadRefs,
|
|
35
|
-
type FormRequestRefs
|
|
35
|
+
type FormRequestRefs,
|
|
36
|
+
type FormResponseToolkit
|
|
36
37
|
} from '~/src/server/routes/types.js'
|
|
37
38
|
import {
|
|
38
39
|
actionSchema,
|
|
@@ -44,7 +45,7 @@ import {
|
|
|
44
45
|
import * as httpService from '~/src/server/services/httpService.js'
|
|
45
46
|
|
|
46
47
|
async function handleHttpEvent(
|
|
47
|
-
request:
|
|
48
|
+
request: AnyFormRequest,
|
|
48
49
|
page: PageControllerClass,
|
|
49
50
|
context: FormContext,
|
|
50
51
|
event: Event,
|
|
@@ -75,10 +76,7 @@ async function handleHttpEvent(
|
|
|
75
76
|
export function makeGetHandler(
|
|
76
77
|
preparePageEventRequestOptions?: PreparePageEventRequestOptions
|
|
77
78
|
) {
|
|
78
|
-
return function getHandler(
|
|
79
|
-
request: FormRequest,
|
|
80
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
81
|
-
) {
|
|
79
|
+
return function getHandler(request: FormRequest, h: FormResponseToolkit) {
|
|
82
80
|
const { params } = request
|
|
83
81
|
|
|
84
82
|
if (normalisePath(params.path) === '') {
|
|
@@ -116,7 +114,7 @@ export function makePostHandler(
|
|
|
116
114
|
) {
|
|
117
115
|
return function postHandler(
|
|
118
116
|
request: FormRequestPayload,
|
|
119
|
-
h:
|
|
117
|
+
h: FormResponseToolkit
|
|
120
118
|
) {
|
|
121
119
|
const { query } = request
|
|
122
120
|
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { slugSchema } from '@defra/forms-model'
|
|
2
2
|
import Boom from '@hapi/boom'
|
|
3
|
-
import {
|
|
4
|
-
type ResponseToolkit,
|
|
5
|
-
type RouteOptions,
|
|
6
|
-
type ServerRoute
|
|
7
|
-
} from '@hapi/hapi'
|
|
3
|
+
import { type RouteOptions, type ServerRoute } from '@hapi/hapi'
|
|
8
4
|
import Joi from 'joi'
|
|
9
5
|
|
|
10
6
|
import { FileUploadPageController } from '~/src/server/plugins/engine/pageControllers/FileUploadPageController.js'
|
|
@@ -14,7 +10,8 @@ import {
|
|
|
14
10
|
type FormRequest,
|
|
15
11
|
type FormRequestPayload,
|
|
16
12
|
type FormRequestPayloadRefs,
|
|
17
|
-
type FormRequestRefs
|
|
13
|
+
type FormRequestRefs,
|
|
14
|
+
type FormResponseToolkit
|
|
18
15
|
} from '~/src/server/routes/types.js'
|
|
19
16
|
import {
|
|
20
17
|
actionSchema,
|
|
@@ -26,10 +23,7 @@ import {
|
|
|
26
23
|
} from '~/src/server/schemas/index.js'
|
|
27
24
|
|
|
28
25
|
// Item delete GET route
|
|
29
|
-
function getHandler(
|
|
30
|
-
request: FormRequest,
|
|
31
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
32
|
-
) {
|
|
26
|
+
function getHandler(request: FormRequest, h: FormResponseToolkit) {
|
|
33
27
|
const { params } = request
|
|
34
28
|
|
|
35
29
|
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
@@ -46,10 +40,7 @@ function getHandler(
|
|
|
46
40
|
})
|
|
47
41
|
}
|
|
48
42
|
|
|
49
|
-
function postHandler(
|
|
50
|
-
request: FormRequestPayload,
|
|
51
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
52
|
-
) {
|
|
43
|
+
function postHandler(request: FormRequestPayload, h: FormResponseToolkit) {
|
|
53
44
|
const { params } = request
|
|
54
45
|
|
|
55
46
|
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
// List summary GET route
|
|
2
2
|
import { slugSchema } from '@defra/forms-model'
|
|
3
3
|
import Boom from '@hapi/boom'
|
|
4
|
-
import {
|
|
5
|
-
type ResponseToolkit,
|
|
6
|
-
type RouteOptions,
|
|
7
|
-
type ServerRoute
|
|
8
|
-
} from '@hapi/hapi'
|
|
4
|
+
import { type RouteOptions, type ServerRoute } from '@hapi/hapi'
|
|
9
5
|
import Joi from 'joi'
|
|
10
6
|
|
|
11
7
|
import { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js'
|
|
@@ -14,7 +10,8 @@ import {
|
|
|
14
10
|
type FormRequest,
|
|
15
11
|
type FormRequestPayload,
|
|
16
12
|
type FormRequestPayloadRefs,
|
|
17
|
-
type FormRequestRefs
|
|
13
|
+
type FormRequestRefs,
|
|
14
|
+
type FormResponseToolkit
|
|
18
15
|
} from '~/src/server/routes/types.js'
|
|
19
16
|
import {
|
|
20
17
|
actionSchema,
|
|
@@ -23,10 +20,7 @@ import {
|
|
|
23
20
|
stateSchema
|
|
24
21
|
} from '~/src/server/schemas/index.js'
|
|
25
22
|
|
|
26
|
-
function getHandler(
|
|
27
|
-
request: FormRequest,
|
|
28
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
29
|
-
) {
|
|
23
|
+
function getHandler(request: FormRequest, h: FormResponseToolkit) {
|
|
30
24
|
const { params } = request
|
|
31
25
|
|
|
32
26
|
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
@@ -38,10 +32,7 @@ function getHandler(
|
|
|
38
32
|
})
|
|
39
33
|
}
|
|
40
34
|
|
|
41
|
-
function postHandler(
|
|
42
|
-
request: FormRequestPayload,
|
|
43
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
44
|
-
) {
|
|
35
|
+
function postHandler(request: FormRequestPayload, h: FormResponseToolkit) {
|
|
45
36
|
const { params } = request
|
|
46
37
|
|
|
47
38
|
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type {
|
|
2
|
+
AnyFormRequest,
|
|
3
|
+
AnyRequest,
|
|
2
4
|
CheckAnswers,
|
|
3
5
|
ErrorMessageTemplate,
|
|
4
6
|
ErrorMessageTemplateList,
|
|
@@ -74,7 +76,8 @@ export type {
|
|
|
74
76
|
FormRequest,
|
|
75
77
|
FormRequestPayload,
|
|
76
78
|
FormRequestPayloadRefs,
|
|
77
|
-
FormRequestRefs
|
|
79
|
+
FormRequestRefs,
|
|
80
|
+
FormResponseToolkit
|
|
78
81
|
} from '~/src/server/routes/types.js'
|
|
79
82
|
|
|
80
83
|
export { FormAction, FormStatus } from '~/src/server/routes/types.js'
|
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
type List,
|
|
8
8
|
type Page
|
|
9
9
|
} from '@defra/forms-model'
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type PluginProperties,
|
|
12
|
+
type Request,
|
|
13
|
+
type ResponseObject
|
|
14
|
+
} from '@hapi/hapi'
|
|
11
15
|
import { type JoiExpression, type ValidationErrorItem } from 'joi'
|
|
12
16
|
|
|
13
17
|
import { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'
|
|
@@ -36,12 +40,15 @@ import {
|
|
|
36
40
|
type FormParams,
|
|
37
41
|
type FormRequest,
|
|
38
42
|
type FormRequestPayload,
|
|
43
|
+
type FormResponseToolkit,
|
|
39
44
|
type FormStatus
|
|
40
45
|
} from '~/src/server/routes/types.js'
|
|
46
|
+
import { type CacheService } from '~/src/server/services/cacheService.js'
|
|
41
47
|
import { type RequestOptions } from '~/src/server/services/httpService.js'
|
|
42
48
|
import { type Services } from '~/src/server/types.js'
|
|
43
49
|
|
|
44
|
-
type
|
|
50
|
+
export type AnyFormRequest = FormRequest | FormRequestPayload
|
|
51
|
+
export type AnyRequest = Request | AnyFormRequest
|
|
45
52
|
|
|
46
53
|
/**
|
|
47
54
|
* Form submission state stores the following in Redis:
|
|
@@ -312,7 +319,7 @@ export interface FormPageViewModel extends PageViewModelBase {
|
|
|
312
319
|
context: FormContext
|
|
313
320
|
errors?: FormSubmissionError[]
|
|
314
321
|
hasMissingNotificationEmail?: boolean
|
|
315
|
-
|
|
322
|
+
allowSaveAndExit: boolean
|
|
316
323
|
}
|
|
317
324
|
|
|
318
325
|
export interface RepeaterSummaryPageViewModel extends PageViewModelBase {
|
|
@@ -357,27 +364,26 @@ export type PreparePageEventRequestOptions = (
|
|
|
357
364
|
) => void
|
|
358
365
|
|
|
359
366
|
export type OnRequestCallback = (
|
|
360
|
-
request:
|
|
367
|
+
request: AnyFormRequest,
|
|
361
368
|
params: FormParams,
|
|
362
369
|
definition: FormDefinition,
|
|
363
370
|
metadata: FormMetadata
|
|
364
371
|
) => void
|
|
365
372
|
|
|
373
|
+
export type SaveAndExitHandler = (
|
|
374
|
+
request: FormRequestPayload,
|
|
375
|
+
h: FormResponseToolkit,
|
|
376
|
+
context: FormContext
|
|
377
|
+
) => ResponseObject
|
|
378
|
+
|
|
366
379
|
export interface PluginOptions {
|
|
367
380
|
model?: FormModel
|
|
368
381
|
services?: Services
|
|
369
382
|
controllers?: Record<string, typeof PageController>
|
|
370
|
-
|
|
383
|
+
cache?: CacheService | string
|
|
371
384
|
globals?: Record<string, GlobalFunction>
|
|
372
385
|
filters?: Record<string, FilterFunction>
|
|
373
|
-
|
|
374
|
-
keyGenerator: (request: RequestType) => string
|
|
375
|
-
sessionHydrator: (request: RequestType) => Promise<FormSubmissionState>
|
|
376
|
-
sessionPersister: (
|
|
377
|
-
state: FormSubmissionState,
|
|
378
|
-
request: RequestType
|
|
379
|
-
) => Promise<void>
|
|
380
|
-
}
|
|
386
|
+
saveAndExit?: SaveAndExitHandler
|
|
381
387
|
pluginPath?: string
|
|
382
388
|
nunjucks: {
|
|
383
389
|
baseLayoutPath: string
|