@defra/forms-engine-plugin 2.1.10 → 3.0.1
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.d.ts +2 -0
- package/.server/server/plugins/engine/models/FormModel.js +5 -2
- 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/outputFormatters/adapter/v1.d.ts +4 -0
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +25 -0
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js +7 -6
- package/.server/server/plugins/engine/outputFormatters/machine/v2.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 +3 -1
- 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/schema.js +3 -2
- package/.server/server/plugins/engine/types/schema.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +13 -12
- 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 +4 -2
- 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 +66 -2
- package/src/server/plugins/engine/models/FormModel.ts +6 -4
- 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/outputFormatters/adapter/v1.test.ts +446 -13
- package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +37 -0
- package/src/server/plugins/engine/outputFormatters/machine/v2.ts +8 -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 +9 -12
- 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/schema.test.ts +40 -0
- package/src/server/plugins/engine/types/schema.ts +3 -1
- package/src/server/plugins/engine/types.ts +22 -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
|
@@ -2,7 +2,6 @@ import { randomUUID } from 'crypto'
|
|
|
2
2
|
|
|
3
3
|
import { type PageRepeat, type Repeat } from '@defra/forms-model'
|
|
4
4
|
import Boom from '@hapi/boom'
|
|
5
|
-
import { type ResponseToolkit } from '@hapi/hapi'
|
|
6
5
|
import Joi from 'joi'
|
|
7
6
|
|
|
8
7
|
import { isRepeatState } from '~/src/server/plugins/engine/components/FormComponent.js'
|
|
@@ -25,7 +24,8 @@ import {
|
|
|
25
24
|
import {
|
|
26
25
|
FormAction,
|
|
27
26
|
type FormRequest,
|
|
28
|
-
type FormRequestPayload
|
|
27
|
+
type FormRequestPayload,
|
|
28
|
+
type FormResponseToolkit
|
|
29
29
|
} from '~/src/server/routes/types.js'
|
|
30
30
|
|
|
31
31
|
export class RepeatPageController extends QuestionPageController {
|
|
@@ -128,10 +128,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
proceed(
|
|
132
|
-
request: FormContextRequest,
|
|
133
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
134
|
-
) {
|
|
131
|
+
proceed(request: FormContextRequest, h: FormResponseToolkit) {
|
|
135
132
|
const nextPath = this.getSummaryPath(request)
|
|
136
133
|
return super.proceed(request, h, nextPath)
|
|
137
134
|
}
|
|
@@ -151,7 +148,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
151
148
|
return async (
|
|
152
149
|
request: FormRequest,
|
|
153
150
|
context: FormContext,
|
|
154
|
-
h:
|
|
151
|
+
h: FormResponseToolkit
|
|
155
152
|
) => {
|
|
156
153
|
const { path } = this
|
|
157
154
|
const { query } = request
|
|
@@ -179,7 +176,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
179
176
|
return (
|
|
180
177
|
request: FormRequest,
|
|
181
178
|
context: FormContext,
|
|
182
|
-
h:
|
|
179
|
+
h: FormResponseToolkit
|
|
183
180
|
) => {
|
|
184
181
|
const { path } = this
|
|
185
182
|
const { query } = request
|
|
@@ -205,7 +202,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
205
202
|
return (
|
|
206
203
|
request: FormRequestPayload,
|
|
207
204
|
context: FormContext,
|
|
208
|
-
h:
|
|
205
|
+
h: FormResponseToolkit
|
|
209
206
|
) => {
|
|
210
207
|
const { path, repeat } = this
|
|
211
208
|
const { query } = request
|
|
@@ -269,7 +266,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
269
266
|
return (
|
|
270
267
|
request: FormRequest,
|
|
271
268
|
context: FormContext,
|
|
272
|
-
h:
|
|
269
|
+
h: FormResponseToolkit
|
|
273
270
|
) => {
|
|
274
271
|
const { viewModel } = this
|
|
275
272
|
const { state } = context
|
|
@@ -304,7 +301,7 @@ export class RepeatPageController extends QuestionPageController {
|
|
|
304
301
|
return async (
|
|
305
302
|
request: FormRequestPayload,
|
|
306
303
|
context: FormContext,
|
|
307
|
-
h:
|
|
304
|
+
h: FormResponseToolkit
|
|
308
305
|
) => {
|
|
309
306
|
const { repeat } = this
|
|
310
307
|
const { state } = context
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
|
|
2
2
|
import { StartPageController } from '~/src/server/plugins/engine/pageControllers/StartPageController.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('StartPageController', () => {
|
|
@@ -22,9 +22,9 @@ describe('StartPageController', () => {
|
|
|
22
22
|
controller = new StartPageController(model, mockPage as any)
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
describe('
|
|
26
|
-
it('should return false (StartPageController does not allow save and
|
|
27
|
-
expect(controller.
|
|
25
|
+
describe('shouldShowSaveAndExit', () => {
|
|
26
|
+
it('should return false (StartPageController does not allow save and exit)', () => {
|
|
27
|
+
expect(controller.shouldShowSaveAndExit(serverWithSaveAndExit)).toBe(
|
|
28
28
|
false
|
|
29
29
|
)
|
|
30
30
|
})
|
|
@@ -9,7 +9,7 @@ export class StartPageController extends QuestionPageController {
|
|
|
9
9
|
* but start pages should really live on gov.uk (whitehall publisher) so a user can be properly signposted.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
allowSaveAndExit = false
|
|
13
13
|
|
|
14
14
|
getViewModel(request: FormRequest, context: FormContext) {
|
|
15
15
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
|
|
2
2
|
import { StatusPageController } from '~/src/server/plugins/engine/pageControllers/StatusPageController.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('StatusPageController', () => {
|
|
@@ -22,9 +22,9 @@ describe('StatusPageController', () => {
|
|
|
22
22
|
controller = new StatusPageController(model, mockPage as any)
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
describe('
|
|
26
|
-
it('should return false (StatusPageController does not allow save and
|
|
27
|
-
expect(controller.
|
|
25
|
+
describe('shouldShowSaveAndExit', () => {
|
|
26
|
+
it('should return false (StatusPageController does not allow save and exit)', () => {
|
|
27
|
+
expect(controller.shouldShowSaveAndExit(serverWithSaveAndExit)).toBe(
|
|
28
28
|
false
|
|
29
29
|
)
|
|
30
30
|
})
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { type PageStatus } from '@defra/forms-model'
|
|
2
|
-
import { type ResponseToolkit } from '@hapi/hapi'
|
|
3
2
|
|
|
4
3
|
import { getCacheService } from '~/src/server/plugins/engine/helpers.js'
|
|
5
4
|
import { type FormModel } from '~/src/server/plugins/engine/models/index.js'
|
|
6
5
|
import { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'
|
|
7
6
|
import { type FormContext } from '~/src/server/plugins/engine/types.js'
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type FormRequest,
|
|
9
|
+
type FormResponseToolkit
|
|
10
|
+
} from '~/src/server/routes/types.js'
|
|
9
11
|
|
|
10
12
|
export class StatusPageController extends QuestionPageController {
|
|
11
13
|
declare pageDef: PageStatus
|
|
12
|
-
|
|
14
|
+
allowSaveAndExit = false
|
|
13
15
|
|
|
14
16
|
constructor(model: FormModel, pageDef: PageStatus) {
|
|
15
17
|
super(model, pageDef)
|
|
@@ -24,7 +26,7 @@ export class StatusPageController extends QuestionPageController {
|
|
|
24
26
|
return async (
|
|
25
27
|
request: FormRequest,
|
|
26
28
|
context: FormContext,
|
|
27
|
-
h:
|
|
29
|
+
h: FormResponseToolkit
|
|
28
30
|
) => {
|
|
29
31
|
const { viewModel, viewName } = this
|
|
30
32
|
|
|
@@ -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
|
|
|
@@ -153,10 +151,12 @@ export function makeLoadFormPreHandler(server: Server, options: PluginOptions) {
|
|
|
153
151
|
: `${prefix}/${slug}`
|
|
154
152
|
).substring(1)
|
|
155
153
|
|
|
154
|
+
const versionNumber = metadata.versions?.[0]?.versionNumber
|
|
155
|
+
|
|
156
156
|
// Construct the form model
|
|
157
157
|
const model = new FormModel(
|
|
158
158
|
definition,
|
|
159
|
-
{ basePath },
|
|
159
|
+
{ basePath, versionNumber },
|
|
160
160
|
services,
|
|
161
161
|
controllers
|
|
162
162
|
)
|
|
@@ -181,10 +181,7 @@ export function makeLoadFormPreHandler(server: Server, options: PluginOptions) {
|
|
|
181
181
|
return handler
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
export function dispatchHandler(
|
|
185
|
-
request: FormRequest,
|
|
186
|
-
h: Pick<ResponseToolkit, 'redirect' | 'view'>
|
|
187
|
-
) {
|
|
184
|
+
export function dispatchHandler(request: FormRequest, h: FormResponseToolkit) {
|
|
188
185
|
const { model } = request.app
|
|
189
186
|
|
|
190
187
|
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
|
|