@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,46 +0,0 @@
1
- import { formMetadataSchema } from '@defra/forms-model'
2
-
3
- import { config } from '~/src/config/index.js'
4
- import { FormStatus } from '~/src/server/routes/types.js'
5
- import { getJson } from '~/src/server/services/httpService.js'
6
-
7
- /**
8
- * Retrieves a form definition from the form manager for a given slug
9
- * @param {string} slug - the slug of the form
10
- */
11
- export async function getFormMetadata(slug) {
12
- const getJsonByType = /** @type {typeof getJson<FormMetadata>} */ (getJson)
13
-
14
- const { payload: metadata } = await getJsonByType(
15
- `${config.get('managerUrl')}/forms/slug/${slug}`
16
- )
17
-
18
- // Run it through the schema to coerce dates
19
- const result = formMetadataSchema.validate(metadata)
20
-
21
- if (result.error) {
22
- throw result.error
23
- }
24
-
25
- return result.value
26
- }
27
-
28
- /**
29
- * Retrieves a form definition from the form manager for a given id
30
- * @param {string} id - the id of the form
31
- * @param {FormStatus} state - the state of the form
32
- */
33
- export async function getFormDefinition(id, state) {
34
- const getJsonByType = /** @type {typeof getJson<FormDefinition>} */ (getJson)
35
-
36
- const suffix = state === FormStatus.Draft ? `/${state}` : ''
37
- const { payload: definition } = await getJsonByType(
38
- `${config.get('managerUrl')}/forms/${id}/definition${suffix}`
39
- )
40
-
41
- return definition
42
- }
43
-
44
- /**
45
- * @import { FormDefinition, FormMetadata } from '@defra/forms-model'
46
- */
@@ -1,90 +0,0 @@
1
- import { StatusCodes } from 'http-status-codes'
2
-
3
- import {
4
- getFormDefinition,
5
- getFormMetadata
6
- } from '~/src/server/plugins/engine/services/formsService.js'
7
- import { FormStatus } from '~/src/server/routes/types.js'
8
- import { getJson } from '~/src/server/services/httpService.js'
9
- import * as fixtures from '~/test/fixtures/index.js'
10
-
11
- const { MANAGER_URL } = process.env
12
-
13
- jest.mock('~/src/server/services/httpService')
14
-
15
- describe('Forms service', () => {
16
- const { definition, metadata } = fixtures.form
17
-
18
- describe('getFormMetadata', () => {
19
- beforeEach(() => {
20
- jest.mocked(getJson).mockResolvedValue({
21
- res: /** @type {IncomingMessage} */ ({
22
- statusCode: StatusCodes.OK
23
- }),
24
- payload: metadata
25
- })
26
- })
27
-
28
- it('requests JSON via form slug', async () => {
29
- await getFormMetadata(metadata.slug)
30
-
31
- expect(getJson).toHaveBeenCalledWith(
32
- `${MANAGER_URL}/forms/slug/${metadata.slug}`
33
- )
34
- })
35
-
36
- it('coerces timestamps from string to Date', async () => {
37
- const payload = {
38
- ...structuredClone(metadata),
39
-
40
- // JSON payload uses string dates in transit
41
- createdAt: metadata.createdAt.toISOString(),
42
- updatedAt: metadata.updatedAt.toISOString()
43
- }
44
-
45
- jest.mocked(getJson).mockResolvedValue({
46
- res: /** @type {IncomingMessage} */ ({
47
- statusCode: StatusCodes.OK
48
- }),
49
- payload
50
- })
51
-
52
- await expect(getFormMetadata(metadata.slug)).resolves.toEqual({
53
- ...metadata,
54
- createdAt: expect.any(Date),
55
- updatedAt: expect.any(Date)
56
- })
57
- })
58
- })
59
-
60
- describe('getFormDefinition', () => {
61
- beforeEach(() => {
62
- jest.mocked(getJson).mockResolvedValue({
63
- res: /** @type {IncomingMessage} */ ({
64
- statusCode: StatusCodes.OK
65
- }),
66
- payload: definition
67
- })
68
- })
69
-
70
- it('requests JSON via form ID (draft)', async () => {
71
- await getFormDefinition(metadata.id, FormStatus.Draft)
72
-
73
- expect(getJson).toHaveBeenCalledWith(
74
- `${MANAGER_URL}/forms/${metadata.id}/definition/draft`
75
- )
76
- })
77
-
78
- it('requests JSON via form ID (live)', async () => {
79
- await getFormDefinition(metadata.id, FormStatus.Live)
80
-
81
- expect(getJson).toHaveBeenCalledWith(
82
- `${MANAGER_URL}/forms/${metadata.id}/definition`
83
- )
84
- })
85
- })
86
- })
87
-
88
- /**
89
- * @import { IncomingMessage } from 'node:http'
90
- */
@@ -1,3 +0,0 @@
1
- export * as formsService from '~/src/server/plugins/engine/services/formsService.js'
2
- export * as formSubmissionService from '~/src/server/plugins/engine/services/formSubmissionService.js'
3
- export * as outputService from '~/src/server/plugins/engine/services/notifyService.js'
@@ -1,132 +0,0 @@
1
- import { checkFormStatus } from '~/src/server/plugins/engine/helpers.js'
2
- import { type FormModel } from '~/src/server/plugins/engine/models/index.js'
3
- import { type DetailItem } from '~/src/server/plugins/engine/models/types.js'
4
- import { getFormatter } from '~/src/server/plugins/engine/outputFormatters/index.js'
5
- import { submit } from '~/src/server/plugins/engine/services/notifyService.js'
6
- import {
7
- FormStatus,
8
- type FormRequestPayload
9
- } from '~/src/server/routes/types.js'
10
- import { sendNotification } from '~/src/server/utils/notify.js'
11
-
12
- jest.mock('~/src/server/utils/notify')
13
- jest.mock('~/src/server/plugins/engine/helpers')
14
- jest.mock('~/src/server/plugins/engine/outputFormatters/index')
15
-
16
- describe('notifyService', () => {
17
- const submitResponse = {
18
- message: 'Submit completed',
19
- result: {
20
- files: {
21
- main: '00000000-0000-0000-0000-000000000000',
22
- repeaters: {
23
- pizza: '11111111-1111-1111-1111-111111111111'
24
- }
25
- }
26
- }
27
- }
28
-
29
- const items: DetailItem[] = []
30
-
31
- const mockRequest: FormRequestPayload = jest.mocked<FormRequestPayload>({
32
- path: 'test',
33
- logger: {
34
- info: jest.fn()
35
- }
36
- } as unknown as FormRequestPayload)
37
- let model: FormModel
38
- const sendNotificationMock = jest.mocked(sendNotification)
39
-
40
- beforeEach(() => {
41
- jest.resetAllMocks()
42
- })
43
-
44
- it('creates a subject line for real forms', async () => {
45
- model = {
46
- name: 'foobar',
47
- def: {
48
- output: {
49
- audience: 'human',
50
- version: '1'
51
- }
52
- }
53
- } as FormModel
54
-
55
- jest.mocked(checkFormStatus).mockReturnValue({
56
- isPreview: false,
57
- state: FormStatus.Draft
58
- })
59
- jest.mocked(getFormatter).mockReturnValue(() => 'dummy-live')
60
-
61
- await submit(mockRequest, model, 'test@defra.gov.uk', items, submitResponse)
62
-
63
- expect(sendNotificationMock).toHaveBeenCalledWith(
64
- expect.objectContaining({
65
- personalisation: {
66
- subject: `Form submission: foobar`,
67
- body: 'dummy-live'
68
- }
69
- })
70
- )
71
- })
72
-
73
- it('creates a subject line for preview forms', async () => {
74
- model = {
75
- name: 'foobar',
76
- def: {
77
- output: {
78
- audience: 'human',
79
- version: '1'
80
- }
81
- }
82
- } as FormModel
83
-
84
- jest.mocked(checkFormStatus).mockReturnValue({
85
- isPreview: true,
86
- state: FormStatus.Draft
87
- })
88
- jest.mocked(getFormatter).mockReturnValue(() => 'dummy-preview')
89
-
90
- await submit(mockRequest, model, 'test@defra.gov.uk', items, submitResponse)
91
-
92
- expect(sendNotificationMock).toHaveBeenCalledWith(
93
- expect.objectContaining({
94
- personalisation: {
95
- subject: `TEST FORM SUBMISSION: foobar`,
96
- body: 'dummy-preview'
97
- }
98
- })
99
- )
100
- })
101
-
102
- it('base64 encodes form data when aimed at machines', async () => {
103
- model = {
104
- name: 'foobar',
105
- def: {
106
- output: {
107
- audience: 'machine',
108
- version: '1'
109
- }
110
- }
111
- } as FormModel
112
-
113
- jest.mocked(checkFormStatus).mockReturnValue({
114
- isPreview: true,
115
- state: FormStatus.Draft
116
- })
117
- jest
118
- .mocked(getFormatter)
119
- .mockReturnValue(() => 'dummy-preview " Hello world \' !@/')
120
-
121
- await submit(mockRequest, model, 'test@defra.gov.uk', items, submitResponse)
122
-
123
- expect(sendNotificationMock).toHaveBeenCalledWith(
124
- expect.objectContaining({
125
- personalisation: {
126
- subject: `TEST FORM SUBMISSION: foobar`,
127
- body: 'ZHVtbXktcHJldmlldyAiIEhlbGxvIHdvcmxkICcgIUAv'
128
- }
129
- })
130
- )
131
- })
132
- })
@@ -1,64 +0,0 @@
1
- import { type SubmitResponsePayload } from '@defra/forms-model'
2
-
3
- import { config } from '~/src/config/index.js'
4
- import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js'
5
- import { checkFormStatus } from '~/src/server/plugins/engine/helpers.js'
6
- import { type FormModel } from '~/src/server/plugins/engine/models/index.js'
7
- import { type DetailItem } from '~/src/server/plugins/engine/models/types.js'
8
- import { getFormatter } from '~/src/server/plugins/engine/outputFormatters/index.js'
9
- import { type FormRequestPayload } from '~/src/server/routes/types.js'
10
- import { sendNotification } from '~/src/server/utils/notify.js'
11
-
12
- const templateId = config.get('notifyTemplateId')
13
-
14
- export async function submit(
15
- request: FormRequestPayload,
16
- model: FormModel,
17
- emailAddress: string,
18
- items: DetailItem[],
19
- submitResponse: SubmitResponsePayload
20
- ) {
21
- const logTags = ['submit', 'email']
22
- const { path } = request
23
- const formStatus = checkFormStatus(path)
24
-
25
- // Get submission email personalisation
26
- request.logger.info(logTags, 'Getting personalisation data')
27
-
28
- const formName = escapeMarkdown(model.name)
29
- const subject = formStatus.isPreview
30
- ? `TEST FORM SUBMISSION: ${formName}`
31
- : `Form submission: ${formName}`
32
-
33
- const outputAudience = model.def.output?.audience ?? 'human'
34
- const outputVersion = model.def.output?.version ?? '1'
35
-
36
- const outputFormatter = getFormatter(outputAudience, outputVersion)
37
- let body = outputFormatter(items, model, submitResponse, formStatus)
38
-
39
- // GOV.UK Notify transforms quotes into curly quotes, so we can't just send the raw payload
40
- // This is logic specific to Notify, so we include the logic here rather than in the formatter
41
- if (outputAudience === 'machine') {
42
- body = Buffer.from(body).toString('base64')
43
- }
44
-
45
- request.logger.info(logTags, 'Sending email')
46
-
47
- try {
48
- // Send submission email
49
- await sendNotification({
50
- templateId,
51
- emailAddress,
52
- personalisation: {
53
- subject,
54
- body
55
- }
56
- })
57
-
58
- request.logger.info(logTags, 'Email sent successfully')
59
- } catch (err) {
60
- request.logger.error(logTags, 'Error sending email', err)
61
-
62
- throw err
63
- }
64
- }
@@ -1,60 +0,0 @@
1
- import { config } from '~/src/config/index.js'
2
- import { getJson, postJson } from '~/src/server/services/httpService.js'
3
-
4
- const uploaderUrl = config.get('uploaderUrl')
5
- const submissionUrl = config.get('submissionUrl')
6
- const uploaderBucketName = config.get('uploaderBucketName')
7
- const stagingPrefix = config.get('stagingPrefix')
8
-
9
- /**
10
- * Initiates a CDP file upload
11
- * @param {string} path - the path of the page in the form
12
- * @param {string} retrievalKey - the retrieval key for the files
13
- * @param {string} [mimeTypes] - the csv string of accepted mimeTypes
14
- */
15
- export async function initiateUpload(path, retrievalKey, mimeTypes) {
16
- const postJsonByType =
17
- /** @type {typeof postJson<UploadInitiateResponse>} */ (postJson)
18
-
19
- const payload = {
20
- redirect: path,
21
- callback: `${submissionUrl}/file`,
22
- s3Bucket: uploaderBucketName,
23
- s3Path: stagingPrefix,
24
- metadata: {
25
- retrievalKey
26
- },
27
- mimeTypes: mimeTypes
28
- ?.split(',')
29
- .map((type) => type.trim())
30
- .filter((type) => type !== '')
31
- // maxFileSize: 25 * 1000 * 1000
32
- }
33
-
34
- const { payload: initiate } = await postJsonByType(
35
- `${uploaderUrl}/initiate`,
36
- { payload }
37
- )
38
-
39
- return initiate
40
- }
41
-
42
- /**
43
- * Get the status of a CDP file upload
44
- * @param {string} uploadId - the ID of the upload
45
- */
46
- export async function getUploadStatus(uploadId) {
47
- const getJsonByType = /** @type {typeof getJson<UploadStatusResponse>} */ (
48
- getJson
49
- )
50
-
51
- const { payload: status } = await getJsonByType(
52
- `${uploaderUrl}/status/${uploadId}`
53
- )
54
-
55
- return status
56
- }
57
-
58
- /**
59
- * @import { UploadInitiateResponse, UploadStatusResponse } from '~/src/server/plugins/engine/types.js'
60
- */
@@ -1,315 +0,0 @@
1
- import {
2
- type ComponentDef,
3
- type Item,
4
- type List,
5
- type Page
6
- } from '@defra/forms-model'
7
- import { type ValidationErrorItem } from 'joi'
8
-
9
- import { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'
10
- import { type Component } from '~/src/server/plugins/engine/components/helpers.js'
11
- import {
12
- type BackLink,
13
- type ComponentText,
14
- type ComponentViewModel
15
- } from '~/src/server/plugins/engine/components/types.js'
16
- import { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'
17
- import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js'
18
- import { type ViewContext } from '~/src/server/plugins/nunjucks/types.js'
19
- import { type FormAction, type FormRequest } from '~/src/server/routes/types.js'
20
-
21
- /**
22
- * Form submission state stores the following in Redis:
23
- * Props containing user's submitted values as `{ [inputId]: value }` or as `{ [sectionName]: { [inputName]: value } }`
24
- * a) . e.g:
25
- * ```ts
26
- * {
27
- * _C9PRHmsgt: 'Ben',
28
- * WfLk9McjzX: 'Music',
29
- * IK7jkUFCBL: 'Royal Academy of Music'
30
- * }
31
- * ```
32
- *
33
- * b)
34
- * ```ts
35
- * {
36
- * checkBeforeYouStart: { ukPassport: true },
37
- * applicantDetails: {
38
- * numberOfApplicants: 1,
39
- * phoneNumber: '77777777',
40
- * emailAddress: 'aaa@aaa.com'
41
- * },
42
- * applicantOneDetails: {
43
- * firstName: 'a',
44
- * middleName: 'a',
45
- * lastName: 'a',
46
- * address: { addressLine1: 'a', addressLine2: 'a', town: 'a', postcode: 'a' }
47
- * }
48
- * }
49
- * ```
50
- */
51
-
52
- /**
53
- * Form submission state
54
- */
55
- export type FormSubmissionState = {
56
- upload?: Record<string, TempFileState>
57
- } & FormState
58
-
59
- export interface FormSubmissionError
60
- extends Pick<ValidationErrorItem, 'context' | 'path'> {
61
- href: string // e.g: '#dateField__day'
62
- name: string // e.g: 'dateField__day'
63
- text: string // e.g: 'Date field must be a real date'
64
- }
65
-
66
- export interface FormParams {
67
- action?: FormAction
68
- confirm?: true
69
- crumb?: string
70
- itemId?: string
71
- }
72
-
73
- /**
74
- * Form POST for question pages
75
- * (after Joi has converted value types)
76
- */
77
- export type FormPayload = FormParams & Partial<Record<string, FormValue>>
78
-
79
- export type FormValue =
80
- | Item['value']
81
- | Item['value'][]
82
- | UploadState
83
- | RepeatListState
84
- | undefined
85
-
86
- export type FormState = Partial<Record<string, FormStateValue>>
87
- export type FormStateValue = Exclude<FormValue, undefined> | null
88
-
89
- export interface FormValidationResult<
90
- ValueType extends FormPayload | FormSubmissionState
91
- > {
92
- value: ValueType
93
- errors: FormSubmissionError[] | undefined
94
- }
95
-
96
- export interface FormContext {
97
- /**
98
- * Evaluation form state only (filtered by visited paths),
99
- * with values formatted for condition evaluation using
100
- * {@link FormComponent.getContextValueFromState}
101
- */
102
- evaluationState: FormState
103
-
104
- /**
105
- * Relevant form state only (filtered by visited paths)
106
- */
107
- relevantState: FormState
108
-
109
- /**
110
- * Relevant pages only (filtered by visited paths)
111
- */
112
- relevantPages: PageControllerClass[]
113
-
114
- /**
115
- * Form submission payload (single page)
116
- */
117
- payload: FormPayload
118
-
119
- /**
120
- * Form submission state (entire form)
121
- */
122
- state: FormSubmissionState
123
-
124
- /**
125
- * Validation errors (entire form)
126
- */
127
- errors?: FormSubmissionError[]
128
-
129
- /**
130
- * Visited paths evaluated from form state
131
- */
132
- paths: string[]
133
-
134
- /**
135
- * Preview URL direct access is allowed
136
- */
137
- isForceAccess: boolean
138
-
139
- /**
140
- * Miscellaneous extra data from event responses
141
- */
142
- data: object
143
-
144
- pageDefMap: Map<string, Page>
145
- listDefMap: Map<string, List>
146
- componentDefMap: Map<string, ComponentDef>
147
- pageMap: Map<string, PageControllerClass>
148
- componentMap: Map<string, Component>
149
- }
150
-
151
- export type FormContextRequest = (
152
- | {
153
- method: 'get'
154
- payload?: undefined
155
- }
156
- | {
157
- method: 'post'
158
- payload: FormPayload
159
- }
160
- | {
161
- method: FormRequest['method']
162
- payload?: object | undefined
163
- }
164
- ) &
165
- Pick<FormRequest, 'app' | 'method' | 'params' | 'path' | 'query' | 'url'>
166
-
167
- export interface UploadInitiateResponse {
168
- uploadId: string
169
- uploadUrl: string
170
- statusUrl: string
171
- }
172
-
173
- export enum UploadStatus {
174
- initiated = 'initiated',
175
- pending = 'pending',
176
- ready = 'ready'
177
- }
178
-
179
- export enum FileStatus {
180
- complete = 'complete',
181
- rejected = 'rejected',
182
- pending = 'pending'
183
- }
184
-
185
- export type UploadState = FileState[]
186
-
187
- export type FileUpload = {
188
- fileId: string
189
- filename: string
190
- contentLength: number
191
- } & (
192
- | {
193
- fileStatus: FileStatus.complete | FileStatus.rejected | FileStatus.pending
194
- errorMessage?: string
195
- }
196
- | {
197
- fileStatus: FileStatus.complete
198
- errorMessage?: undefined
199
- }
200
- )
201
-
202
- export interface FileUploadMetadata {
203
- retrievalKey: string
204
- }
205
-
206
- export type UploadStatusResponse =
207
- | {
208
- uploadStatus: UploadStatus.initiated
209
- metadata: FileUploadMetadata
210
- form: { file?: undefined }
211
- }
212
- | {
213
- uploadStatus: UploadStatus.pending | UploadStatus.ready
214
- metadata: FileUploadMetadata
215
- form: { file: FileUpload }
216
- numberOfRejectedFiles?: number
217
- }
218
- | {
219
- uploadStatus: UploadStatus.ready
220
- metadata: FileUploadMetadata
221
- form: { file: FileUpload }
222
- numberOfRejectedFiles: 0
223
- }
224
-
225
- export type UploadStatusFileResponse = Exclude<
226
- UploadStatusResponse,
227
- { uploadStatus: UploadStatus.initiated }
228
- >
229
-
230
- export interface FileState {
231
- uploadId: string
232
- status: UploadStatusFileResponse
233
- }
234
-
235
- export interface TempFileState {
236
- upload?: UploadInitiateResponse
237
- files: UploadState
238
- }
239
-
240
- export interface RepeatItemState extends FormPayload {
241
- itemId: string
242
- }
243
-
244
- export type RepeatListState = RepeatItemState[]
245
-
246
- export interface CheckAnswers {
247
- title?: ComponentText
248
- summaryList: SummaryList
249
- }
250
-
251
- export interface SummaryList {
252
- classes?: string
253
- rows: SummaryListRow[]
254
- }
255
-
256
- export interface SummaryListRow {
257
- key: ComponentText
258
- value: ComponentText
259
- actions?: { items: SummaryListAction[] }
260
- }
261
-
262
- export type SummaryListAction = ComponentText & {
263
- href: string
264
- visuallyHiddenText: string
265
- }
266
-
267
- export interface PageViewModelBase extends Partial<ViewContext> {
268
- page: PageController
269
- name?: string
270
- pageTitle: string
271
- sectionTitle?: string
272
- showTitle: boolean
273
- isStartPage: boolean
274
- backLink?: BackLink
275
- feedbackLink?: string
276
- serviceUrl: string
277
- phaseTag?: string
278
- }
279
-
280
- export interface ItemDeletePageViewModel extends PageViewModelBase {
281
- context: FormContext
282
- itemTitle: string
283
- confirmation?: ComponentText
284
- buttonConfirm: ComponentText
285
- buttonCancel: ComponentText
286
- }
287
-
288
- export interface FormPageViewModel extends PageViewModelBase {
289
- components: ComponentViewModel[]
290
- context: FormContext
291
- errors?: FormSubmissionError[]
292
- hasMissingNotificationEmail?: boolean
293
- }
294
-
295
- export interface RepeaterSummaryPageViewModel extends PageViewModelBase {
296
- context: FormContext
297
- errors?: FormSubmissionError[]
298
- checkAnswers: CheckAnswers[]
299
- repeatTitle: string
300
- }
301
-
302
- export interface FeaturedFormPageViewModel extends FormPageViewModel {
303
- formAction?: string
304
- formComponent: ComponentViewModel
305
- componentsBefore: ComponentViewModel[]
306
- uploadId: string | undefined
307
- proxyUrl: string | null
308
- }
309
-
310
- export type PageViewModel =
311
- | PageViewModelBase
312
- | ItemDeletePageViewModel
313
- | FormPageViewModel
314
- | RepeaterSummaryPageViewModel
315
- | FeaturedFormPageViewModel