@defra/forms-engine-plugin 4.7.2-alpha → 4.7.3

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 (402) hide show
  1. package/.server/client/javascripts/geospatial-map.d.ts +6 -6
  2. package/.server/client/javascripts/geospatial-map.js +3 -3
  3. package/.server/client/javascripts/location-map.d.ts +1 -1
  4. package/.server/client/javascripts/location-map.js +1 -1
  5. package/.server/client/javascripts/map.d.ts +1 -1
  6. package/.server/client/javascripts/map.js +1 -1
  7. package/.server/client/javascripts/shared.d.ts +7 -7
  8. package/.server/server/index.d.ts +1 -1
  9. package/.server/server/plugins/crumb.d.ts +1 -1
  10. package/.server/server/plugins/engine/beta/form-context.d.ts +6 -6
  11. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +4 -4
  12. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +2 -2
  13. package/.server/server/plugins/engine/components/CheckboxesField.js +2 -2
  14. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  15. package/.server/server/plugins/engine/components/ComponentBase.d.ts +5 -5
  16. package/.server/server/plugins/engine/components/ComponentCollection.d.ts +8 -8
  17. package/.server/server/plugins/engine/components/DatePartsField.d.ts +11 -11
  18. package/.server/server/plugins/engine/components/DeclarationField.d.ts +3 -3
  19. package/.server/server/plugins/engine/components/Details.d.ts +1 -1
  20. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +22 -22
  21. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -4
  22. package/.server/server/plugins/engine/components/FileUploadField.d.ts +3 -3
  23. package/.server/server/plugins/engine/components/FormComponent.d.ts +10 -10
  24. package/.server/server/plugins/engine/components/GeospatialField.d.ts +6 -6
  25. package/.server/server/plugins/engine/components/HiddenField.d.ts +2 -2
  26. package/.server/server/plugins/engine/components/Html.d.ts +1 -1
  27. package/.server/server/plugins/engine/components/InsetText.d.ts +1 -1
  28. package/.server/server/plugins/engine/components/LatLongField.d.ts +22 -22
  29. package/.server/server/plugins/engine/components/List.d.ts +8 -8
  30. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +10 -10
  31. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +6 -6
  32. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +14 -14
  33. package/.server/server/plugins/engine/components/Markdown.d.ts +1 -1
  34. package/.server/server/plugins/engine/components/MonthYearField.d.ts +11 -11
  35. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +5 -5
  36. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +1 -1
  37. package/.server/server/plugins/engine/components/NumberField.d.ts +3 -3
  38. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +1 -1
  39. package/.server/server/plugins/engine/components/PaymentField.d.ts +12 -12
  40. package/.server/server/plugins/engine/components/RadiosField.d.ts +1 -1
  41. package/.server/server/plugins/engine/components/SelectField.d.ts +4 -4
  42. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +10 -10
  43. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +4 -4
  44. package/.server/server/plugins/engine/components/TextField.d.ts +2 -2
  45. package/.server/server/plugins/engine/components/UkAddressField.d.ts +11 -11
  46. package/.server/server/plugins/engine/components/YesNoField.d.ts +2 -2
  47. package/.server/server/plugins/engine/components/helpers/__stubs__/geospatial.d.ts +1 -1
  48. package/.server/server/plugins/engine/components/helpers/components.d.ts +5 -5
  49. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +1 -1
  50. package/.server/server/plugins/engine/components/index.d.ts +27 -27
  51. package/.server/server/plugins/engine/components/types.d.ts +1 -1
  52. package/.server/server/plugins/engine/configureEnginePlugin.d.ts +4 -4
  53. package/.server/server/plugins/engine/date-helper.d.ts +1 -1
  54. package/.server/server/plugins/engine/helpers.d.ts +8 -8
  55. package/.server/server/plugins/engine/index.d.ts +5 -5
  56. package/.server/server/plugins/engine/models/FormModel.d.ts +6 -6
  57. package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +6 -6
  58. package/.server/server/plugins/engine/models/index.d.ts +2 -2
  59. package/.server/server/plugins/engine/models/types.d.ts +4 -4
  60. package/.server/server/plugins/engine/options.d.ts +1 -1
  61. package/.server/server/plugins/engine/options.js +1 -1
  62. package/.server/server/plugins/engine/options.test.js +1 -1
  63. package/.server/server/plugins/engine/outputFormatters/adapter/v1.d.ts +4 -4
  64. package/.server/server/plugins/engine/outputFormatters/human/v1.d.ts +4 -4
  65. package/.server/server/plugins/engine/outputFormatters/index.d.ts +5 -5
  66. package/.server/server/plugins/engine/outputFormatters/machine/v1.d.ts +4 -4
  67. package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +4 -4
  68. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +8 -8
  69. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +6 -6
  70. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +8 -8
  71. package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +5 -5
  72. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +4 -4
  73. package/.server/server/plugins/engine/pageControllers/StatusPageController.d.ts +4 -4
  74. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +5 -5
  75. package/.server/server/plugins/engine/pageControllers/TerminalPageController.d.ts +3 -3
  76. package/.server/server/plugins/engine/pageControllers/__stubs__/request.d.ts +2 -2
  77. package/.server/server/plugins/engine/pageControllers/errors.d.ts +1 -1
  78. package/.server/server/plugins/engine/pageControllers/helpers/pages.d.ts +2 -2
  79. package/.server/server/plugins/engine/pageControllers/helpers/state.d.ts +5 -5
  80. package/.server/server/plugins/engine/pageControllers/helpers/state.js +1 -1
  81. package/.server/server/plugins/engine/pageControllers/helpers/state.js.map +1 -1
  82. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +1 -1
  83. package/.server/server/plugins/engine/pageControllers/index.d.ts +7 -7
  84. package/.server/server/plugins/engine/plugin.d.ts +1 -1
  85. package/.server/server/plugins/engine/routes/file-upload.d.ts +1 -1
  86. package/.server/server/plugins/engine/routes/index.d.ts +3 -3
  87. package/.server/server/plugins/engine/routes/payment-helper.d.ts +3 -3
  88. package/.server/server/plugins/engine/routes/payment-helper.js +2 -2
  89. package/.server/server/plugins/engine/routes/payment.js +5 -5
  90. package/.server/server/plugins/engine/routes/payment.test.js +1 -1
  91. package/.server/server/plugins/engine/routes/questions.d.ts +2 -2
  92. package/.server/server/plugins/engine/routes/repeaters/item-delete.d.ts +2 -2
  93. package/.server/server/plugins/engine/routes/repeaters/summary.d.ts +2 -2
  94. package/.server/server/plugins/engine/services/index.d.ts +3 -3
  95. package/.server/server/plugins/engine/services/notifyService.d.ts +4 -4
  96. package/.server/server/plugins/engine/services/uploadService.d.ts +2 -2
  97. package/.server/server/plugins/engine/services/uploadService.js +1 -1
  98. package/.server/server/plugins/engine/types/index.d.ts +10 -10
  99. package/.server/server/plugins/engine/types/schema.d.ts +1 -1
  100. package/.server/server/plugins/engine/types.d.ts +25 -16
  101. package/.server/server/plugins/engine/types.js.map +1 -1
  102. package/.server/server/plugins/engine/validationHelpers.d.ts +2 -2
  103. package/.server/server/plugins/engine/vision.d.ts +1 -1
  104. package/.server/server/plugins/map/index.d.ts +1 -1
  105. package/.server/server/plugins/map/index.js +1 -1
  106. package/.server/server/plugins/map/routes/get-os-token.d.ts +11 -1
  107. package/.server/server/plugins/map/routes/get-os-token.js +12 -2
  108. package/.server/server/plugins/map/routes/get-os-token.js.map +1 -1
  109. package/.server/server/plugins/map/routes/index.d.ts +4 -4
  110. package/.server/server/plugins/map/routes/index.js +3 -2
  111. package/.server/server/plugins/map/routes/index.js.map +1 -1
  112. package/.server/server/plugins/map/service.d.ts +1 -1
  113. package/.server/server/plugins/map/service.js +5 -2
  114. package/.server/server/plugins/map/service.js.map +1 -1
  115. package/.server/server/plugins/map/test/__stubs__/find.d.ts +1 -1
  116. package/.server/server/plugins/map/test/__stubs__/find.js +1 -1
  117. package/.server/server/plugins/nunjucks/context.d.ts +2 -2
  118. package/.server/server/plugins/nunjucks/context.js +2 -2
  119. package/.server/server/plugins/nunjucks/context.test.js +1 -1
  120. package/.server/server/plugins/nunjucks/enviroment.test.js +1 -1
  121. package/.server/server/plugins/nunjucks/environment.d.ts +3 -3
  122. package/.server/server/plugins/nunjucks/environment.js +3 -3
  123. package/.server/server/plugins/nunjucks/filters/answer.d.ts +1 -1
  124. package/.server/server/plugins/nunjucks/filters/answer.js +2 -2
  125. package/.server/server/plugins/nunjucks/filters/answer.test.js +1 -1
  126. package/.server/server/plugins/nunjucks/filters/evaluate.d.ts +1 -1
  127. package/.server/server/plugins/nunjucks/filters/evaluate.js +1 -1
  128. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  129. package/.server/server/plugins/nunjucks/filters/field.js +1 -1
  130. package/.server/server/plugins/nunjucks/filters/field.test.js +1 -1
  131. package/.server/server/plugins/nunjucks/filters/href.d.ts +1 -1
  132. package/.server/server/plugins/nunjucks/filters/href.js +1 -1
  133. package/.server/server/plugins/nunjucks/filters/href.test.js +1 -1
  134. package/.server/server/plugins/nunjucks/filters/index.d.ts +8 -8
  135. package/.server/server/plugins/nunjucks/filters/page.d.ts +1 -1
  136. package/.server/server/plugins/nunjucks/filters/page.js +1 -1
  137. package/.server/server/plugins/nunjucks/filters/page.test.js +1 -1
  138. package/.server/server/plugins/nunjucks/index.d.ts +3 -3
  139. package/.server/server/plugins/nunjucks/render.d.ts +2 -2
  140. package/.server/server/plugins/nunjucks/render.js +1 -1
  141. package/.server/server/plugins/nunjucks/types.d.ts +1 -1
  142. package/.server/server/plugins/nunjucks/types.js +1 -1
  143. package/.server/server/plugins/payment/helper.d.ts +2 -2
  144. package/.server/server/plugins/payment/helper.js +1 -1
  145. package/.server/server/plugins/payment/service.d.ts +3 -3
  146. package/.server/server/plugins/payment/service.js +1 -1
  147. package/.server/server/plugins/postcode-lookup/index.d.ts +1 -1
  148. package/.server/server/plugins/postcode-lookup/index.js +1 -1
  149. package/.server/server/plugins/postcode-lookup/models/index.d.ts +6 -6
  150. package/.server/server/plugins/postcode-lookup/models/index.js +1 -1
  151. package/.server/server/plugins/postcode-lookup/routes/index.d.ts +6 -6
  152. package/.server/server/plugins/postcode-lookup/routes/index.js +15 -15
  153. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  154. package/.server/server/plugins/postcode-lookup/service.d.ts +1 -1
  155. package/.server/server/plugins/postcode-lookup/service.js +5 -2
  156. package/.server/server/plugins/postcode-lookup/service.js.map +1 -1
  157. package/.server/server/plugins/postcode-lookup/types.js +1 -1
  158. package/.server/server/routes/index.d.ts +2 -2
  159. package/.server/server/routes/types.d.ts +1 -1
  160. package/.server/server/schemas/index.d.ts +2 -2
  161. package/.server/server/services/cacheService.d.ts +8 -8
  162. package/.server/server/services/cacheService.js +2 -5
  163. package/.server/server/services/cacheService.js.map +1 -1
  164. package/.server/server/services/httpService.test.js +1 -1
  165. package/.server/server/services/index.d.ts +1 -1
  166. package/.server/server/types.d.ts +7 -7
  167. package/.server/server/utils/file-form-service.d.ts +2 -2
  168. package/.server/server/utils/file-form-service.js +1 -1
  169. package/package.json +8 -4
  170. package/src/client/javascripts/application.js +1 -1
  171. package/src/client/javascripts/geospatial-map.js +4 -4
  172. package/src/client/javascripts/location-map.js +2 -2
  173. package/src/client/javascripts/map.js +3 -3
  174. package/src/client/javascripts/shared.js +7 -7
  175. package/src/index.ts +3 -3
  176. package/src/server/common/helpers/logging/logger-options.ts +1 -1
  177. package/src/server/common/helpers/logging/logger.ts +1 -1
  178. package/src/server/common/helpers/logging/request-logger.ts +1 -1
  179. package/src/server/common/helpers/logging/request-tracing.js +1 -1
  180. package/src/server/common/helpers/redis-client.js +2 -2
  181. package/src/server/index.ts +13 -13
  182. package/src/server/plugins/crumb.ts +2 -2
  183. package/src/server/plugins/engine/beta/form-context.ts +9 -9
  184. package/src/server/plugins/engine/components/AutocompleteField.ts +3 -3
  185. package/src/server/plugins/engine/components/CheckboxesField.ts +7 -8
  186. package/src/server/plugins/engine/components/ComponentBase.ts +5 -5
  187. package/src/server/plugins/engine/components/ComponentCollection.ts +9 -9
  188. package/src/server/plugins/engine/components/DatePartsField.ts +8 -8
  189. package/src/server/plugins/engine/components/DeclarationField.ts +3 -3
  190. package/src/server/plugins/engine/components/Details.ts +1 -1
  191. package/src/server/plugins/engine/components/EastingNorthingField.ts +9 -9
  192. package/src/server/plugins/engine/components/EmailAddressField.ts +3 -3
  193. package/src/server/plugins/engine/components/FileUploadField.ts +6 -6
  194. package/src/server/plugins/engine/components/FormComponent.ts +4 -4
  195. package/src/server/plugins/engine/components/GeospatialField.ts +5 -5
  196. package/src/server/plugins/engine/components/HiddenField.ts +4 -4
  197. package/src/server/plugins/engine/components/Html.ts +1 -1
  198. package/src/server/plugins/engine/components/InsetText.ts +1 -1
  199. package/src/server/plugins/engine/components/LatLongField.ts +9 -9
  200. package/src/server/plugins/engine/components/List.ts +2 -2
  201. package/src/server/plugins/engine/components/ListFormComponent.ts +4 -4
  202. package/src/server/plugins/engine/components/LocationFieldBase.ts +5 -5
  203. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +5 -5
  204. package/src/server/plugins/engine/components/Markdown.ts +1 -1
  205. package/src/server/plugins/engine/components/MonthYearField.ts +8 -8
  206. package/src/server/plugins/engine/components/MultilineTextField.ts +4 -4
  207. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +2 -2
  208. package/src/server/plugins/engine/components/NumberField.ts +3 -3
  209. package/src/server/plugins/engine/components/OsGridRefField.ts +2 -2
  210. package/src/server/plugins/engine/components/PaymentField.ts +8 -8
  211. package/src/server/plugins/engine/components/RadiosField.ts +1 -1
  212. package/src/server/plugins/engine/components/SelectField.ts +2 -2
  213. package/src/server/plugins/engine/components/SelectionControlField.ts +4 -4
  214. package/src/server/plugins/engine/components/TelephoneNumberField.ts +4 -4
  215. package/src/server/plugins/engine/components/TextField.ts +3 -3
  216. package/src/server/plugins/engine/components/UkAddressField.ts +7 -7
  217. package/src/server/plugins/engine/components/YesNoField.ts +5 -5
  218. package/src/server/plugins/engine/components/helpers/__stubs__/geospatial.ts +1 -1
  219. package/src/server/plugins/engine/components/helpers/components.ts +8 -8
  220. package/src/server/plugins/engine/components/helpers/geospatial.ts +1 -1
  221. package/src/server/plugins/engine/components/index.ts +27 -27
  222. package/src/server/plugins/engine/components/types.ts +1 -1
  223. package/src/server/plugins/engine/configureEnginePlugin.ts +10 -10
  224. package/src/server/plugins/engine/date-helper.ts +1 -1
  225. package/src/server/plugins/engine/helpers.ts +8 -8
  226. package/src/server/plugins/engine/index.ts +8 -8
  227. package/src/server/plugins/engine/models/FormModel.ts +15 -15
  228. package/src/server/plugins/engine/models/SummaryViewModel.ts +10 -10
  229. package/src/server/plugins/engine/models/index.ts +2 -2
  230. package/src/server/plugins/engine/models/types.ts +4 -4
  231. package/src/server/plugins/engine/options.js +3 -3
  232. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +6 -6
  233. package/src/server/plugins/engine/outputFormatters/human/v1.ts +9 -9
  234. package/src/server/plugins/engine/outputFormatters/index.ts +8 -8
  235. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +7 -7
  236. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +6 -6
  237. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +9 -9
  238. package/src/server/plugins/engine/pageControllers/PageController.ts +7 -7
  239. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +13 -13
  240. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +6 -6
  241. package/src/server/plugins/engine/pageControllers/StartPageController.ts +3 -3
  242. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +5 -5
  243. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +12 -12
  244. package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +3 -3
  245. package/src/server/plugins/engine/pageControllers/__stubs__/request.ts +3 -3
  246. package/src/server/plugins/engine/pageControllers/__stubs__/server.ts +2 -2
  247. package/src/server/plugins/engine/pageControllers/errors.ts +1 -1
  248. package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -2
  249. package/src/server/plugins/engine/pageControllers/helpers/state.ts +9 -9
  250. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +5 -5
  251. package/src/server/plugins/engine/pageControllers/index.ts +7 -7
  252. package/src/server/plugins/engine/pageControllers/validationOptions.ts +1 -1
  253. package/src/server/plugins/engine/plugin.ts +14 -14
  254. package/src/server/plugins/engine/routes/file-upload.ts +2 -2
  255. package/src/server/plugins/engine/routes/index.ts +10 -10
  256. package/src/server/plugins/engine/routes/payment-helper.js +4 -4
  257. package/src/server/plugins/engine/routes/payment.js +9 -9
  258. package/src/server/plugins/engine/routes/questions.ts +10 -10
  259. package/src/server/plugins/engine/routes/repeaters/item-delete.ts +6 -6
  260. package/src/server/plugins/engine/routes/repeaters/summary.ts +5 -5
  261. package/src/server/plugins/engine/services/formSubmissionService.js +2 -2
  262. package/src/server/plugins/engine/services/index.js +3 -3
  263. package/src/server/plugins/engine/services/localFormsService.js +2 -2
  264. package/src/server/plugins/engine/services/notifyService.ts +9 -9
  265. package/src/server/plugins/engine/services/uploadService.js +3 -3
  266. package/src/server/plugins/engine/types/index.ts +10 -10
  267. package/src/server/plugins/engine/types/schema.ts +2 -2
  268. package/src/server/plugins/engine/types.ts +22 -17
  269. package/src/server/plugins/engine/validationHelpers.ts +3 -3
  270. package/src/server/plugins/engine/vision.ts +3 -3
  271. package/src/server/plugins/map/index.js +2 -2
  272. package/src/server/plugins/map/routes/get-os-token.js +15 -3
  273. package/src/server/plugins/map/routes/index.js +7 -5
  274. package/src/server/plugins/map/service.js +7 -4
  275. package/src/server/plugins/map/test/__stubs__/find.js +1 -1
  276. package/src/server/plugins/nunjucks/context.js +5 -5
  277. package/src/server/plugins/nunjucks/environment.js +6 -6
  278. package/src/server/plugins/nunjucks/filters/answer.js +3 -3
  279. package/src/server/plugins/nunjucks/filters/evaluate.js +2 -2
  280. package/src/server/plugins/nunjucks/filters/field.js +1 -1
  281. package/src/server/plugins/nunjucks/filters/href.js +2 -2
  282. package/src/server/plugins/nunjucks/filters/index.js +8 -8
  283. package/src/server/plugins/nunjucks/filters/page.js +1 -1
  284. package/src/server/plugins/nunjucks/index.js +3 -3
  285. package/src/server/plugins/nunjucks/plugin.js +3 -3
  286. package/src/server/plugins/nunjucks/render.js +2 -2
  287. package/src/server/plugins/nunjucks/types.js +1 -1
  288. package/src/server/plugins/payment/helper.js +2 -2
  289. package/src/server/plugins/payment/service.js +4 -4
  290. package/src/server/plugins/postcode-lookup/index.js +2 -2
  291. package/src/server/plugins/postcode-lookup/models/index.js +3 -3
  292. package/src/server/plugins/postcode-lookup/routes/index.js +24 -14
  293. package/src/server/plugins/postcode-lookup/service.js +7 -4
  294. package/src/server/plugins/postcode-lookup/types.js +1 -1
  295. package/src/server/plugins/session.ts +1 -1
  296. package/src/server/routes/index.ts +2 -2
  297. package/src/server/routes/public.ts +1 -1
  298. package/src/server/routes/types.ts +1 -1
  299. package/src/server/schemas/index.ts +2 -2
  300. package/src/server/secure-context.js +1 -1
  301. package/src/server/services/cacheService.ts +13 -18
  302. package/src/server/services/httpService.ts +1 -1
  303. package/src/server/services/index.ts +1 -1
  304. package/src/server/types.ts +7 -7
  305. package/src/server/utils/notify.ts +2 -2
  306. package/src/server/utils/utils.js +1 -1
  307. package/src/typings/hapi/index.d.ts +4 -4
  308. package/src/typings/joi/index.d.ts +1 -1
  309. package/src/server/common/helpers/logging/logger-options.test.ts +0 -50
  310. package/src/server/index.test.ts +0 -644
  311. package/src/server/plugins/engine/beta/form-context.test.ts +0 -373
  312. package/src/server/plugins/engine/components/AutocompleteField.test.ts +0 -362
  313. package/src/server/plugins/engine/components/CheckboxesField.test.ts +0 -486
  314. package/src/server/plugins/engine/components/DatePartsField.test.ts +0 -927
  315. package/src/server/plugins/engine/components/DeclarationField.test.ts +0 -560
  316. package/src/server/plugins/engine/components/Details.test.ts +0 -49
  317. package/src/server/plugins/engine/components/EastingNorthingField.test.ts +0 -727
  318. package/src/server/plugins/engine/components/EmailAddressField.test.ts +0 -445
  319. package/src/server/plugins/engine/components/FileUploadField.test.ts +0 -1079
  320. package/src/server/plugins/engine/components/GeospatialField.test.ts +0 -380
  321. package/src/server/plugins/engine/components/HiddenField.test.ts +0 -188
  322. package/src/server/plugins/engine/components/Html.test.ts +0 -48
  323. package/src/server/plugins/engine/components/InsetText.test.ts +0 -48
  324. package/src/server/plugins/engine/components/LatLongField.test.ts +0 -898
  325. package/src/server/plugins/engine/components/List.test.ts +0 -79
  326. package/src/server/plugins/engine/components/LocationFieldBase.test.ts +0 -253
  327. package/src/server/plugins/engine/components/LocationFieldHelpers.test.ts +0 -743
  328. package/src/server/plugins/engine/components/Markdown.test.ts +0 -48
  329. package/src/server/plugins/engine/components/MonthYearField.test.ts +0 -617
  330. package/src/server/plugins/engine/components/MultilineTextField.test.ts +0 -647
  331. package/src/server/plugins/engine/components/NationalGridFieldNumberField.test.ts +0 -449
  332. package/src/server/plugins/engine/components/NumberField.test.ts +0 -723
  333. package/src/server/plugins/engine/components/OsGridRefField.test.ts +0 -460
  334. package/src/server/plugins/engine/components/PaymentField.test.ts +0 -745
  335. package/src/server/plugins/engine/components/RadiosField.test.ts +0 -297
  336. package/src/server/plugins/engine/components/SelectField.test.ts +0 -289
  337. package/src/server/plugins/engine/components/TelephoneNumberField.test.ts +0 -384
  338. package/src/server/plugins/engine/components/TextField.test.ts +0 -521
  339. package/src/server/plugins/engine/components/UkAddressField.test.ts +0 -806
  340. package/src/server/plugins/engine/components/YesNoField.test.ts +0 -256
  341. package/src/server/plugins/engine/components/helpers/components.test.ts +0 -399
  342. package/src/server/plugins/engine/components/helpers/geospatial.test.js +0 -55
  343. package/src/server/plugins/engine/components/helpers/helpers.test.ts +0 -219
  344. package/src/server/plugins/engine/date-helper.test.ts +0 -47
  345. package/src/server/plugins/engine/helpers.test.ts +0 -868
  346. package/src/server/plugins/engine/models/FormModel.test.ts +0 -725
  347. package/src/server/plugins/engine/models/SummaryViewModel.test.ts +0 -472
  348. package/src/server/plugins/engine/options.test.js +0 -63
  349. package/src/server/plugins/engine/outputFormatters/adapter/v1.location.test.ts +0 -356
  350. package/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts +0 -871
  351. package/src/server/plugins/engine/outputFormatters/human/v1.payment.test.ts +0 -147
  352. package/src/server/plugins/engine/outputFormatters/human/v1.test.ts +0 -145
  353. package/src/server/plugins/engine/outputFormatters/index.test.ts +0 -17
  354. package/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +0 -268
  355. package/src/server/plugins/engine/outputFormatters/machine/v2.location.test.ts +0 -341
  356. package/src/server/plugins/engine/outputFormatters/machine/v2.payment.test.ts +0 -115
  357. package/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +0 -311
  358. package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +0 -1372
  359. package/src/server/plugins/engine/pageControllers/PageController.test.ts +0 -246
  360. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +0 -1686
  361. package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +0 -279
  362. package/src/server/plugins/engine/pageControllers/StartPageController.test.ts +0 -32
  363. package/src/server/plugins/engine/pageControllers/StatusPageController.test.ts +0 -32
  364. package/src/server/plugins/engine/pageControllers/SummaryPageController.test.ts +0 -89
  365. package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +0 -37
  366. package/src/server/plugins/engine/pageControllers/errors.test.ts +0 -78
  367. package/src/server/plugins/engine/pageControllers/helpers/helpers.test.ts +0 -182
  368. package/src/server/plugins/engine/pageControllers/helpers/state.test.ts +0 -359
  369. package/src/server/plugins/engine/pageControllers/helpers/submission.test.ts +0 -373
  370. package/src/server/plugins/engine/referenceNumbers.test.ts +0 -74
  371. package/src/server/plugins/engine/routes/index.test.ts +0 -332
  372. package/src/server/plugins/engine/routes/payment-helper.test.js +0 -136
  373. package/src/server/plugins/engine/routes/payment.test.js +0 -180
  374. package/src/server/plugins/engine/routes/questions.test.ts +0 -502
  375. package/src/server/plugins/engine/routes/repeaters/item-delete.test.ts +0 -83
  376. package/src/server/plugins/engine/routes/repeaters/summary.test.ts +0 -75
  377. package/src/server/plugins/engine/services/formsService.test.js +0 -26
  378. package/src/server/plugins/engine/services/notifyService.test.ts +0 -310
  379. package/src/server/plugins/engine/types/schema.test.ts +0 -234
  380. package/src/server/plugins/engine/views/components/service-banner/template.test.js +0 -43
  381. package/src/server/plugins/engine/views/components/tag-env/template.test.js +0 -28
  382. package/src/server/plugins/engine/views/partials/preview-banner.test.js +0 -122
  383. package/src/server/plugins/map/routes/get-os-token.test.js +0 -55
  384. package/src/server/plugins/map/service.test.js +0 -144
  385. package/src/server/plugins/nunjucks/context.test.js +0 -109
  386. package/src/server/plugins/nunjucks/enviroment.test.js +0 -207
  387. package/src/server/plugins/nunjucks/filters/answer.test.js +0 -92
  388. package/src/server/plugins/nunjucks/filters/field.test.js +0 -75
  389. package/src/server/plugins/nunjucks/filters/href.test.js +0 -80
  390. package/src/server/plugins/nunjucks/filters/merge.test.js +0 -15
  391. package/src/server/plugins/nunjucks/filters/page.test.js +0 -65
  392. package/src/server/plugins/payment/helper.test.js +0 -29
  393. package/src/server/plugins/payment/service.test.js +0 -218
  394. package/src/server/plugins/postcode-lookup/service.test.js +0 -177
  395. package/src/server/postcode-lookup.test.ts +0 -64
  396. package/src/server/routes/dummy-api.test.ts +0 -97
  397. package/src/server/services/cacheService.test.ts +0 -308
  398. package/src/server/services/httpService.test.js +0 -491
  399. package/src/server/utils/file-form-service.test.js +0 -127
  400. package/src/server/utils/notify.test.ts +0 -37
  401. package/src/server/utils/secure-context/get-trust-store-certs.test.js +0 -19
  402. package/src/server/utils/utils.test.js +0 -69
@@ -1,1079 +0,0 @@
1
- import {
2
- ComponentType,
3
- type FileUploadFieldComponent,
4
- type FormMetadata
5
- } from '@defra/forms-model'
6
- import Boom from '@hapi/boom'
7
-
8
- import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'
9
- import {
10
- FileUploadField,
11
- tempItemSchema
12
- } from '~/src/server/plugins/engine/components/FileUploadField.js'
13
- import {
14
- getAnswer,
15
- type Field
16
- } from '~/src/server/plugins/engine/components/helpers/components.js'
17
- import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
18
- import { InvalidComponentStateError } from '~/src/server/plugins/engine/pageControllers/errors.js'
19
- import {
20
- createPage,
21
- type PageControllerClass
22
- } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js'
23
- import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'
24
- import { type Services } from '~/src/server/plugins/engine/types/index.js'
25
- import {
26
- FileStatus,
27
- UploadStatus,
28
- type FormContext,
29
- type UploadState
30
- } from '~/src/server/plugins/engine/types.js'
31
- import { type FormRequestPayload } from '~/src/server/routes/types.js'
32
- import definition from '~/test/form/definitions/file-upload-basic.js'
33
- import { getFormData, getFormState } from '~/test/helpers/component-helpers.js'
34
-
35
- describe('FileUploadField', () => {
36
- let model: FormModel
37
-
38
- const validTempState: UploadState = [
39
- {
40
- uploadId: '3075efea-e5de-476f-a0bf-9ae7ef56ca69',
41
- status: {
42
- uploadStatus: UploadStatus.pending,
43
- metadata: {
44
- retrievalKey: 'enrique.chase@defra.gov.uk'
45
- },
46
- form: {
47
- file: {
48
- fileId: 'fcb4f0f8-6862-4836-86dc-f56ff900b0ff',
49
- filename: 'SampleJPGImage_30mbmb.jpg',
50
- fileStatus: FileStatus.pending,
51
- contentLength: 30789588,
52
- errorMessage: 'The selected file has not fully uploaded'
53
- }
54
- },
55
- numberOfRejectedFiles: 0
56
- }
57
- },
58
- {
59
- uploadId: 'c7e8c8f1-fa5b-4587-966a-96066c6356bb',
60
- status: {
61
- uploadStatus: UploadStatus.ready,
62
- metadata: {
63
- retrievalKey: 'enrique.chase@defra.gov.uk'
64
- },
65
- form: {
66
- file: {
67
- fileId: 'e1d6cf98-35a7-4f97-8a28-cdd2b115d8fa',
68
- filename: 'virus.txt',
69
- fileStatus: FileStatus.rejected,
70
- contentLength: 9662,
71
- errorMessage: 'The selected file contains a virus'
72
- }
73
- },
74
- numberOfRejectedFiles: 1
75
- }
76
- },
77
- {
78
- uploadId: 'ec9f9b26-76c6-4ede-8aaa-3d4e02fe9984',
79
- status: {
80
- uploadStatus: UploadStatus.ready,
81
- metadata: {
82
- retrievalKey: 'enrique.chase@defra.gov.uk'
83
- },
84
- form: {
85
- file: {
86
- fileId: '71fb359c-dee7-4c2e-8701-239eb892765a',
87
- filename: 'SampleJPGImage_20mbmb.jpg',
88
- fileStatus: FileStatus.complete,
89
- contentLength: 21348301
90
- }
91
- },
92
- numberOfRejectedFiles: 0
93
- }
94
- }
95
- ]
96
-
97
- const validState: UploadState = [
98
- {
99
- uploadId: '3075efea-e5de-476f-a0bf-9ae7ef56ca69',
100
- status: {
101
- uploadStatus: UploadStatus.ready,
102
- metadata: {
103
- retrievalKey: 'enrique.chase@defra.gov.uk'
104
- },
105
- form: {
106
- file: {
107
- fileId: 'fcb4f0f8-6862-4836-86dc-f56ff900b0ff',
108
- filename: 'SampleJPGImage_30mbmb.jpg',
109
- fileStatus: FileStatus.complete,
110
- contentLength: 30789588
111
- }
112
- },
113
- numberOfRejectedFiles: 0
114
- }
115
- },
116
- {
117
- uploadId: 'c7e8c8f1-fa5b-4587-966a-96066c6356bb',
118
- status: {
119
- uploadStatus: UploadStatus.ready,
120
- metadata: {
121
- retrievalKey: 'enrique.chase@defra.gov.uk'
122
- },
123
- form: {
124
- file: {
125
- fileId: 'e1d6cf98-35a7-4f97-8a28-cdd2b115d8fa',
126
- filename: 'error-messages.txt',
127
- fileStatus: FileStatus.complete,
128
- contentLength: 9662
129
- }
130
- },
131
- numberOfRejectedFiles: 0
132
- }
133
- },
134
- {
135
- uploadId: 'ec9f9b26-76c6-4ede-8aaa-3d4e02fe9984',
136
- status: {
137
- uploadStatus: UploadStatus.ready,
138
- metadata: {
139
- retrievalKey: 'enrique.chase@defra.gov.uk'
140
- },
141
- form: {
142
- file: {
143
- fileId: '71fb359c-dee7-4c2e-8701-239eb892765a',
144
- filename: 'SampleJPGImage_20mbmb.jpg',
145
- fileStatus: FileStatus.complete,
146
- contentLength: 21348301
147
- }
148
- },
149
- numberOfRejectedFiles: 0
150
- }
151
- }
152
- ]
153
-
154
- beforeEach(() => {
155
- model = new FormModel(definition, {
156
- basePath: 'test'
157
- })
158
- })
159
-
160
- describe('Defaults', () => {
161
- let def: FileUploadFieldComponent
162
- let page: PageControllerClass
163
- let collection: ComponentCollection
164
- let field: Field
165
-
166
- beforeEach(() => {
167
- def = {
168
- title: 'Example file upload field',
169
- shortDescription: 'Example file upload',
170
- name: 'myComponent',
171
- type: ComponentType.FileUploadField,
172
- options: {},
173
- schema: {}
174
- } satisfies FileUploadFieldComponent
175
-
176
- page = createPage(model, definition.pages[0])
177
- collection = new ComponentCollection([def], { page, model })
178
- field = collection.fields[0]
179
- })
180
-
181
- describe('Schema', () => {
182
- it('uses component short description as label', () => {
183
- const { formSchema } = collection
184
- const { keys } = formSchema.describe()
185
-
186
- expect(keys).toHaveProperty(
187
- 'myComponent',
188
- expect.objectContaining({
189
- flags: expect.objectContaining({
190
- label: 'Example file upload'
191
- })
192
- })
193
- )
194
- })
195
-
196
- it('uses component title as label', () => {
197
- def = {
198
- title: 'Example file upload field',
199
- name: 'myComponent',
200
- type: ComponentType.FileUploadField,
201
- options: {},
202
- schema: {}
203
- } satisfies FileUploadFieldComponent
204
-
205
- page = createPage(model, definition.pages[0])
206
- collection = new ComponentCollection([def], { page, model })
207
-
208
- const { formSchema } = collection
209
- const { keys } = formSchema.describe()
210
-
211
- expect(keys).toHaveProperty(
212
- 'myComponent',
213
- expect.objectContaining({
214
- flags: expect.objectContaining({
215
- label: 'Example file upload field'
216
- })
217
- })
218
- )
219
- })
220
-
221
- it('uses component name as keys', () => {
222
- const { formSchema } = collection
223
- const { keys } = formSchema.describe()
224
-
225
- expect(field.keys).toEqual(['myComponent'])
226
- expect(field.collection).toBeUndefined()
227
-
228
- for (const key of field.keys) {
229
- expect(keys).toHaveProperty(key)
230
- }
231
- })
232
-
233
- it('is required by default', () => {
234
- const { formSchema } = collection
235
- const { keys } = formSchema.describe()
236
-
237
- expect(keys).toHaveProperty(
238
- 'myComponent',
239
- expect.objectContaining({
240
- flags: expect.objectContaining({
241
- presence: 'required'
242
- })
243
- })
244
- )
245
- })
246
-
247
- it('is optional when configured', () => {
248
- const collectionOptional = new ComponentCollection(
249
- [{ ...def, options: { required: false } }],
250
- { model }
251
- )
252
-
253
- const { formSchema } = collectionOptional
254
- const { keys } = formSchema.describe()
255
-
256
- expect(keys).toHaveProperty(
257
- 'myComponent',
258
- expect.objectContaining({
259
- flags: expect.objectContaining({
260
- presence: 'optional'
261
- })
262
- })
263
- )
264
-
265
- const result = collectionOptional.validate(getFormData())
266
- expect(result.errors).toBeUndefined()
267
- })
268
-
269
- it('accepts valid values', () => {
270
- const result1 = collection.validate(getFormData(validState))
271
- const result2 = tempItemSchema.validate(validTempState[0], opts)
272
- const result3 = tempItemSchema.validate(validTempState[1], opts)
273
- const result4 = tempItemSchema.validate(validTempState[2], opts)
274
-
275
- expect(result1.errors).toBeUndefined()
276
- expect(result2.error).toBeUndefined()
277
- expect(result3.error).toBeUndefined()
278
- expect(result4.error).toBeUndefined()
279
- })
280
-
281
- it('adds errors for empty value', () => {
282
- const result = collection.validate(getFormData())
283
-
284
- expect(result.errors).toEqual([
285
- expect.objectContaining({
286
- text: 'Select example file upload'
287
- })
288
- ])
289
- })
290
-
291
- it('adds errors for empty value with no shortDescription', () => {
292
- def = {
293
- title: 'Example file upload field',
294
- name: 'myComponent',
295
- type: ComponentType.FileUploadField,
296
- options: {},
297
- schema: {}
298
- } satisfies FileUploadFieldComponent
299
-
300
- collection = new ComponentCollection([def], { model })
301
- const result = collection.validate(getFormData())
302
-
303
- expect(result.errors).toEqual([
304
- expect.objectContaining({
305
- text: 'Select example file upload field'
306
- })
307
- ])
308
- })
309
-
310
- it('adds errors for invalid values', () => {
311
- const result1 = collection.validate(getFormData(['invalid']))
312
- const result2 = collection.validate(
313
- // @ts-expect-error - Allow invalid param for test
314
- getFormData({ unknown: 'invalid' })
315
- )
316
-
317
- expect(result1.errors).toBeTruthy()
318
- expect(result2.errors).toBeTruthy()
319
- })
320
- })
321
-
322
- describe('State', () => {
323
- it('returns text from state', () => {
324
- const state1 = getFormState(validState)
325
- const state2 = getFormState(null)
326
-
327
- const answer1 = getAnswer(field, state1)
328
- const answer2 = getAnswer(field, state2)
329
-
330
- expect(answer1).toBe('Uploaded 3 files')
331
- expect(answer2).toBe('')
332
- })
333
-
334
- it('returns payload from state', () => {
335
- const state1 = getFormState(validState)
336
- const state2 = getFormState(null)
337
-
338
- const payload1 = field.getFormDataFromState(state1)
339
- const payload2 = field.getFormDataFromState(state2)
340
-
341
- expect(payload1).toEqual(getFormData(validState))
342
- expect(payload2).toEqual(getFormData())
343
- })
344
-
345
- it('returns value from state', () => {
346
- const state1 = getFormState(validState)
347
- const state2 = getFormState(null)
348
-
349
- const value1 = field.getFormValueFromState(state1)
350
- const value2 = field.getFormValueFromState(state2)
351
-
352
- expect(value1).toBe(validState)
353
- expect(value2).toBeUndefined()
354
- })
355
-
356
- it('returns context for conditions and form submission', () => {
357
- const state1 = getFormState(validState)
358
- const state2 = getFormState(null)
359
-
360
- const value1 = field.getContextValueFromState(state1)
361
- const value2 = field.getContextValueFromState(state2)
362
-
363
- const { file: file1 } = validState[0].status.form
364
- const { file: file2 } = validState[1].status.form
365
- const { file: file3 } = validState[2].status.form
366
-
367
- expect(value1).toEqual([file1.fileId, file2.fileId, file3.fileId])
368
- expect(value2).toBeNull()
369
- })
370
-
371
- it('returns state from payload', () => {
372
- const payload1 = getFormData(validState)
373
- const payload2 = getFormData()
374
-
375
- const value1 = field.getStateFromValidForm(payload1)
376
- const value2 = field.getStateFromValidForm(payload2)
377
-
378
- expect(value1).toEqual(getFormState(validState))
379
- expect(value2).toEqual(getFormState(null))
380
- })
381
- })
382
-
383
- describe('View model', () => {
384
- it('sets Nunjucks component defaults', () => {
385
- const viewModel = field.getViewModel(getFormData(validState))
386
-
387
- expect(viewModel).toEqual(
388
- expect.objectContaining({
389
- label: { text: def.title },
390
- name: 'file', // hardcoded to 'file' for CDP
391
- id: 'myComponent',
392
- value: '', // input type=file can't have a default value
393
- upload: {
394
- count: 3,
395
- summaryList: {
396
- classes: 'govuk-summary-list--long-key',
397
- rows: [
398
- {
399
- key: {
400
- html: expect.stringContaining('SampleJPGImage_30mbmb.jpg')
401
- },
402
- value: {
403
- html: expect.stringContaining('Uploaded')
404
- },
405
- actions: {
406
- items: [
407
- {
408
- href: `/test/file-upload-component/${validState[0].status.form.file.fileId}/confirm-delete`,
409
- text: 'Remove',
410
- attributes: { id: 'myComponent__0' },
411
- classes: 'govuk-link--no-visited-state',
412
- visuallyHiddenText: 'SampleJPGImage_30mbmb.jpg'
413
- }
414
- ]
415
- }
416
- },
417
- {
418
- key: {
419
- html: expect.stringContaining('error-messages.txt')
420
- },
421
- value: {
422
- html: expect.stringContaining('Uploaded')
423
- },
424
- actions: {
425
- items: [
426
- {
427
- href: `/test/file-upload-component/${validState[1].status.form.file.fileId}/confirm-delete`,
428
- text: 'Remove',
429
- attributes: { id: 'myComponent__1' },
430
- classes: 'govuk-link--no-visited-state',
431
- visuallyHiddenText: 'error-messages.txt'
432
- }
433
- ]
434
- }
435
- },
436
- {
437
- key: {
438
- html: expect.stringContaining('SampleJPGImage_20mbmb.jpg')
439
- },
440
- value: {
441
- html: expect.stringContaining('Uploaded')
442
- },
443
- actions: {
444
- items: [
445
- {
446
- href: `/test/file-upload-component/${validState[2].status.form.file.fileId}/confirm-delete`,
447
- text: 'Remove',
448
- attributes: { id: 'myComponent__2' },
449
- classes: 'govuk-link--no-visited-state',
450
- visuallyHiddenText: 'SampleJPGImage_20mbmb.jpg'
451
- }
452
- ]
453
- }
454
- }
455
- ]
456
- }
457
- },
458
- multiple: true
459
- })
460
- )
461
- })
462
-
463
- it('sets Nunjucks component defaults (preview URL direct access)', () => {
464
- const viewModel = field.getViewModel(
465
- getFormData(validState),
466
- undefined,
467
-
468
- // Preview URL '?force'
469
- { force: '' }
470
- )
471
-
472
- expect(viewModel).toEqual(
473
- expect.objectContaining({
474
- label: { text: def.title },
475
- name: 'file', // hardcoded to 'file' for CDP
476
- id: 'myComponent',
477
- value: '', // input type=file can't have a default value
478
- upload: {
479
- count: 3,
480
- summaryList: {
481
- classes: 'govuk-summary-list--long-key',
482
- rows: [
483
- {
484
- key: {
485
- html: expect.stringContaining('SampleJPGImage_30mbmb.jpg')
486
- },
487
- value: {
488
- html: expect.stringContaining('Uploaded')
489
- },
490
- actions: {
491
- items: []
492
- }
493
- },
494
- {
495
- key: {
496
- html: expect.stringContaining('error-messages.txt')
497
- },
498
- value: {
499
- html: expect.stringContaining('Uploaded')
500
- },
501
- actions: {
502
- items: []
503
- }
504
- },
505
- {
506
- key: {
507
- html: expect.stringContaining('SampleJPGImage_20mbmb.jpg')
508
- },
509
- value: {
510
- html: expect.stringContaining('Uploaded')
511
- },
512
- actions: {
513
- items: []
514
- }
515
- }
516
- ]
517
- }
518
- }
519
- })
520
- )
521
- })
522
-
523
- it('sets Nunjucks component defaults with temp valid state', () => {
524
- const viewModel = field.getViewModel(getFormData(validTempState))
525
-
526
- expect(viewModel).toEqual(
527
- expect.objectContaining({
528
- label: { text: def.title },
529
- name: 'file', // hardcoded to 'file' for CDP
530
- id: 'myComponent',
531
- value: '', // input type=file can't have a default value
532
- upload: {
533
- count: 1,
534
- summaryList: {
535
- classes: 'govuk-summary-list--long-key',
536
- rows: [
537
- {
538
- key: {
539
- html: expect.stringContaining('SampleJPGImage_20mbmb.jpg')
540
- },
541
- value: {
542
- html: expect.stringContaining('Uploaded')
543
- },
544
- actions: {
545
- items: [
546
- {
547
- href: `/test/file-upload-component/${validState[2].status.form.file.fileId}/confirm-delete`,
548
- text: 'Remove',
549
- attributes: { id: 'myComponent__0' },
550
- classes: 'govuk-link--no-visited-state',
551
- visuallyHiddenText: 'SampleJPGImage_20mbmb.jpg'
552
- }
553
- ]
554
- }
555
- }
556
- ]
557
- }
558
- },
559
- multiple: true
560
- })
561
- )
562
- })
563
-
564
- it('sets Nunjucks component defaults with temp valid state with errors (on POST)', () => {
565
- const viewModel = field.getViewModel(getFormData(validTempState), [])
566
-
567
- expect(viewModel).toEqual(
568
- expect.objectContaining({
569
- label: { text: def.title },
570
- name: 'file', // hardcoded to 'file' for CDP
571
- id: 'myComponent',
572
- value: '', // input type=file can't have a default value
573
- upload: {
574
- count: 1,
575
- summaryList: {
576
- classes: 'govuk-summary-list--long-key',
577
- rows: [
578
- {
579
- key: {
580
- html: expect.stringContaining('SampleJPGImage_20mbmb.jpg')
581
- },
582
- value: {
583
- html: expect.stringContaining('Uploaded')
584
- },
585
- actions: {
586
- items: [
587
- {
588
- href: `/test/file-upload-component/${validState[2].status.form.file.fileId}/confirm-delete`,
589
- text: 'Remove',
590
- attributes: { id: 'myComponent__0' },
591
- classes: 'govuk-link--no-visited-state',
592
- visuallyHiddenText: 'SampleJPGImage_20mbmb.jpg'
593
- }
594
- ]
595
- }
596
- }
597
- ]
598
- }
599
- },
600
- multiple: true
601
- })
602
- )
603
- })
604
- })
605
-
606
- describe('AllPossibleErrors', () => {
607
- it('should return errors', () => {
608
- const errors = field.getAllPossibleErrors()
609
- expect(errors.baseErrors).not.toBeEmpty()
610
- expect(errors.advancedSettingsErrors).not.toBeEmpty()
611
- })
612
- })
613
- })
614
-
615
- describe('Validation', () => {
616
- describe.each([
617
- {
618
- description: 'Schema min and max',
619
- component: {
620
- title: 'Example file upload field',
621
- name: 'myComponent',
622
- type: ComponentType.FileUploadField,
623
- options: {},
624
- schema: {
625
- min: 1,
626
- max: 2
627
- }
628
- } satisfies FileUploadFieldComponent,
629
- assertions: [
630
- {
631
- input: getFormData([]),
632
- output: {
633
- value: getFormData([]),
634
- errors: [
635
- expect.objectContaining({
636
- text: 'Example file upload field must contain at least 1 items'
637
- })
638
- ]
639
- }
640
- },
641
- {
642
- input: getFormData(validState),
643
- output: {
644
- value: getFormData(validState),
645
- errors: [
646
- expect.objectContaining({
647
- text: 'Example file upload field must contain less than or equal to 2 items'
648
- })
649
- ]
650
- }
651
- }
652
- ]
653
- },
654
- {
655
- description: 'Schema default min',
656
- component: {
657
- title: 'Example file upload field',
658
- name: 'myComponent',
659
- type: ComponentType.FileUploadField,
660
- options: {},
661
- schema: {}
662
- } satisfies FileUploadFieldComponent,
663
- assertions: [
664
- {
665
- input: getFormData([]),
666
- output: {
667
- value: getFormData([]),
668
- errors: [
669
- expect.objectContaining({
670
- text: 'Example file upload field must contain at least 1 items'
671
- })
672
- ]
673
- }
674
- }
675
- ]
676
- },
677
- {
678
- description: 'Schema length',
679
- component: {
680
- title: 'Example file upload field',
681
- name: 'myComponent',
682
- type: ComponentType.FileUploadField,
683
- options: {},
684
- schema: {
685
- length: 4
686
- }
687
- } satisfies FileUploadFieldComponent,
688
- assertions: [
689
- {
690
- input: getFormData([]),
691
- output: {
692
- value: getFormData([]),
693
- errors: [
694
- expect.objectContaining({
695
- text: 'Example file upload field must contain 4 items'
696
- })
697
- ]
698
- }
699
- },
700
- {
701
- input: getFormData(validState),
702
- output: {
703
- value: getFormData(validState),
704
- errors: [
705
- expect.objectContaining({
706
- text: 'Example file upload field must contain 4 items'
707
- })
708
- ]
709
- }
710
- },
711
- {
712
- input: getFormData([...validState, ...validState]),
713
- output: {
714
- value: getFormData([...validState, ...validState]),
715
- errors: [
716
- expect.objectContaining({
717
- text: 'Example file upload field must contain 4 items'
718
- })
719
- ]
720
- }
721
- }
722
- ]
723
- },
724
- {
725
- description: 'Optional',
726
- component: {
727
- title: 'Example file upload field',
728
- name: 'myComponent',
729
- type: ComponentType.FileUploadField,
730
- options: {
731
- required: false
732
- },
733
- schema: {}
734
- } satisfies FileUploadFieldComponent,
735
- assertions: [
736
- {
737
- input: getFormData([]),
738
- output: {
739
- value: getFormData([])
740
- }
741
- },
742
- {
743
- input: getFormData(),
744
- output: {
745
- value: getFormData()
746
- }
747
- }
748
- ]
749
- },
750
- {
751
- description: 'Optional schema min and max',
752
- component: {
753
- title: 'Example file upload field',
754
- name: 'myComponent',
755
- type: ComponentType.FileUploadField,
756
- options: {
757
- required: false
758
- },
759
- schema: {
760
- min: 1,
761
- max: 2
762
- }
763
- } satisfies FileUploadFieldComponent,
764
- assertions: [
765
- {
766
- input: getFormData(),
767
- output: {
768
- value: getFormData()
769
- }
770
- },
771
- {
772
- input: getFormData([]),
773
- output: {
774
- value: getFormData([]),
775
- errors: [
776
- expect.objectContaining({
777
- text: 'Example file upload field must contain at least 1 items'
778
- })
779
- ]
780
- }
781
- },
782
- {
783
- input: getFormData(validState),
784
- output: {
785
- value: getFormData(validState),
786
- errors: [
787
- expect.objectContaining({
788
- text: 'Example file upload field must contain less than or equal to 2 items'
789
- })
790
- ]
791
- }
792
- }
793
- ]
794
- },
795
- {
796
- description: 'Optional schema length',
797
- component: {
798
- title: 'Example file upload field',
799
- name: 'myComponent',
800
- type: ComponentType.FileUploadField,
801
- options: {
802
- required: false
803
- },
804
- schema: {
805
- length: 4
806
- }
807
- } satisfies FileUploadFieldComponent,
808
- assertions: [
809
- {
810
- input: getFormData(),
811
- output: {
812
- value: getFormData()
813
- }
814
- },
815
- {
816
- input: getFormData([]),
817
- output: {
818
- value: getFormData([]),
819
- errors: [
820
- expect.objectContaining({
821
- text: 'Example file upload field must contain 4 items'
822
- })
823
- ]
824
- }
825
- },
826
- {
827
- input: getFormData(validState),
828
- output: {
829
- value: getFormData(validState),
830
- errors: [
831
- expect.objectContaining({
832
- text: 'Example file upload field must contain 4 items'
833
- })
834
- ]
835
- }
836
- },
837
- {
838
- input: getFormData([...validState, ...validState]),
839
- output: {
840
- value: getFormData([...validState, ...validState]),
841
- errors: [
842
- expect.objectContaining({
843
- text: 'Example file upload field must contain 4 items'
844
- })
845
- ]
846
- }
847
- }
848
- ]
849
- }
850
- ])('$description', ({ component: def, assertions }) => {
851
- let collection: ComponentCollection
852
-
853
- beforeEach(() => {
854
- collection = new ComponentCollection([def], { model })
855
- })
856
-
857
- it.each([...assertions])(
858
- 'validates custom example',
859
- ({ input, output }) => {
860
- const result = collection.validate(input)
861
- expect(result).toEqual(output)
862
- }
863
- )
864
- })
865
- })
866
-
867
- describe('onSubmit', () => {
868
- let fileUploadField: FileUploadField
869
- let mockRequest: FormRequestPayload
870
- let mockMetadata: FormMetadata
871
- let mockContext: FormContext
872
- let mockPersistFiles: jest.Mock
873
-
874
- beforeEach(() => {
875
- // Create a FileUploadField instance
876
- const componentDef: FileUploadFieldComponent = {
877
- name: 'fileUpload',
878
- title: 'Upload something',
879
- type: ComponentType.FileUploadField,
880
- options: {},
881
- schema: {}
882
- }
883
-
884
- const page = model.pages.find((p) => p.path === '/file-upload-component')
885
- fileUploadField = new FileUploadField(componentDef, {
886
- model,
887
- page
888
- })
889
-
890
- // Mock persistFiles
891
- mockPersistFiles = jest.fn().mockResolvedValue(undefined)
892
-
893
- // Mock request
894
- mockRequest = {
895
- app: {
896
- model: {
897
- services: {
898
- formSubmissionService: {
899
- persistFiles: mockPersistFiles
900
- }
901
- }
902
- }
903
- }
904
- } as unknown as FormRequestPayload
905
-
906
- // Mock metadata
907
- mockMetadata = {
908
- notificationEmail: 'test@example.com'
909
- } as FormMetadata
910
-
911
- // Mock context with state
912
- mockContext = {
913
- state: {
914
- fileUpload: validState
915
- }
916
- } as unknown as FormContext
917
- })
918
-
919
- afterEach(() => {
920
- jest.clearAllMocks()
921
- })
922
-
923
- it('should successfully persist files', async () => {
924
- await fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
925
-
926
- expect(mockPersistFiles).toHaveBeenCalledTimes(1)
927
- expect(mockPersistFiles).toHaveBeenCalledWith(
928
- [
929
- {
930
- fileId: 'fcb4f0f8-6862-4836-86dc-f56ff900b0ff',
931
- initiatedRetrievalKey: 'enrique.chase@defra.gov.uk'
932
- },
933
- {
934
- fileId: 'e1d6cf98-35a7-4f97-8a28-cdd2b115d8fa',
935
- initiatedRetrievalKey: 'enrique.chase@defra.gov.uk'
936
- },
937
- {
938
- fileId: '71fb359c-dee7-4c2e-8701-239eb892765a',
939
- initiatedRetrievalKey: 'enrique.chase@defra.gov.uk'
940
- }
941
- ],
942
- 'test@example.com'
943
- )
944
- })
945
-
946
- it('should fail when notificationEmail is not set', async () => {
947
- mockMetadata.notificationEmail = undefined
948
-
949
- await expect(
950
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
951
- ).rejects.toThrow('Unexpected missing notificationEmail in metadata')
952
- })
953
-
954
- it('should fail when notificationEmail is empty string', async () => {
955
- mockMetadata.notificationEmail = ''
956
-
957
- await expect(
958
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
959
- ).rejects.toThrow('Unexpected missing notificationEmail in metadata')
960
- })
961
-
962
- it('should not call persistFiles when no files in state', async () => {
963
- mockContext.state = {}
964
-
965
- await fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
966
-
967
- expect(mockPersistFiles).not.toHaveBeenCalled()
968
- })
969
-
970
- it('should not call persistFiles when empty array in state', async () => {
971
- mockContext.state = { fileUpload: [] }
972
-
973
- await fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
974
-
975
- expect(mockPersistFiles).not.toHaveBeenCalled()
976
- })
977
-
978
- it('should throw Error when formSubmissionService is not available', async () => {
979
- if (!mockRequest.app.model) {
980
- throw new Error('Invalid test setup')
981
- }
982
-
983
- mockRequest.app.model.services = {} as unknown as Services
984
-
985
- await expect(
986
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
987
- ).rejects.toThrow('No form submission service available in app model')
988
- })
989
-
990
- it('should throw InvalidComponentStateError when persistFiles throws 403 Forbidden', async () => {
991
- const forbiddenError = Boom.forbidden('Invalid retrieval key')
992
- mockPersistFiles.mockRejectedValue(forbiddenError)
993
-
994
- await expect(
995
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
996
- ).rejects.toThrow(InvalidComponentStateError)
997
-
998
- const error = await fileUploadField
999
- .onSubmit(mockRequest, mockMetadata, mockContext)
1000
- .catch((e: unknown) => e)
1001
-
1002
- expect(error).toBeInstanceOf(InvalidComponentStateError)
1003
- expect((error as InvalidComponentStateError).component).toBe(
1004
- fileUploadField
1005
- )
1006
- expect((error as InvalidComponentStateError).userMessage).toBe(
1007
- 'There was a problem with your uploaded files. Re-upload them before submitting the form again.'
1008
- )
1009
- })
1010
-
1011
- it('should throw InvalidComponentStateError when persistFiles throws 410 Gone', async () => {
1012
- const goneError = Boom.resourceGone('File has expired')
1013
- mockPersistFiles.mockRejectedValue(goneError)
1014
-
1015
- await expect(
1016
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1017
- ).rejects.toThrow(InvalidComponentStateError)
1018
-
1019
- const error = await fileUploadField
1020
- .onSubmit(mockRequest, mockMetadata, mockContext)
1021
- .catch((e: unknown) => e)
1022
-
1023
- expect(error).toBeInstanceOf(InvalidComponentStateError)
1024
- expect((error as InvalidComponentStateError).component).toBe(
1025
- fileUploadField
1026
- )
1027
- expect((error as InvalidComponentStateError).userMessage).toBe(
1028
- 'There was a problem with your uploaded files. Re-upload them before submitting the form again.'
1029
- )
1030
- })
1031
-
1032
- it('should throw InvalidComponentStateError when persistFiles throws 404 Not Found', async () => {
1033
- const notFoundError = Boom.notFound('File not found')
1034
- mockPersistFiles.mockRejectedValue(notFoundError)
1035
-
1036
- await expect(
1037
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1038
- ).rejects.toThrow(InvalidComponentStateError)
1039
-
1040
- const error = await fileUploadField
1041
- .onSubmit(mockRequest, mockMetadata, mockContext)
1042
- .catch((e: unknown) => e)
1043
-
1044
- expect(error).toBeInstanceOf(InvalidComponentStateError)
1045
- expect((error as InvalidComponentStateError).component).toBe(
1046
- fileUploadField
1047
- )
1048
- expect((error as InvalidComponentStateError).userMessage).toBe(
1049
- 'There was a problem with your uploaded files. Re-upload them before submitting the form again.'
1050
- )
1051
- })
1052
-
1053
- it('should re-throw other Boom errors without wrapping', async () => {
1054
- const serverError = Boom.internal('Internal server error')
1055
- mockPersistFiles.mockRejectedValue(serverError)
1056
-
1057
- await expect(
1058
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1059
- ).rejects.toThrow(serverError)
1060
-
1061
- await expect(
1062
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1063
- ).rejects.not.toThrow(InvalidComponentStateError)
1064
- })
1065
-
1066
- it('should re-throw non-Boom errors without wrapping', async () => {
1067
- const genericError = new Error('Something went wrong')
1068
- mockPersistFiles.mockRejectedValue(genericError)
1069
-
1070
- await expect(
1071
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1072
- ).rejects.toThrow(genericError)
1073
-
1074
- await expect(
1075
- fileUploadField.onSubmit(mockRequest, mockMetadata, mockContext)
1076
- ).rejects.not.toThrow(InvalidComponentStateError)
1077
- })
1078
- })
1079
- })