@defra/forms-engine-plugin 0.0.2 → 0.0.4

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 (330) hide show
  1. package/.public/assets/fonts/bold-affa96571d-v2.woff +0 -0
  2. package/.public/assets/fonts/bold-b542beb274-v2.woff2 +0 -0
  3. package/.public/assets/fonts/light-94a07e06a1-v2.woff2 +0 -0
  4. package/.public/assets/fonts/light-f591b13f7d-v2.woff +0 -0
  5. package/.public/assets/images/favicon.ico +0 -0
  6. package/.public/assets/images/favicon.svg +1 -0
  7. package/.public/assets/images/govuk-crest.svg +1 -0
  8. package/.public/assets/images/govuk-icon-180.png +0 -0
  9. package/.public/assets/images/govuk-icon-192.png +0 -0
  10. package/.public/assets/images/govuk-icon-512.png +0 -0
  11. package/.public/assets/images/govuk-icon-mask.svg +1 -0
  12. package/.public/assets/images/govuk-opengraph-image.png +0 -0
  13. package/.public/assets/manifest.json +39 -0
  14. package/.public/assets-manifest.json +24 -0
  15. package/.public/javascripts/application.0fd8c18.min.js +3 -0
  16. package/.public/javascripts/application.0fd8c18.min.js.LICENSE.txt +58 -0
  17. package/.public/javascripts/application.0fd8c18.min.js.map +1 -0
  18. package/.public/javascripts/file-upload.b2f18f5.min.js +2 -0
  19. package/.public/javascripts/file-upload.b2f18f5.min.js.map +1 -0
  20. package/.public/javascripts/vendor/accessible-autocomplete.275d332.min.js +2 -0
  21. package/.public/javascripts/vendor/accessible-autocomplete.275d332.min.js.map +1 -0
  22. package/.public/stylesheets/application.e340021.min.css +14 -0
  23. package/.public/stylesheets/application.e340021.min.css.map +1 -0
  24. package/.server/server/plugins/nunjucks/environment.js +3 -3
  25. package/.server/server/plugins/nunjucks/environment.js.map +1 -1
  26. package/package.json +6 -2
  27. package/.browserslistrc +0 -16
  28. package/.editorconfig +0 -9
  29. package/.eslintrc.cjs +0 -266
  30. package/.github/dependabot.yml +0 -85
  31. package/.github/workflows/check-pull-request.yml +0 -209
  32. package/.github/workflows/pr-notifier.yml +0 -98
  33. package/.github/workflows/publish.yml +0 -111
  34. package/.husky/pre-commit +0 -1
  35. package/.lintstagedrc.js +0 -4
  36. package/.nvmrc +0 -1
  37. package/.prettierignore +0 -8
  38. package/.prettierrc.cjs +0 -26
  39. package/Dockerfile +0 -61
  40. package/Procfile +0 -1
  41. package/babel.config.cjs +0 -55
  42. package/compose/aws.env +0 -4
  43. package/compose/start-localstack.sh +0 -26
  44. package/docker-compose.yaml +0 -86
  45. package/globals.d.ts +0 -1
  46. package/jest.config.cjs +0 -54
  47. package/jest.environment.js +0 -4
  48. package/jest.setup.cjs +0 -14
  49. package/postcss.config.js +0 -26
  50. package/sonar-project.properties +0 -17
  51. package/src/client/javascripts/application.js +0 -87
  52. package/src/client/javascripts/file-upload.js +0 -386
  53. package/src/client/stylesheets/_code.scss +0 -33
  54. package/src/client/stylesheets/_govuk-frontend.scss +0 -4
  55. package/src/client/stylesheets/_prose.scss +0 -56
  56. package/src/client/stylesheets/_service-banner.scss +0 -24
  57. package/src/client/stylesheets/_summary-list.scss +0 -28
  58. package/src/client/stylesheets/_tag-env.scss +0 -24
  59. package/src/client/stylesheets/application.scss +0 -14
  60. package/src/common/cookies.js +0 -58
  61. package/src/common/cookies.test.js +0 -23
  62. package/src/common/types.js +0 -5
  63. package/src/config/index.ts +0 -271
  64. package/src/index.ts +0 -31
  65. package/src/server/common/helpers/logging/logger-options.test.ts +0 -50
  66. package/src/server/common/helpers/logging/logger-options.ts +0 -46
  67. package/src/server/common/helpers/logging/logger.ts +0 -7
  68. package/src/server/common/helpers/logging/request-logger.ts +0 -9
  69. package/src/server/common/helpers/logging/request-tracing.js +0 -10
  70. package/src/server/common/helpers/redis-client.js +0 -70
  71. package/src/server/constants.js +0 -1
  72. package/src/server/forms/README.md +0 -10
  73. package/src/server/forms/components.json +0 -1015
  74. package/src/server/forms/report-a-terrorist.json +0 -270
  75. package/src/server/forms/runner-components-test.json +0 -365
  76. package/src/server/forms/test.json +0 -581
  77. package/src/server/index.test.ts +0 -582
  78. package/src/server/index.ts +0 -140
  79. package/src/server/plugins/blankie.test.ts +0 -73
  80. package/src/server/plugins/blankie.ts +0 -48
  81. package/src/server/plugins/crumb.ts +0 -20
  82. package/src/server/plugins/engine/README.md +0 -87
  83. package/src/server/plugins/engine/components/AutocompleteField.test.ts +0 -294
  84. package/src/server/plugins/engine/components/AutocompleteField.ts +0 -49
  85. package/src/server/plugins/engine/components/CheckboxesField.test.ts +0 -379
  86. package/src/server/plugins/engine/components/CheckboxesField.ts +0 -106
  87. package/src/server/plugins/engine/components/ComponentBase.ts +0 -97
  88. package/src/server/plugins/engine/components/ComponentCollection.ts +0 -278
  89. package/src/server/plugins/engine/components/DatePartsField.test.ts +0 -822
  90. package/src/server/plugins/engine/components/DatePartsField.ts +0 -264
  91. package/src/server/plugins/engine/components/Details.test.ts +0 -49
  92. package/src/server/plugins/engine/components/Details.ts +0 -30
  93. package/src/server/plugins/engine/components/EmailAddressField.test.ts +0 -395
  94. package/src/server/plugins/engine/components/EmailAddressField.ts +0 -55
  95. package/src/server/plugins/engine/components/FileUploadField.test.ts +0 -778
  96. package/src/server/plugins/engine/components/FileUploadField.ts +0 -262
  97. package/src/server/plugins/engine/components/FormComponent.ts +0 -249
  98. package/src/server/plugins/engine/components/Html.test.ts +0 -48
  99. package/src/server/plugins/engine/components/Html.ts +0 -29
  100. package/src/server/plugins/engine/components/InsetText.test.ts +0 -48
  101. package/src/server/plugins/engine/components/InsetText.ts +0 -27
  102. package/src/server/plugins/engine/components/List.test.ts +0 -76
  103. package/src/server/plugins/engine/components/List.ts +0 -72
  104. package/src/server/plugins/engine/components/ListFormComponent.ts +0 -140
  105. package/src/server/plugins/engine/components/MonthYearField.test.ts +0 -567
  106. package/src/server/plugins/engine/components/MonthYearField.ts +0 -222
  107. package/src/server/plugins/engine/components/MultilineTextField.test.ts +0 -558
  108. package/src/server/plugins/engine/components/MultilineTextField.ts +0 -138
  109. package/src/server/plugins/engine/components/NumberField.test.ts +0 -701
  110. package/src/server/plugins/engine/components/NumberField.ts +0 -163
  111. package/src/server/plugins/engine/components/RadiosField.test.ts +0 -288
  112. package/src/server/plugins/engine/components/RadiosField.ts +0 -24
  113. package/src/server/plugins/engine/components/SelectField.test.ts +0 -288
  114. package/src/server/plugins/engine/components/SelectField.ts +0 -47
  115. package/src/server/plugins/engine/components/SelectionControlField.ts +0 -43
  116. package/src/server/plugins/engine/components/TelephoneNumberField.test.ts +0 -356
  117. package/src/server/plugins/engine/components/TelephoneNumberField.ts +0 -67
  118. package/src/server/plugins/engine/components/TextField.test.ts +0 -489
  119. package/src/server/plugins/engine/components/TextField.ts +0 -96
  120. package/src/server/plugins/engine/components/UkAddressField.test.ts +0 -623
  121. package/src/server/plugins/engine/components/UkAddressField.ts +0 -172
  122. package/src/server/plugins/engine/components/YesNoField.test.ts +0 -248
  123. package/src/server/plugins/engine/components/YesNoField.ts +0 -31
  124. package/src/server/plugins/engine/components/constants.ts +0 -1
  125. package/src/server/plugins/engine/components/helpers.ts +0 -330
  126. package/src/server/plugins/engine/components/index.ts +0 -24
  127. package/src/server/plugins/engine/components/types.ts +0 -117
  128. package/src/server/plugins/engine/configureEnginePlugin.ts +0 -47
  129. package/src/server/plugins/engine/helpers.test.ts +0 -791
  130. package/src/server/plugins/engine/helpers.ts +0 -379
  131. package/src/server/plugins/engine/index.ts +0 -7
  132. package/src/server/plugins/engine/models/FormModel.test.ts +0 -42
  133. package/src/server/plugins/engine/models/FormModel.ts +0 -443
  134. package/src/server/plugins/engine/models/RepeatingSummaryViewModel.ts +0 -0
  135. package/src/server/plugins/engine/models/Section.ts +0 -0
  136. package/src/server/plugins/engine/models/SummaryViewModel.test.ts +0 -209
  137. package/src/server/plugins/engine/models/SummaryViewModel.ts +0 -220
  138. package/src/server/plugins/engine/models/index.ts +0 -2
  139. package/src/server/plugins/engine/models/types.ts +0 -114
  140. package/src/server/plugins/engine/outputFormatters/human/v1.test.ts +0 -143
  141. package/src/server/plugins/engine/outputFormatters/human/v1.ts +0 -73
  142. package/src/server/plugins/engine/outputFormatters/index.test.ts +0 -17
  143. package/src/server/plugins/engine/outputFormatters/index.ts +0 -44
  144. package/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +0 -229
  145. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +0 -140
  146. package/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +0 -229
  147. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +0 -153
  148. package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +0 -1108
  149. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +0 -446
  150. package/src/server/plugins/engine/pageControllers/PageController.test.ts +0 -205
  151. package/src/server/plugins/engine/pageControllers/PageController.ts +0 -176
  152. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +0 -1264
  153. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +0 -561
  154. package/src/server/plugins/engine/pageControllers/README.md +0 -28
  155. package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +0 -264
  156. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +0 -458
  157. package/src/server/plugins/engine/pageControllers/StartPageController.ts +0 -18
  158. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +0 -50
  159. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +0 -261
  160. package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +0 -28
  161. package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +0 -19
  162. package/src/server/plugins/engine/pageControllers/helpers.test.ts +0 -198
  163. package/src/server/plugins/engine/pageControllers/helpers.ts +0 -101
  164. package/src/server/plugins/engine/pageControllers/index.ts +0 -10
  165. package/src/server/plugins/engine/pageControllers/validationOptions.ts +0 -89
  166. package/src/server/plugins/engine/plugin.ts +0 -673
  167. package/src/server/plugins/engine/services/formSubmissionService.js +0 -46
  168. package/src/server/plugins/engine/services/formsService.js +0 -46
  169. package/src/server/plugins/engine/services/formsService.test.js +0 -90
  170. package/src/server/plugins/engine/services/index.js +0 -3
  171. package/src/server/plugins/engine/services/notifyService.test.ts +0 -132
  172. package/src/server/plugins/engine/services/notifyService.ts +0 -64
  173. package/src/server/plugins/engine/services/uploadService.js +0 -60
  174. package/src/server/plugins/engine/types.ts +0 -315
  175. package/src/server/plugins/engine/views/components/autocompletefield.html +0 -5
  176. package/src/server/plugins/engine/views/components/checkboxesfield.html +0 -5
  177. package/src/server/plugins/engine/views/components/datepartsfield.html +0 -5
  178. package/src/server/plugins/engine/views/components/details.html +0 -6
  179. package/src/server/plugins/engine/views/components/emailaddressfield.html +0 -5
  180. package/src/server/plugins/engine/views/components/fileuploadfield-key.html +0 -8
  181. package/src/server/plugins/engine/views/components/fileuploadfield-value.html +0 -3
  182. package/src/server/plugins/engine/views/components/fileuploadfield.html +0 -24
  183. package/src/server/plugins/engine/views/components/html.html +0 -3
  184. package/src/server/plugins/engine/views/components/insettext.html +0 -7
  185. package/src/server/plugins/engine/views/components/list.html +0 -36
  186. package/src/server/plugins/engine/views/components/monthyearfield.html +0 -5
  187. package/src/server/plugins/engine/views/components/multilinetextfield.html +0 -10
  188. package/src/server/plugins/engine/views/components/numberfield.html +0 -5
  189. package/src/server/plugins/engine/views/components/radiosfield.html +0 -5
  190. package/src/server/plugins/engine/views/components/selectfield.html +0 -5
  191. package/src/server/plugins/engine/views/components/telephonenumberfield.html +0 -5
  192. package/src/server/plugins/engine/views/components/textfield.html +0 -5
  193. package/src/server/plugins/engine/views/components/ukaddressfield.html +0 -25
  194. package/src/server/plugins/engine/views/components/yesnofield.html +0 -5
  195. package/src/server/plugins/engine/views/file-upload.html +0 -45
  196. package/src/server/plugins/engine/views/index.html +0 -39
  197. package/src/server/plugins/engine/views/item-delete.html +0 -56
  198. package/src/server/plugins/engine/views/partials/components.html +0 -6
  199. package/src/server/plugins/engine/views/partials/conditional-components.html +0 -3
  200. package/src/server/plugins/engine/views/partials/debug.html +0 -44
  201. package/src/server/plugins/engine/views/partials/form.html +0 -15
  202. package/src/server/plugins/engine/views/partials/heading.html +0 -16
  203. package/src/server/plugins/engine/views/partials/preview-banner.html +0 -32
  204. package/src/server/plugins/engine/views/partials/preview-banner.test.js +0 -122
  205. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +0 -10
  206. package/src/server/plugins/engine/views/repeat-list-summary.html +0 -53
  207. package/src/server/plugins/errorPages.ts +0 -58
  208. package/src/server/plugins/nunjucks/context.js +0 -88
  209. package/src/server/plugins/nunjucks/context.test.js +0 -142
  210. package/src/server/plugins/nunjucks/enviroment.test.js +0 -201
  211. package/src/server/plugins/nunjucks/environment.js +0 -116
  212. package/src/server/plugins/nunjucks/filters/answer.js +0 -27
  213. package/src/server/plugins/nunjucks/filters/answer.test.js +0 -89
  214. package/src/server/plugins/nunjucks/filters/evaluate.js +0 -21
  215. package/src/server/plugins/nunjucks/filters/field.js +0 -28
  216. package/src/server/plugins/nunjucks/filters/field.test.js +0 -75
  217. package/src/server/plugins/nunjucks/filters/highlight.js +0 -11
  218. package/src/server/plugins/nunjucks/filters/href.js +0 -30
  219. package/src/server/plugins/nunjucks/filters/href.test.js +0 -80
  220. package/src/server/plugins/nunjucks/filters/index.js +0 -8
  221. package/src/server/plugins/nunjucks/filters/inspect.js +0 -15
  222. package/src/server/plugins/nunjucks/filters/page.js +0 -24
  223. package/src/server/plugins/nunjucks/filters/page.test.js +0 -65
  224. package/src/server/plugins/nunjucks/index.js +0 -3
  225. package/src/server/plugins/nunjucks/plugin.js +0 -40
  226. package/src/server/plugins/nunjucks/render.js +0 -42
  227. package/src/server/plugins/nunjucks/types.js +0 -40
  228. package/src/server/plugins/pulse.ts +0 -11
  229. package/src/server/plugins/router.ts +0 -201
  230. package/src/server/plugins/session.ts +0 -28
  231. package/src/server/routes/health.js +0 -13
  232. package/src/server/routes/health.test.js +0 -35
  233. package/src/server/routes/index.test.ts +0 -125
  234. package/src/server/routes/index.ts +0 -2
  235. package/src/server/routes/public.ts +0 -47
  236. package/src/server/routes/types.ts +0 -48
  237. package/src/server/schemas/index.ts +0 -34
  238. package/src/server/secure-context.js +0 -43
  239. package/src/server/services/cacheService.test.ts +0 -276
  240. package/src/server/services/cacheService.ts +0 -131
  241. package/src/server/services/httpService.test.js +0 -491
  242. package/src/server/services/httpService.ts +0 -50
  243. package/src/server/services/index.ts +0 -1
  244. package/src/server/types.ts +0 -54
  245. package/src/server/utils/notify.test.ts +0 -37
  246. package/src/server/utils/notify.ts +0 -50
  247. package/src/server/utils/secure-context/get-trust-store-certs.js +0 -11
  248. package/src/server/utils/secure-context/get-trust-store-certs.test.js +0 -19
  249. package/src/server/utils/utils.js +0 -24
  250. package/src/server/utils/utils.test.js +0 -54
  251. package/src/server/views/404.html +0 -16
  252. package/src/server/views/500.html +0 -19
  253. package/src/server/views/components/debug/macro.njk +0 -3
  254. package/src/server/views/components/debug/template.njk +0 -13
  255. package/src/server/views/components/service-banner/macro.njk +0 -3
  256. package/src/server/views/components/service-banner/template.njk +0 -20
  257. package/src/server/views/components/service-banner/template.test.js +0 -43
  258. package/src/server/views/components/tag-env/macro.njk +0 -3
  259. package/src/server/views/components/tag-env/template.njk +0 -30
  260. package/src/server/views/components/tag-env/template.test.js +0 -66
  261. package/src/server/views/confirmation.html +0 -19
  262. package/src/server/views/help/accessibility-statement.html +0 -58
  263. package/src/server/views/help/cookie-preferences.html +0 -57
  264. package/src/server/views/help/cookies.html +0 -71
  265. package/src/server/views/help/get-support.html +0 -37
  266. package/src/server/views/help/privacy-notice.html +0 -68
  267. package/src/server/views/help/terms-and-conditions.html +0 -83
  268. package/src/server/views/layout.html +0 -199
  269. package/src/server/views/summary.html +0 -50
  270. package/src/typings/hapi/index.d.ts +0 -95
  271. package/src/typings/hapi-tracing/index.d.ts +0 -6
  272. package/src/typings/index.d.ts +0 -3
  273. package/src/typings/joi/index.d.ts +0 -22
  274. package/stylelint.config.js +0 -10
  275. package/test/client/javascripts/file-upload.test.js +0 -1197
  276. package/test/condition/checkboxes.test.js +0 -112
  277. package/test/condition/radios.test.js +0 -112
  278. package/test/condition/text.test.js +0 -103
  279. package/test/fixtures/assets-manifest.json +0 -4
  280. package/test/fixtures/form.js +0 -86
  281. package/test/fixtures/index.js +0 -2
  282. package/test/fixtures/list.js +0 -92
  283. package/test/form/cookies.test.js +0 -338
  284. package/test/form/csrf.test.js +0 -87
  285. package/test/form/definitions/basic.js +0 -101
  286. package/test/form/definitions/blank.js +0 -10
  287. package/test/form/definitions/checkboxes.json +0 -88
  288. package/test/form/definitions/components.json +0 -452
  289. package/test/form/definitions/conditional-reveal.js +0 -140
  290. package/test/form/definitions/conditions-basic.js +0 -187
  291. package/test/form/definitions/conditions-complex.js +0 -338
  292. package/test/form/definitions/conditions-dates.js +0 -78
  293. package/test/form/definitions/conditions-escaping.js +0 -143
  294. package/test/form/definitions/demo-cph-number.js +0 -3099
  295. package/test/form/definitions/feedback.json +0 -45
  296. package/test/form/definitions/fields-optional.js +0 -402
  297. package/test/form/definitions/fields-required.js +0 -402
  298. package/test/form/definitions/file-upload-basic.js +0 -44
  299. package/test/form/definitions/file-upload.js +0 -66
  300. package/test/form/definitions/minimal.js +0 -39
  301. package/test/form/definitions/phase-alpha.json +0 -33
  302. package/test/form/definitions/phase-default.json +0 -26
  303. package/test/form/definitions/radios.json +0 -88
  304. package/test/form/definitions/repeat-mixed.js +0 -54
  305. package/test/form/definitions/repeat.js +0 -70
  306. package/test/form/definitions/status.json +0 -126
  307. package/test/form/definitions/templates.js +0 -183
  308. package/test/form/definitions/test.json +0 -581
  309. package/test/form/definitions/text.json +0 -75
  310. package/test/form/definitions/titles.json +0 -170
  311. package/test/form/definitions.test.js +0 -47
  312. package/test/form/exit-page.test.js +0 -210
  313. package/test/form/feedback.test.js +0 -68
  314. package/test/form/fields-optional.test.js +0 -237
  315. package/test/form/fields-required.test.js +0 -294
  316. package/test/form/file-upload.test.js +0 -313
  317. package/test/form/govuk-notify.test.js +0 -449
  318. package/test/form/journey-basic.test.js +0 -444
  319. package/test/form/persist-files.test.js +0 -227
  320. package/test/form/phase-banner.test.js +0 -71
  321. package/test/form/repeat.test.js +0 -628
  322. package/test/form/summary-submission-email.test.js +0 -95
  323. package/test/form/template.test.js +0 -288
  324. package/test/form/titles.test.js +0 -204
  325. package/test/helpers/component-helpers.js +0 -74
  326. package/test/utils/get-cookie.js +0 -42
  327. package/test/utils/get-form-definitions.js +0 -18
  328. package/tmp.pdf +0 -1
  329. package/tsconfig.json +0 -28
  330. package/webpack.config.js +0 -208
@@ -1,444 +0,0 @@
1
- import { join } from 'node:path'
2
-
3
- import { within } from '@testing-library/dom'
4
- import { StatusCodes } from 'http-status-codes'
5
-
6
- import { createServer } from '~/src/server/index.js'
7
- import { submit } from '~/src/server/plugins/engine/services/formSubmissionService.js'
8
- import { getFormMetadata } from '~/src/server/plugins/engine/services/formsService.js'
9
- import { FormAction } from '~/src/server/routes/types.js'
10
- import * as fixtures from '~/test/fixtures/index.js'
11
- import { renderResponse } from '~/test/helpers/component-helpers.js'
12
- import { getCookie, getCookieHeader } from '~/test/utils/get-cookie.js'
13
-
14
- const basePath = '/basic'
15
-
16
- jest.mock('~/src/server/utils/notify.ts')
17
- jest.mock('~/src/server/plugins/engine/services/formsService.js')
18
- jest.mock('~/src/server/plugins/engine/services/formSubmissionService.js')
19
-
20
- describe('Form journey', () => {
21
- const journey = [
22
- /**
23
- * Question page 1
24
- */
25
- {
26
- heading1: 'Buy a rod fishing licence',
27
- heading2: 'Licence details',
28
-
29
- paths: {
30
- current: '/licence',
31
- next: '/full-name'
32
- },
33
-
34
- fields: [
35
- {
36
- title: 'Which fishing licence do you want to get?',
37
- text: '1 day',
38
- payload: {
39
- empty: { licenceLength: '' },
40
- valid: { licenceLength: '1' }
41
- },
42
-
43
- errors: {
44
- empty: 'Select which fishing licence do you want to get?'
45
- }
46
- }
47
- ]
48
- },
49
-
50
- /**
51
- * Question page 2
52
- */
53
- {
54
- heading1: "What's your name?",
55
- heading2: 'Personal details',
56
-
57
- paths: {
58
- current: '/full-name',
59
- previous: '/licence',
60
- next: '/summary'
61
- },
62
-
63
- fields: [
64
- {
65
- title: "What's your name?",
66
- text: 'Firstname Lastname',
67
- payload: {
68
- empty: { fullName: '' },
69
- valid: { fullName: 'Firstname Lastname' }
70
- },
71
-
72
- errors: {
73
- empty: "Enter what's your name?"
74
- }
75
- }
76
- ]
77
- },
78
-
79
- /**
80
- * Check answers
81
- */
82
- {
83
- heading1: 'Summary',
84
-
85
- paths: {
86
- current: '/summary',
87
- previous: '/full-name'
88
- }
89
- }
90
- ]
91
-
92
- /** @type {Server} */
93
- let server
94
-
95
- /** @type {string} */
96
- let csrfToken
97
-
98
- /** @type {ReturnType<typeof getCookieHeader>} */
99
- let headers
100
-
101
- /** @type {BoundFunctions<typeof queries>} */
102
- let container
103
-
104
- // Create server before each test
105
- beforeAll(async () => {
106
- server = await createServer({
107
- formFileName: 'basic.js',
108
- formFilePath: join(import.meta.dirname, 'definitions'),
109
- enforceCsrf: true
110
- })
111
-
112
- await server.initialize()
113
-
114
- // Navigate to start
115
- const response = await server.inject({
116
- url: `${basePath}${journey[0].paths.current}`
117
- })
118
-
119
- // Extract the session cookie
120
- csrfToken = getCookie(response, 'crumb')
121
- headers = getCookieHeader(response, ['session', 'crumb'])
122
- })
123
-
124
- beforeEach(() => {
125
- jest.mocked(getFormMetadata).mockResolvedValue(fixtures.form.metadata)
126
- })
127
-
128
- afterAll(async () => {
129
- await server.stop()
130
- })
131
-
132
- describe.each(journey)(
133
- 'Page: $paths.current',
134
- ({ heading1, heading2, paths, fields = [] }) => {
135
- beforeEach(async () => {
136
- ;({ container } = await renderResponse(server, {
137
- url: `${basePath}${paths.current}`,
138
- headers
139
- }))
140
- })
141
-
142
- if (paths.previous) {
143
- it('should render the back link', () => {
144
- const $backLink = container.getByRole('link', {
145
- name: 'Back'
146
- })
147
-
148
- expect($backLink).toBeInTheDocument()
149
- expect($backLink).toHaveAttribute(
150
- 'href',
151
- `${basePath}${paths.previous}`
152
- )
153
- })
154
- }
155
-
156
- it('should render the page heading', () => {
157
- const $heading = container.getByRole('heading', {
158
- name: heading1,
159
- level: 1
160
- })
161
-
162
- expect($heading).toBeInTheDocument()
163
- })
164
-
165
- if (heading2) {
166
- it('should render the page subheading', () => {
167
- const $heading = container.getByRole('heading', {
168
- name: heading2,
169
- level: 2
170
- })
171
-
172
- expect($heading).toBeInTheDocument()
173
- })
174
- }
175
-
176
- if (paths.next) {
177
- it('should show errors when invalid on submit', async () => {
178
- const payload = {}
179
-
180
- for (const field of fields) {
181
- Object.assign(payload, field.payload.empty)
182
- }
183
-
184
- // Submit form with empty values
185
- const { container, response } = await renderResponse(server, {
186
- url: `${basePath}${paths.current}`,
187
- method: 'POST',
188
- headers,
189
- payload: { ...payload, crumb: csrfToken }
190
- })
191
-
192
- expect(response.statusCode).toBe(StatusCodes.OK)
193
- expect(response.headers.location).toBeUndefined()
194
-
195
- const $errorSummary = container.getByRole('alert')
196
- const $errorItems = within($errorSummary).getAllByRole('listitem')
197
-
198
- const $heading = within($errorSummary).getByRole('heading', {
199
- name: 'There is a problem',
200
- level: 2
201
- })
202
-
203
- expect($heading).toBeInTheDocument()
204
-
205
- for (const [index, { errors }] of fields.entries()) {
206
- expect($errorItems[index]).toHaveTextContent(errors.empty)
207
- }
208
- })
209
-
210
- it('should redirect to the next page on submit', async () => {
211
- const payload = {}
212
-
213
- for (const field of fields) {
214
- Object.assign(payload, field.payload.valid)
215
- }
216
-
217
- // Submit form with populated values
218
- const response = await server.inject({
219
- url: `${basePath}${paths.current}`,
220
- method: 'POST',
221
- headers,
222
- payload: { ...payload, crumb: csrfToken }
223
- })
224
-
225
- expect(response.statusCode).toBe(StatusCodes.SEE_OTHER)
226
- expect(response.headers.location).toBe(`${basePath}${paths.next}`)
227
- })
228
- }
229
- }
230
- )
231
-
232
- describe('Page: /summary', () => {
233
- /** @type {HTMLElement[]} */
234
- let $titles
235
-
236
- /** @type {HTMLElement[]} */
237
- let $values
238
-
239
- /** @type {HTMLElement[]} */
240
- let $actions
241
-
242
- beforeEach(async () => {
243
- ;({ container } = await renderResponse(server, {
244
- url: `${basePath}/summary`,
245
- headers
246
- }))
247
-
248
- $titles = container.queryAllByRole('term')
249
-
250
- // Field values
251
- $values = container
252
- .queryAllByRole('definition')
253
- .filter(({ classList }) =>
254
- classList.contains('govuk-summary-list__value')
255
- )
256
-
257
- // Change links
258
- $actions = container
259
- .queryAllByRole('definition')
260
- .filter(({ classList }) =>
261
- classList.contains('govuk-summary-list__actions')
262
- )
263
- })
264
-
265
- it('should render the page heading with email notification warning', () => {
266
- const $heading = container.getByRole('heading', {
267
- name: 'Summary',
268
- level: 1
269
- })
270
- const $warning = container.getByRole('link', {
271
- name: 'enter the email address (opens in new tab)'
272
- })
273
-
274
- expect($warning).toBeInTheDocument()
275
- expect($heading).toBeInTheDocument()
276
- })
277
-
278
- it('should render each section heading', () => {
279
- const $section1 = container.getByRole('heading', {
280
- name: journey[0].heading2,
281
- level: 2
282
- })
283
-
284
- const $section2 = container.getByRole('heading', {
285
- name: journey[1].heading2,
286
- level: 2
287
- })
288
-
289
- expect($section1).toBeInTheDocument()
290
- expect($section2).toBeInTheDocument()
291
- })
292
-
293
- it('should render field values', () => {
294
- for (const { fields = [] } of journey) {
295
- for (const detail of fields) {
296
- const index = $titles.findIndex(
297
- ({ textContent }) => textContent?.trim() === detail.title
298
- )
299
-
300
- // Check for field title and value
301
- expect($titles[index]).toHaveTextContent(detail.title)
302
- expect($values[index]).toHaveTextContent(detail.text)
303
- }
304
- }
305
- })
306
-
307
- it('should render field change links', async () => {
308
- for (const { fields = [], paths } of journey) {
309
- for (const detail of fields) {
310
- const index = $titles.findIndex(
311
- ({ textContent }) => textContent?.trim() === detail.title
312
- )
313
-
314
- /** @satisfies {HTMLAnchorElement} */
315
- const $changeLink = within($actions[index]).getByRole('link', {
316
- name: `Change ${detail.title}`
317
- })
318
-
319
- const returnUrl = `${basePath}/summary`
320
-
321
- // Check for change link
322
- expect($changeLink).toBeInTheDocument()
323
- expect($changeLink).toHaveAttribute(
324
- 'href',
325
- `${basePath}${paths.current}?returnUrl=${encodeURIComponent(returnUrl)}`
326
- )
327
-
328
- // Follow change link
329
- const response1 = await server.inject({
330
- url: $changeLink.href,
331
- headers
332
- })
333
-
334
- expect(response1.statusCode).toBe(StatusCodes.OK)
335
-
336
- const payload = {}
337
-
338
- for (const field of fields) {
339
- Object.assign(payload, field.payload.valid)
340
- }
341
-
342
- // Submit and redirect back to summary page
343
- const response2 = await server.inject({
344
- url: $changeLink.href,
345
- method: 'POST',
346
- headers,
347
- payload: { ...payload, crumb: csrfToken }
348
- })
349
-
350
- expect(response2.statusCode).toBe(StatusCodes.SEE_OTHER)
351
- expect(response2.headers.location).toBe(returnUrl)
352
- }
353
- }
354
- })
355
-
356
- it('should prevent access to the complete page before submit', async () => {
357
- const response = await server.inject({
358
- url: `${basePath}/status`,
359
- headers
360
- })
361
-
362
- // Redirect back to start
363
- expect(response.statusCode).toBe(StatusCodes.MOVED_TEMPORARILY)
364
- expect(response.headers.location).toBe(`${basePath}/licence`)
365
- })
366
-
367
- it('should redirect to the complete page on submit', async () => {
368
- jest.mocked(submit).mockResolvedValueOnce({
369
- message: 'Submit completed',
370
- result: {
371
- files: {
372
- main: '00000000-0000-0000-0000-000000000000',
373
- repeaters: {}
374
- }
375
- }
376
- })
377
-
378
- const response = await server.inject({
379
- url: `${basePath}/summary`,
380
- method: 'POST',
381
- headers,
382
- payload: {
383
- crumb: csrfToken,
384
- action: FormAction.Send
385
- }
386
- })
387
-
388
- expect(submit).toHaveBeenCalledWith({
389
- main: [
390
- {
391
- name: 'licenceLength',
392
- title: 'Which fishing licence do you want to get?',
393
- value: '1'
394
- },
395
- {
396
- name: 'fullName',
397
- title: "What's your name?",
398
- value: 'Firstname Lastname'
399
- }
400
- ],
401
- repeaters: [],
402
- retrievalKey: 'enrique.chase@defra.gov.uk',
403
- sessionId: expect.any(String)
404
- })
405
-
406
- expect(response.statusCode).toBe(StatusCodes.SEE_OTHER)
407
- expect(response.headers.location).toBe(`${basePath}/status`)
408
-
409
- const { container } = await renderResponse(server, {
410
- url: `${basePath}/status`,
411
- headers
412
- })
413
-
414
- const $heading1 = container.getByRole('heading', {
415
- name: 'Form submitted',
416
- level: 1
417
- })
418
-
419
- const $heading2 = container.getByRole('heading', {
420
- name: 'What happens next',
421
- level: 2
422
- })
423
-
424
- expect($heading1).toBeInTheDocument()
425
- expect($heading2).toBeInTheDocument()
426
- })
427
-
428
- it('should redirect back to start (after submit)', async () => {
429
- const response = await server.inject({
430
- url: `${basePath}/summary`,
431
- headers
432
- })
433
-
434
- // Redirect back to start
435
- expect(response.statusCode).toBe(StatusCodes.MOVED_TEMPORARILY)
436
- expect(response.headers.location).toBe(`${basePath}/licence`)
437
- })
438
- })
439
- })
440
-
441
- /**
442
- * @import { Server } from '@hapi/hapi'
443
- * @import { BoundFunctions, queries } from '@testing-library/dom'
444
- */
@@ -1,227 +0,0 @@
1
- import { join } from 'node:path'
2
-
3
- import { StatusCodes } from 'http-status-codes'
4
-
5
- import { createServer } from '~/src/server/index.js'
6
- import {
7
- persistFiles,
8
- submit
9
- } from '~/src/server/plugins/engine/services/formSubmissionService.js'
10
- import { getFormMetadata } from '~/src/server/plugins/engine/services/formsService.js'
11
- import * as uploadService from '~/src/server/plugins/engine/services/uploadService.js'
12
- import { FileStatus, UploadStatus } from '~/src/server/plugins/engine/types.js'
13
- import { FormAction } from '~/src/server/routes/types.js'
14
- import { CacheService } from '~/src/server/services/cacheService.js'
15
- import * as fixtures from '~/test/fixtures/index.js'
16
- import { getCookieHeader } from '~/test/utils/get-cookie.js'
17
-
18
- const basePath = '/file-upload-basic'
19
-
20
- jest.mock('~/src/server/utils/notify.ts')
21
- jest.mock('~/src/server/plugins/engine/services/formsService.js')
22
- jest.mock('~/src/server/plugins/engine/services/formSubmissionService.js')
23
- jest.mock('~/src/server/plugins/engine/services/uploadService.js')
24
-
25
- /**
26
- * @satisfies {FileState}
27
- */
28
- const readyFile = {
29
- uploadId: '404a31b2-8ee8-49b5-a6e8-23da9e69ba9e',
30
- status: {
31
- uploadStatus: UploadStatus.ready,
32
- metadata: {
33
- retrievalKey: 'foo.bar@defra.gov.uk'
34
- },
35
- form: {
36
- file: {
37
- fileId: 'a9e7470b-86a5-4826-a908-360a36aac71d',
38
- filename: 'api details.pdf',
39
- fileStatus: FileStatus.complete,
40
- contentLength: 735163
41
- }
42
- },
43
- numberOfRejectedFiles: 0
44
- }
45
- }
46
-
47
- /**
48
- * @satisfies {FileState}
49
- */
50
- const readyFile2 = {
51
- uploadId: '404a31b2-8ee8-49b5-a6e8-23da9e69ba1f',
52
- status: {
53
- uploadStatus: UploadStatus.ready,
54
- metadata: {
55
- retrievalKey: 'foo.bar@defra.gov.uk'
56
- },
57
- form: {
58
- file: {
59
- fileId: 'a9e7470b-86a5-4826-a908-360a36aac72a',
60
- filename: 'myfile.pdf',
61
- fileStatus: FileStatus.complete,
62
- contentLength: 735163
63
- }
64
- },
65
- numberOfRejectedFiles: 0
66
- }
67
- }
68
-
69
- describe('Submission journey test', () => {
70
- /** @type {Server} */
71
- let server
72
-
73
- // Create server before each test
74
- beforeAll(async () => {
75
- server = await createServer({
76
- formFileName: 'file-upload-basic.js',
77
- formFilePath: join(import.meta.dirname, 'definitions')
78
- })
79
-
80
- await server.initialize()
81
- })
82
-
83
- beforeEach(() => {
84
- jest.mocked(getFormMetadata).mockResolvedValue(fixtures.form.metadata)
85
- })
86
-
87
- afterAll(async () => {
88
- await server.stop()
89
- })
90
-
91
- test('GET /file-upload-component returns 200', async () => {
92
- jest.spyOn(CacheService.prototype, 'getState').mockResolvedValueOnce({})
93
-
94
- jest.mocked(uploadService.initiateUpload).mockResolvedValueOnce({
95
- uploadId: '123-546-789',
96
- uploadUrl: 'http://localhost:7337/upload-and-scan/123-546-789',
97
- statusUrl: 'http://localhost:7337/status/123-546-789'
98
- })
99
-
100
- const res = await server.inject({
101
- url: `${basePath}/file-upload-component`
102
- })
103
-
104
- expect(res.statusCode).toBe(StatusCodes.OK)
105
- expect(res.headers['content-type']).toContain('text/html')
106
- })
107
-
108
- test('POST /file-upload-component returns 303', async () => {
109
- jest.spyOn(CacheService.prototype, 'getState').mockResolvedValueOnce(
110
- // @ts-expect-error - Allow upload property mismatch with `FormState`
111
- /** @type {FormSubmissionState} */ ({
112
- upload: {
113
- '/file-upload-component': {
114
- files: [readyFile, readyFile2],
115
- upload: {
116
- uploadId: '123-546-788',
117
- uploadUrl: 'http://localhost:7337/upload-and-scan/123-546-788',
118
- statusUrl: 'http://localhost:7337/status/123-546-788'
119
- }
120
- }
121
- }
122
- })
123
- )
124
-
125
- jest
126
- .mocked(uploadService.getUploadStatus)
127
- .mockResolvedValueOnce(readyFile.status)
128
- .mockResolvedValueOnce(readyFile2.status)
129
-
130
- jest.mocked(getFormMetadata).mockResolvedValue(fixtures.form.metadata)
131
-
132
- jest.mocked(uploadService.initiateUpload).mockResolvedValueOnce({
133
- uploadId: '123-546-790',
134
- uploadUrl: 'http://localhost:7337/upload-and-scan/123-546-790',
135
- statusUrl: 'http://localhost:7337/status/123-546-790'
136
- })
137
-
138
- jest.mocked(submit).mockResolvedValueOnce({
139
- message: 'Submit completed',
140
- result: {
141
- files: {
142
- main: '00000000-0000-0000-0000-000000000000',
143
- repeaters: {}
144
- }
145
- }
146
- })
147
-
148
- // POST the form data to set the state
149
- const res = await server.inject({
150
- url: `${basePath}/file-upload-component`,
151
- method: 'POST',
152
- payload: {
153
- crumb: 'dummyCrumb',
154
- action: FormAction.Validate
155
- }
156
- })
157
-
158
- expect(res.statusCode).toBe(StatusCodes.SEE_OTHER)
159
- expect(res.headers.location).toBe(`${basePath}/summary`)
160
-
161
- // Extract the session cookie
162
- const headers = getCookieHeader(res, 'session')
163
-
164
- // GET the summary page
165
- await server.inject({
166
- url: `${basePath}/summary`,
167
- headers
168
- })
169
-
170
- // POST the summary form and assert
171
- // the mock sendNotification contains
172
- // the correct personalisation data
173
- const submitRes = await server.inject({
174
- url: `${basePath}/summary`,
175
- method: 'POST',
176
- headers,
177
- payload: {}
178
- })
179
-
180
- expect(persistFiles).toHaveBeenCalledTimes(1)
181
- expect(submit).toHaveBeenCalledWith({
182
- main: [
183
- {
184
- name: 'fileUpload',
185
- title: 'Upload something',
186
- value: [
187
- 'a9e7470b-86a5-4826-a908-360a36aac71d',
188
- 'a9e7470b-86a5-4826-a908-360a36aac72a'
189
- ].join(',')
190
- }
191
- ],
192
- repeaters: [],
193
- retrievalKey: 'enrique.chase@defra.gov.uk',
194
- sessionId: expect.any(String)
195
- })
196
-
197
- expect(submitRes.statusCode).toBe(StatusCodes.SEE_OTHER)
198
- expect(submitRes.headers.location).toBe(`${basePath}/status`)
199
-
200
- // Finally GET the /{slug}/status page
201
- const statusRes = await server.inject({
202
- url: `${basePath}/status`,
203
- headers
204
- })
205
-
206
- expect(statusRes.statusCode).toBe(StatusCodes.OK)
207
- expect(statusRes.headers['content-type']).toContain('text/html')
208
- expect(persistFiles).toHaveBeenCalledWith(
209
- [
210
- {
211
- fileId: readyFile.status.form.file.fileId,
212
- initiatedRetrievalKey: readyFile.status.metadata.retrievalKey
213
- },
214
- {
215
- fileId: readyFile2.status.form.file.fileId,
216
- initiatedRetrievalKey: readyFile2.status.metadata.retrievalKey
217
- }
218
- ],
219
- 'enrique.chase@defra.gov.uk'
220
- )
221
- })
222
- })
223
-
224
- /**
225
- * @import { Server } from '@hapi/hapi'
226
- * @import { FileState, FormSubmissionState } from '~/src/server/plugins/engine/types.js'
227
- */