@defra/forms-engine-plugin 4.0.7 → 4.0.9

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 (47) hide show
  1. package/.server/server/forms/components.json +7 -0
  2. package/.server/server/forms/page-events.yaml +1 -1
  3. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +12 -1
  4. package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -1
  5. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  6. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  7. package/.server/server/plugins/engine/components/DeclarationField.d.ts +81 -0
  8. package/.server/server/plugins/engine/components/DeclarationField.js +123 -0
  9. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -0
  10. package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
  11. package/.server/server/plugins/engine/components/helpers/components.js +3 -0
  12. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  13. package/.server/server/plugins/engine/components/index.d.ts +1 -0
  14. package/.server/server/plugins/engine/components/index.js +1 -0
  15. package/.server/server/plugins/engine/components/index.js.map +1 -1
  16. package/.server/server/plugins/engine/models/SummaryViewModel.js +4 -0
  17. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  18. package/.server/server/plugins/engine/pageControllers/validationOptions.js +1 -0
  19. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  20. package/.server/server/plugins/engine/views/components/declarationfield.html +14 -0
  21. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  22. package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
  23. package/.server/server/plugins/nunjucks/filters/index.js +1 -0
  24. package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
  25. package/.server/server/plugins/nunjucks/filters/merge.d.ts +7 -0
  26. package/.server/server/plugins/nunjucks/filters/merge.js +16 -0
  27. package/.server/server/plugins/nunjucks/filters/merge.js.map +1 -0
  28. package/.server/server/plugins/nunjucks/filters/merge.test.js +19 -0
  29. package/.server/server/plugins/nunjucks/filters/merge.test.js.map +1 -0
  30. package/package.json +2 -2
  31. package/src/server/forms/components.json +7 -0
  32. package/src/server/forms/page-events.yaml +1 -1
  33. package/src/server/forms/register-as-a-unicorn-breeder.yaml +12 -1
  34. package/src/server/index.test.ts +1 -0
  35. package/src/server/plugins/engine/components/ComponentBase.ts +1 -0
  36. package/src/server/plugins/engine/components/ComponentCollection.ts +1 -0
  37. package/src/server/plugins/engine/components/DeclarationField.test.ts +426 -0
  38. package/src/server/plugins/engine/components/DeclarationField.ts +167 -0
  39. package/src/server/plugins/engine/components/helpers/components.ts +5 -0
  40. package/src/server/plugins/engine/components/index.ts +1 -0
  41. package/src/server/plugins/engine/models/SummaryViewModel.test.ts +76 -3
  42. package/src/server/plugins/engine/models/SummaryViewModel.ts +5 -1
  43. package/src/server/plugins/engine/pageControllers/validationOptions.ts +4 -0
  44. package/src/server/plugins/engine/views/components/declarationfield.html +14 -0
  45. package/src/server/plugins/nunjucks/filters/index.js +1 -0
  46. package/src/server/plugins/nunjucks/filters/merge.js +16 -0
  47. package/src/server/plugins/nunjucks/filters/merge.test.js +15 -0
@@ -15,6 +15,7 @@ import {
15
15
  type FormContextRequest,
16
16
  type FormState
17
17
  } from '~/src/server/plugins/engine/types.js'
18
+ import v2Definition from '~/test/form/definitions/conditions-relative-dates-v2.js'
18
19
  import definition from '~/test/form/definitions/repeat-mixed.js'
19
20
  const basePath = `${FORM_PREFIX}/test`
20
21
 
@@ -326,7 +327,7 @@ describe('SummaryPageController', () => {
326
327
  expect(viewModel).toHaveProperty('allowSaveAndExit', true)
327
328
  })
328
329
 
329
- it('should display correct page title', () => {
330
+ it('should display correct page title for v1 form', () => {
330
331
  const state: FormState = {
331
332
  $$__referenceNumber: 'foobar',
332
333
  orderType: 'collection',
@@ -334,9 +335,81 @@ describe('SummaryPageController', () => {
334
335
  }
335
336
 
336
337
  const context = model.getFormContext(request, state)
337
- const viewModel = controller.getViewModel(request, context)
338
+ const viewModel = controller.getSummaryViewModel(request, context)
339
+
340
+ expect(viewModel.pageTitle).toBe(
341
+ 'Check your answers before sending your form'
342
+ )
343
+ })
344
+
345
+ it('should display default page title for v2 form when title not supplied', () => {
346
+ const state: FormState = {
347
+ $$__referenceNumber: 'foobar',
348
+ orderType: 'collection',
349
+ pizza: []
350
+ }
351
+
352
+ const titleModel = new FormModel(v2Definition, {
353
+ basePath: `${FORM_PREFIX}/test`
354
+ })
355
+
356
+ controller = new SummaryPageController(titleModel, v2Definition.pages[5])
357
+
358
+ request = {
359
+ method: 'get',
360
+ url: new URL('http://example.com/repeat/pizza-order/summary'),
361
+ path: '/test/summary',
362
+ params: {
363
+ path: 'summary',
364
+ slug: 'test'
365
+ },
366
+ query: {},
367
+ app: { model: titleModel },
368
+ server: serverWithSaveAndExit
369
+ }
370
+
371
+ const context = titleModel.getFormContext(request, state)
372
+ const viewModel = controller.getSummaryViewModel(request, context)
373
+
374
+ expect(viewModel.pageTitle).toBe(
375
+ 'Check your answers before sending your form'
376
+ )
377
+ })
378
+
379
+ it('should display override page title for v2 form when title supplied', () => {
380
+ const state: FormState = {
381
+ $$__referenceNumber: 'foobar',
382
+ orderType: 'collection',
383
+ pizza: []
384
+ }
385
+
386
+ const v2DefinitionWithSummaryTitle = structuredClone(v2Definition)
387
+ const summaryPage = v2DefinitionWithSummaryTitle.pages[5]
388
+ summaryPage.title = 'Override summary title'
389
+
390
+ const titleModel = new FormModel(v2DefinitionWithSummaryTitle, {
391
+ basePath: `${FORM_PREFIX}/test`
392
+ })
393
+
394
+ controller = new SummaryPageController(titleModel, summaryPage)
395
+
396
+ request = {
397
+ method: 'get',
398
+ url: new URL('http://example.com/repeat/pizza-order/summary'),
399
+ path: '/test/summary',
400
+ params: {
401
+ path: 'summary',
402
+ slug: 'test'
403
+ },
404
+ query: {},
405
+ app: { model: titleModel },
406
+ server: serverWithSaveAndExit
407
+ }
408
+
409
+ const context = titleModel.getFormContext(request, state)
410
+ const viewModel = controller.getSummaryViewModel(request, context)
338
411
 
339
- expect(viewModel.pageTitle).toBe('Check your answers')
412
+ expect(viewModel.pageTitle).toBe('Override summary title')
340
413
  })
341
414
  })
342
415
  })
@@ -1,4 +1,4 @@
1
- import { type Section } from '@defra/forms-model'
1
+ import { SchemaVersion, type Section } from '@defra/forms-model'
2
2
 
3
3
  import {
4
4
  getAnswer,
@@ -64,6 +64,10 @@ export class SummaryViewModel {
64
64
 
65
65
  this.page = page
66
66
  this.pageTitle = page.title
67
+ if (def.schema === SchemaVersion.V2 && !page.title) {
68
+ this.pageTitle = 'Check your answers before sending your form'
69
+ }
70
+
67
71
  this.serviceUrl = `/${basePath}`
68
72
  this.name = def.name
69
73
  this.declaration = def.declaration
@@ -20,6 +20,10 @@ const opts = {
20
20
  * see @link https://joi.dev/api/?v=17.4.2#template-syntax for template syntax
21
21
  */
22
22
  export const messageTemplate: Record<string, JoiExpression> = {
23
+ declarationRequired: joi.expression(
24
+ 'You must confirm you understand and agree with the {{lowerFirst(#label)}} to continue',
25
+ opts
26
+ ) as JoiExpression,
23
27
  required: joi.expression(
24
28
  'Enter {{lowerFirst(#label)}}',
25
29
  opts
@@ -0,0 +1,14 @@
1
+ {% from "govuk/components/fieldset/macro.njk" import govukFieldset %}
2
+ {% from "govuk/components/checkboxes/macro.njk" import govukCheckboxes %}
3
+ {% from "govuk/components/hint/macro.njk" import govukHint %}
4
+
5
+ {% macro DeclarationField(component) %}
6
+ {% set content %}
7
+ <div class="app-prose-scope">
8
+ {{ component.model.content | markdown | safe }}
9
+ </div>
10
+ {% endset %}
11
+ {% set checkboxes = component.model | merge({ formGroup: { beforeInputs: { html: content } } }) %}
12
+ {{ govukCheckboxes(checkboxes) }}
13
+ <input type="hidden" name="{{ component.model.name }}" value="unchecked">
14
+ {% endmacro %}
@@ -5,3 +5,4 @@ export { answer } from '~/src/server/plugins/nunjucks/filters/answer.js'
5
5
  export { href } from '~/src/server/plugins/nunjucks/filters/href.js'
6
6
  export { field } from '~/src/server/plugins/nunjucks/filters/field.js'
7
7
  export { page } from '~/src/server/plugins/nunjucks/filters/page.js'
8
+ export { merge } from '~/src/server/plugins/nunjucks/filters/merge.js'
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Nunjucks filter to get the page for a given path
3
+ * @param {Record<string, any>} targetDictionary - Object to extend
4
+ * @param {Record<string, any> | string} sourceDictionary - Object to merge into target
5
+ * @returns {Record<string, any>}
6
+ */
7
+ export function merge(targetDictionary, sourceDictionary) {
8
+ if (typeof sourceDictionary !== 'object') {
9
+ return targetDictionary
10
+ }
11
+
12
+ return {
13
+ ...targetDictionary,
14
+ ...sourceDictionary
15
+ }
16
+ }
@@ -0,0 +1,15 @@
1
+ import { merge } from '~/src/server/plugins/nunjucks/filters/merge.js'
2
+
3
+ describe('merge', () => {
4
+ const propertyToMerge = { lorem: 'ipsum' }
5
+ it('should return the target if source is not an object', () => {
6
+ expect(merge(propertyToMerge, 'dolar')).toBe(propertyToMerge)
7
+ })
8
+
9
+ it('should merge the properties if they are valid', () => {
10
+ expect(merge({ lorem: 'dolar', dolar: 'sit' }, propertyToMerge)).toEqual({
11
+ lorem: 'ipsum',
12
+ dolar: 'sit'
13
+ })
14
+ })
15
+ })