@defra/forms-engine-plugin 3.0.9 → 4.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.
Files changed (34) hide show
  1. package/.server/server/plugins/engine/plugin.js +3 -2
  2. package/.server/server/plugins/engine/plugin.js.map +1 -1
  3. package/.server/server/plugins/engine/routes/index.d.ts +2 -2
  4. package/.server/server/plugins/engine/routes/index.js +10 -8
  5. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  6. package/.server/server/plugins/engine/routes/questions.d.ts +4 -4
  7. package/.server/server/plugins/engine/routes/questions.js +10 -10
  8. package/.server/server/plugins/engine/routes/questions.js.map +1 -1
  9. package/.server/server/plugins/engine/routes/repeaters/item-delete.d.ts +2 -1
  10. package/.server/server/plugins/engine/routes/repeaters/item-delete.js +31 -27
  11. package/.server/server/plugins/engine/routes/repeaters/item-delete.js.map +1 -1
  12. package/.server/server/plugins/engine/routes/repeaters/summary.d.ts +2 -1
  13. package/.server/server/plugins/engine/routes/repeaters/summary.js +31 -27
  14. package/.server/server/plugins/engine/routes/repeaters/summary.js.map +1 -1
  15. package/.server/server/plugins/engine/types.d.ts +3 -3
  16. package/.server/server/plugins/engine/types.js.map +1 -1
  17. package/.server/server/routes/types.d.ts +1 -1
  18. package/.server/server/routes/types.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/server/plugins/engine/helpers.test.ts +2 -1
  21. package/src/server/plugins/engine/pageControllers/PageController.test.ts +2 -1
  22. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +8 -4
  23. package/src/server/plugins/engine/pageControllers/SummaryPageController.test.ts +2 -1
  24. package/src/server/plugins/engine/plugin.ts +10 -4
  25. package/src/server/plugins/engine/routes/index.test.ts +316 -0
  26. package/src/server/plugins/engine/routes/index.ts +11 -6
  27. package/src/server/plugins/engine/routes/questions.test.ts +126 -15
  28. package/src/server/plugins/engine/routes/questions.ts +71 -57
  29. package/src/server/plugins/engine/routes/repeaters/item-delete.test.ts +83 -0
  30. package/src/server/plugins/engine/routes/repeaters/item-delete.ts +39 -33
  31. package/src/server/plugins/engine/routes/repeaters/summary.test.ts +75 -0
  32. package/src/server/plugins/engine/routes/repeaters/summary.ts +28 -22
  33. package/src/server/plugins/engine/types.ts +6 -7
  34. package/src/server/routes/types.ts +4 -1
@@ -0,0 +1,75 @@
1
+ import { getRoutes } from '~/src/server/plugins/engine/routes/repeaters/summary.js'
2
+ import { type OnRequestCallback } from '~/src/server/plugins/engine/types.js'
3
+
4
+ describe('repeater summary routes', () => {
5
+ describe('route configuration', () => {
6
+ it('should return all expected routes', () => {
7
+ const routes = getRoutes({}, {}, undefined)
8
+
9
+ expect(routes).toHaveLength(4)
10
+
11
+ const expectedPaths = [
12
+ '/{slug}/{path}/summary',
13
+ '/preview/{state}/{slug}/{path}/summary'
14
+ ]
15
+
16
+ expectedPaths.forEach((path) => {
17
+ const getRoute = routes.find(
18
+ (route) => route.method === 'get' && route.path === path
19
+ )
20
+ const postRoute = routes.find(
21
+ (route) => route.method === 'post' && route.path === path
22
+ )
23
+
24
+ expect(getRoute).toBeDefined()
25
+ expect(postRoute).toBeDefined()
26
+ })
27
+ })
28
+
29
+ it('should pass onRequest callback to handlers', () => {
30
+ const onRequestCallback: OnRequestCallback = jest
31
+ .fn()
32
+ .mockResolvedValue(undefined)
33
+ const routes = getRoutes({}, {}, onRequestCallback)
34
+
35
+ // Test that the handlers are created with the onRequest callback
36
+ const getRoute = routes.find(
37
+ (route) =>
38
+ route.method === 'get' && route.path === '/{slug}/{path}/summary'
39
+ )
40
+ const postRoute = routes.find(
41
+ (route) =>
42
+ route.method === 'post' && route.path === '/{slug}/{path}/summary'
43
+ )
44
+
45
+ expect(getRoute?.handler).toBeDefined()
46
+ expect(postRoute?.handler).toBeDefined()
47
+ })
48
+ })
49
+
50
+ describe('handler functionality', () => {
51
+ it('should create handlers that accept onRequest callback', () => {
52
+ const onRequestCallback: OnRequestCallback = jest
53
+ .fn()
54
+ .mockResolvedValue(undefined)
55
+ const routes = getRoutes({}, {}, onRequestCallback)
56
+
57
+ // Test that the handlers are created with the onRequest callback
58
+ const getRoute = routes.find(
59
+ (route) =>
60
+ route.method === 'get' && route.path === '/{slug}/{path}/summary'
61
+ )
62
+ const postRoute = routes.find(
63
+ (route) =>
64
+ route.method === 'post' && route.path === '/{slug}/{path}/summary'
65
+ )
66
+
67
+ expect(getRoute?.handler).toBeDefined()
68
+ expect(postRoute?.handler).toBeDefined()
69
+
70
+ // Test that handlers are functions
71
+ expect(typeof getRoute?.handler).toBe('function')
72
+ expect(typeof postRoute?.handler).toBe('function')
73
+ })
74
+ })
75
+ })
@@ -6,6 +6,7 @@ import Joi from 'joi'
6
6
 
7
7
  import { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js'
8
8
  import { redirectOrMakeHandler } from '~/src/server/plugins/engine/routes/index.js'
9
+ import { type OnRequestCallback } from '~/src/server/plugins/engine/types.js'
9
10
  import {
10
11
  type FormRequest,
11
12
  type FormRequestPayload,
@@ -20,41 +21,46 @@ import {
20
21
  stateSchema
21
22
  } from '~/src/server/schemas/index.js'
22
23
 
23
- function getHandler(request: FormRequest, h: FormResponseToolkit) {
24
- const { params } = request
24
+ function getHandler(onRequest?: OnRequestCallback) {
25
+ return async function (request: FormRequest, h: FormResponseToolkit) {
26
+ const { params } = request
25
27
 
26
- return redirectOrMakeHandler(request, h, (page, context) => {
27
- if (!(page instanceof RepeatPageController)) {
28
- throw Boom.notFound(`No repeater page found for /${params.path}`)
29
- }
28
+ return redirectOrMakeHandler(request, h, onRequest, (page, context) => {
29
+ if (!(page instanceof RepeatPageController)) {
30
+ throw Boom.notFound(`No repeater page found for /${params.path}`)
31
+ }
30
32
 
31
- return page.makeGetListSummaryRouteHandler()(request, context, h)
32
- })
33
+ return page.makeGetListSummaryRouteHandler()(request, context, h)
34
+ })
35
+ }
33
36
  }
34
37
 
35
- function postHandler(request: FormRequestPayload, h: FormResponseToolkit) {
36
- const { params } = request
38
+ function postHandler(onRequest?: OnRequestCallback) {
39
+ return async function (request: FormRequestPayload, h: FormResponseToolkit) {
40
+ const { params } = request
37
41
 
38
- return redirectOrMakeHandler(request, h, (page, context) => {
39
- const { isForceAccess } = context
42
+ return redirectOrMakeHandler(request, h, onRequest, (page, context) => {
43
+ const { isForceAccess } = context
40
44
 
41
- if (isForceAccess || !(page instanceof RepeatPageController)) {
42
- throw Boom.notFound(`No repeater page found for /${params.path}`)
43
- }
45
+ if (isForceAccess || !(page instanceof RepeatPageController)) {
46
+ throw Boom.notFound(`No repeater page found for /${params.path}`)
47
+ }
44
48
 
45
- return page.makePostListSummaryRouteHandler()(request, context, h)
46
- })
49
+ return page.makePostListSummaryRouteHandler()(request, context, h)
50
+ })
51
+ }
47
52
  }
48
53
 
49
54
  export function getRoutes(
50
55
  getRouteOptions: RouteOptions<FormRequestRefs>,
51
- postRouteOptions: RouteOptions<FormRequestPayloadRefs>
56
+ postRouteOptions: RouteOptions<FormRequestPayloadRefs>,
57
+ onRequest?: OnRequestCallback
52
58
  ): (ServerRoute<FormRequestRefs> | ServerRoute<FormRequestPayloadRefs>)[] {
53
59
  return [
54
60
  {
55
61
  method: 'get',
56
62
  path: '/{slug}/{path}/summary',
57
- handler: getHandler,
63
+ handler: getHandler(onRequest),
58
64
  options: {
59
65
  ...getRouteOptions,
60
66
  validate: {
@@ -69,7 +75,7 @@ export function getRoutes(
69
75
  {
70
76
  method: 'get',
71
77
  path: '/preview/{state}/{slug}/{path}/summary',
72
- handler: getHandler,
78
+ handler: getHandler(onRequest),
73
79
  options: {
74
80
  ...getRouteOptions,
75
81
  validate: {
@@ -85,7 +91,7 @@ export function getRoutes(
85
91
  {
86
92
  method: 'post',
87
93
  path: '/{slug}/{path}/summary',
88
- handler: postHandler,
94
+ handler: postHandler(onRequest),
89
95
  options: {
90
96
  ...postRouteOptions,
91
97
  validate: {
@@ -106,7 +112,7 @@ export function getRoutes(
106
112
  {
107
113
  method: 'post',
108
114
  path: '/preview/{state}/{slug}/{path}/summary',
109
- handler: postHandler,
115
+ handler: postHandler(onRequest),
110
116
  options: {
111
117
  ...postRouteOptions,
112
118
  validate: {
@@ -1,8 +1,6 @@
1
1
  import {
2
2
  type ComponentDef,
3
3
  type Event,
4
- type FormDefinition,
5
- type FormMetadata,
6
4
  type FormVersionMetadata,
7
5
  type Item,
8
6
  type List,
@@ -38,7 +36,6 @@ import {
38
36
  import { type ViewContext } from '~/src/server/plugins/nunjucks/types.js'
39
37
  import {
40
38
  type FormAction,
41
- type FormParams,
42
39
  type FormRequest,
43
40
  type FormRequestPayload,
44
41
  type FormResponseToolkit,
@@ -368,10 +365,12 @@ export type PreparePageEventRequestOptions = (
368
365
 
369
366
  export type OnRequestCallback = (
370
367
  request: AnyFormRequest,
371
- params: FormParams,
372
- definition: FormDefinition,
373
- metadata: FormMetadata
374
- ) => void
368
+ h: FormResponseToolkit,
369
+ context: FormContext
370
+ ) =>
371
+ | ResponseObject
372
+ | FormResponseToolkit['continue']
373
+ | Promise<ResponseObject | FormResponseToolkit['continue']>
375
374
 
376
375
  export type SaveAndExitHandler = (
377
376
  request: FormRequestPayload,
@@ -37,7 +37,10 @@ export interface FormRequestPayloadRefs extends FormRequestRefs {
37
37
 
38
38
  export type FormRequest = Request<FormRequestRefs>
39
39
  export type FormRequestPayload = Request<FormRequestPayloadRefs>
40
- export type FormResponseToolkit = Pick<ResponseToolkit, 'redirect' | 'view'>
40
+ export type FormResponseToolkit = Pick<
41
+ ResponseToolkit,
42
+ 'redirect' | 'view' | 'continue'
43
+ >
41
44
 
42
45
  export enum FormAction {
43
46
  Continue = 'continue',