@defra/forms-engine-plugin 4.0.24 → 4.0.26

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 (93) hide show
  1. package/.server/server/forms/components.json +2 -2
  2. package/.server/server/plugins/engine/components/DeclarationField.d.ts +2 -0
  3. package/.server/server/plugins/engine/components/DeclarationField.js +8 -1
  4. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  5. package/.server/server/plugins/engine/components/HiddenField.d.ts +21 -0
  6. package/.server/server/plugins/engine/components/HiddenField.js +50 -0
  7. package/.server/server/plugins/engine/components/HiddenField.js.map +1 -0
  8. package/.server/server/plugins/engine/components/Markdown.d.ts +2 -0
  9. package/.server/server/plugins/engine/components/Markdown.js +4 -1
  10. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  11. package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
  12. package/.server/server/plugins/engine/components/helpers/components.js +3 -0
  13. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  14. package/.server/server/plugins/engine/components/index.d.ts +1 -0
  15. package/.server/server/plugins/engine/components/index.js +1 -0
  16. package/.server/server/plugins/engine/components/index.js.map +1 -1
  17. package/.server/server/plugins/engine/helpers.js +2 -1
  18. package/.server/server/plugins/engine/helpers.js.map +1 -1
  19. package/.server/server/plugins/engine/index.js +4 -1
  20. package/.server/server/plugins/engine/index.js.map +1 -1
  21. package/.server/server/plugins/engine/models/FormModel.d.ts +2 -0
  22. package/.server/server/plugins/engine/models/FormModel.js +2 -0
  23. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  24. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +1 -1
  25. package/.server/server/plugins/engine/pageControllers/PageController.js +2 -8
  26. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  27. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +7 -0
  28. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  29. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +8 -2
  30. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  31. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +2 -1
  32. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  33. package/.server/server/plugins/engine/pageControllers/helpers/state.d.ts +11 -0
  34. package/.server/server/plugins/engine/pageControllers/helpers/state.js +66 -0
  35. package/.server/server/plugins/engine/pageControllers/helpers/state.js.map +1 -0
  36. package/.server/server/plugins/engine/routes/index.js +2 -1
  37. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  38. package/.server/server/plugins/engine/services/formsService.d.ts +6 -0
  39. package/.server/server/plugins/engine/services/formsService.js +10 -0
  40. package/.server/server/plugins/engine/services/formsService.js.map +1 -1
  41. package/.server/server/plugins/engine/services/formsService.test.js +14 -0
  42. package/.server/server/plugins/engine/services/formsService.test.js.map +1 -0
  43. package/.server/server/plugins/engine/types.d.ts +4 -0
  44. package/.server/server/plugins/engine/types.js.map +1 -1
  45. package/.server/server/plugins/engine/views/components/declarationfield.html +1 -1
  46. package/.server/server/plugins/engine/views/components/hiddenfield.html +3 -0
  47. package/.server/server/plugins/engine/views/components/markdown.html +1 -1
  48. package/.server/server/plugins/engine/views/confirmation.html +6 -1
  49. package/.server/server/plugins/engine/views/partials/form.html +9 -1
  50. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  51. package/.server/server/services/cacheService.d.ts +3 -7
  52. package/.server/server/services/cacheService.js.map +1 -1
  53. package/.server/server/types.d.ts +1 -0
  54. package/.server/server/types.js.map +1 -1
  55. package/.server/server/utils/file-form-service.d.ts +6 -0
  56. package/.server/server/utils/file-form-service.js +22 -1
  57. package/.server/server/utils/file-form-service.js.map +1 -1
  58. package/.server/server/utils/file-form-service.test.js +86 -0
  59. package/.server/server/utils/file-form-service.test.js.map +1 -0
  60. package/package.json +3 -2
  61. package/src/server/forms/components.json +2 -2
  62. package/src/server/plugins/engine/components/DeclarationField.test.ts +24 -0
  63. package/src/server/plugins/engine/components/DeclarationField.ts +20 -2
  64. package/src/server/plugins/engine/components/HiddenField.test.ts +188 -0
  65. package/src/server/plugins/engine/components/HiddenField.ts +68 -0
  66. package/src/server/plugins/engine/components/Markdown.ts +4 -1
  67. package/src/server/plugins/engine/components/helpers/components.ts +5 -0
  68. package/src/server/plugins/engine/components/helpers/helpers.test.ts +17 -0
  69. package/src/server/plugins/engine/components/index.ts +1 -0
  70. package/src/server/plugins/engine/helpers.ts +2 -1
  71. package/src/server/plugins/engine/index.ts +5 -2
  72. package/src/server/plugins/engine/models/FormModel.ts +3 -0
  73. package/src/server/plugins/engine/pageControllers/PageController.test.ts +4 -11
  74. package/src/server/plugins/engine/pageControllers/PageController.ts +1 -9
  75. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +7 -0
  76. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +9 -2
  77. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +5 -1
  78. package/src/server/plugins/engine/pageControllers/helpers/state.test.ts +221 -0
  79. package/src/server/plugins/engine/pageControllers/helpers/state.ts +93 -0
  80. package/src/server/plugins/engine/routes/index.test.ts +24 -11
  81. package/src/server/plugins/engine/routes/index.ts +1 -1
  82. package/src/server/plugins/engine/services/formsService.js +10 -0
  83. package/src/server/plugins/engine/services/formsService.test.js +21 -0
  84. package/src/server/plugins/engine/types.ts +5 -0
  85. package/src/server/plugins/engine/views/components/declarationfield.html +1 -1
  86. package/src/server/plugins/engine/views/components/hiddenfield.html +3 -0
  87. package/src/server/plugins/engine/views/components/markdown.html +1 -1
  88. package/src/server/plugins/engine/views/confirmation.html +6 -1
  89. package/src/server/plugins/engine/views/partials/form.html +9 -1
  90. package/src/server/services/cacheService.ts +3 -2
  91. package/src/server/types.ts +1 -0
  92. package/src/server/utils/file-form-service.js +27 -1
  93. package/src/server/utils/file-form-service.test.js +114 -0
@@ -6,6 +6,7 @@ import { type createServer } from '~/src/server/index.js'
6
6
  import {
7
7
  type AnyFormRequest,
8
8
  type AnyRequest,
9
+ type FormConfirmationState,
9
10
  type FormPayload,
10
11
  type FormState,
11
12
  type FormSubmissionError,
@@ -55,7 +56,7 @@ export class CacheService {
55
56
 
56
57
  async getConfirmationState(
57
58
  request: AnyFormRequest
58
- ): Promise<{ confirmed?: true }> {
59
+ ): Promise<FormConfirmationState> {
59
60
  const key = this.Key(request, ADDITIONAL_IDENTIFIER.Confirmation)
60
61
  const value = await this.cache.get(key)
61
62
 
@@ -64,7 +65,7 @@ export class CacheService {
64
65
 
65
66
  async setConfirmationState(
66
67
  request: AnyFormRequest,
67
- confirmationState: { confirmed?: true }
68
+ confirmationState: FormConfirmationState
68
69
  ) {
69
70
  const key = this.Key(request, ADDITIONAL_IDENTIFIER.Confirmation)
70
71
  const ttl = config.get('confirmationSessionTimeout')
@@ -23,6 +23,7 @@ import { type CacheService } from '~/src/server/services/cacheService.js'
23
23
 
24
24
  export interface FormsService {
25
25
  getFormMetadata: (slug: string) => Promise<FormMetadata>
26
+ getFormMetadataById: (id: string) => Promise<FormMetadata>
26
27
  getFormDefinition: (
27
28
  id: string,
28
29
  state: FormStatus
@@ -97,6 +97,23 @@ export class FileFormService {
97
97
  return metadata
98
98
  }
99
99
 
100
+ /**
101
+ * Get the form metadata by form id
102
+ * @param {string} id - the form id
103
+ * @returns {FormMetadata}
104
+ */
105
+ getFormMetadataById(id) {
106
+ const metadata = Array.from(this.#metadata.values()).find(
107
+ (form) => form.id === id
108
+ )
109
+
110
+ if (!metadata) {
111
+ throw new Error(`Form metadata id '${id}' not found`)
112
+ }
113
+
114
+ return metadata
115
+ }
116
+
100
117
  /**
101
118
  * Get the form defintion by id
102
119
  * @param {string} id - the form id
@@ -127,6 +144,15 @@ export class FileFormService {
127
144
  return Promise.resolve(this.getFormMetadata(slug))
128
145
  },
129
146
 
147
+ /**
148
+ * Get the form metadata by form id
149
+ * @param {string} id
150
+ * @returns {Promise<FormMetadata>}
151
+ */
152
+ getFormMetadataById: (id) => {
153
+ return Promise.resolve(this.getFormMetadataById(id))
154
+ },
155
+
130
156
  /**
131
157
  * Get the form defintion by id
132
158
  * @param {string} id
@@ -140,5 +166,5 @@ export class FileFormService {
140
166
  }
141
167
 
142
168
  /**
143
- * @import { FormMetadata, FormDefinition } from '@defra/forms-model'
169
+ * @import { FormMetadata, FormDefinition, FormStatus } from '@defra/forms-model'
144
170
  */
@@ -0,0 +1,114 @@
1
+ import { join } from 'node:path'
2
+
3
+ import { FormStatus } from '~/src/server/routes/types.js'
4
+ import { FileFormService } from '~/src/server/utils/file-form-service.js'
5
+
6
+ describe('File-form-service', () => {
7
+ /** @type {FileFormService} */
8
+ let service
9
+ beforeEach(async () => {
10
+ const now = new Date()
11
+ const user = { id: 'user', displayName: 'Username' }
12
+ const author = {
13
+ createdAt: now,
14
+ createdBy: user,
15
+ updatedAt: now,
16
+ updatedBy: user
17
+ }
18
+ service = new FileFormService()
19
+ const metadata = {
20
+ organisation: 'Defra',
21
+ teamName: 'Team name',
22
+ teamEmail: 'team@defra.gov.uk',
23
+ submissionGuidance: "Thanks for your submission, we'll be in touch",
24
+ notificationEmail: 'email@domain.com',
25
+ ...author,
26
+ live: author
27
+ }
28
+ await service.addForm(
29
+ `${join(import.meta.dirname, '../../../test/form/definitions')}/components.json`,
30
+ {
31
+ ...metadata,
32
+ id: '95e92559-968d-44ae-8666-2b1ad3dffd31',
33
+ title: 'Form test',
34
+ slug: 'form-test'
35
+ }
36
+ )
37
+ })
38
+
39
+ describe('metadata by slug', () => {
40
+ it('should get form metadata by slug', () => {
41
+ const meta = service.getFormMetadata('form-test')
42
+ expect(meta.id).toBe('95e92559-968d-44ae-8666-2b1ad3dffd31')
43
+ expect(meta.title).toBe('Form test')
44
+ })
45
+
46
+ it('should throw if not found', () => {
47
+ expect(() => service.getFormMetadata('form-test-missing')).toThrow(
48
+ "Form metadata 'form-test-missing' not found"
49
+ )
50
+ })
51
+ })
52
+
53
+ describe('metadata by id', () => {
54
+ it('should get form metadata by id', () => {
55
+ const meta = service.getFormMetadataById(
56
+ '95e92559-968d-44ae-8666-2b1ad3dffd31'
57
+ )
58
+ expect(meta.id).toBe('95e92559-968d-44ae-8666-2b1ad3dffd31')
59
+ expect(meta.title).toBe('Form test')
60
+ })
61
+
62
+ it('should throw if not found', () => {
63
+ expect(() => service.getFormMetadataById('id-missing')).toThrow(
64
+ "Form metadata id 'id-missing' not found"
65
+ )
66
+ })
67
+ })
68
+
69
+ describe('definition by id', () => {
70
+ it('should get form definition by id', () => {
71
+ const form = service.getFormDefinition(
72
+ '95e92559-968d-44ae-8666-2b1ad3dffd31'
73
+ )
74
+ expect(form.name).toBe('All components')
75
+ expect(form.startPage).toBe('/all-components')
76
+ })
77
+
78
+ it('should throw if not found', () => {
79
+ expect(() => service.getFormDefinition('id-missing')).toThrow(
80
+ "Form definition 'id-missing' not found"
81
+ )
82
+ })
83
+ })
84
+
85
+ describe('toFormsService', () => {
86
+ it('should create interface', async () => {
87
+ const interfaceImpl = service.toFormsService()
88
+ const res1 = await interfaceImpl.getFormMetadata('form-test')
89
+ expect(res1.id).toBe('95e92559-968d-44ae-8666-2b1ad3dffd31')
90
+ expect(res1.title).toBe('Form test')
91
+
92
+ const res2 = await interfaceImpl.getFormMetadataById(
93
+ '95e92559-968d-44ae-8666-2b1ad3dffd31'
94
+ )
95
+ expect(res2.id).toBe('95e92559-968d-44ae-8666-2b1ad3dffd31')
96
+ expect(res2.title).toBe('Form test')
97
+
98
+ const res3 = await interfaceImpl.getFormDefinition(
99
+ '95e92559-968d-44ae-8666-2b1ad3dffd31',
100
+ FormStatus.Draft
101
+ )
102
+ expect(res3?.name).toBe('All components')
103
+ expect(res3?.startPage).toBe('/all-components')
104
+ })
105
+ })
106
+
107
+ describe('readForm', () => {
108
+ it('should throw if invalid extension', async () => {
109
+ await expect(
110
+ service.readForm('/some-folder/some-file.bad')
111
+ ).rejects.toThrow("Invalid file extension '.bad'")
112
+ })
113
+ })
114
+ })