@defra/forms-engine-plugin 4.0.5 → 4.0.7
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.
- package/.public/stylesheets/application.min.css +2 -2
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/stylesheets/_location-input.scss +60 -0
- package/.server/client/stylesheets/application.scss +1 -6
- package/.server/client/stylesheets/shared.scss +8 -0
- package/.server/server/forms/register-as-a-unicorn-breeder.yaml +28 -0
- package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -1
- package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
- package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +121 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.js +166 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -0
- package/.server/server/plugins/engine/components/LatLongField.d.ts +121 -0
- package/.server/server/plugins/engine/components/LatLongField.js +164 -0
- package/.server/server/plugins/engine/components/LatLongField.js.map +1 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +134 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.js +85 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +108 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +96 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +19 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +40 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -0
- package/.server/server/plugins/engine/components/OsGridRefField.d.ts +19 -0
- package/.server/server/plugins/engine/components/OsGridRefField.js +56 -0
- package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -4
- package/.server/server/plugins/engine/components/helpers/components.js +21 -29
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +4 -0
- package/.server/server/plugins/engine/components/index.js +4 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/components/markdownParser.d.ts +2 -0
- package/.server/server/plugins/engine/components/markdownParser.js +28 -0
- package/.server/server/plugins/engine/components/markdownParser.js.map +1 -0
- package/.server/server/plugins/engine/components/types.d.ts +10 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js +7 -0
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
- package/.server/server/plugins/engine/types/index.d.ts +1 -1
- package/.server/server/plugins/engine/types/index.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +2 -2
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +53 -0
- package/.server/server/plugins/engine/views/components/eastingnorthingfield.html +5 -0
- package/.server/server/plugins/engine/views/components/latlongfield.html +5 -0
- package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +13 -0
- package/.server/server/plugins/engine/views/components/osgridreffield.html +13 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/package.json +3 -3
- package/src/client/stylesheets/_location-input.scss +60 -0
- package/src/client/stylesheets/application.scss +1 -6
- package/src/client/stylesheets/shared.scss +8 -0
- package/src/server/forms/register-as-a-unicorn-breeder.yaml +28 -0
- package/src/server/plugins/engine/components/ComponentBase.ts +1 -1
- package/src/server/plugins/engine/components/EastingNorthingField.test.ts +665 -0
- package/src/server/plugins/engine/components/EastingNorthingField.ts +224 -0
- package/src/server/plugins/engine/components/LatLongField.test.ts +700 -0
- package/src/server/plugins/engine/components/LatLongField.ts +213 -0
- package/src/server/plugins/engine/components/LocationFieldBase.test.ts +253 -0
- package/src/server/plugins/engine/components/LocationFieldBase.ts +152 -0
- package/src/server/plugins/engine/components/LocationFieldHelpers.test.ts +338 -0
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +123 -0
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.test.ts +438 -0
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +52 -0
- package/src/server/plugins/engine/components/OsGridRefField.test.ts +469 -0
- package/src/server/plugins/engine/components/OsGridRefField.ts +71 -0
- package/src/server/plugins/engine/components/helpers/components.test.ts +270 -0
- package/src/server/plugins/engine/components/helpers/components.ts +39 -47
- package/src/server/plugins/engine/components/helpers/helpers.test.ts +71 -1
- package/src/server/plugins/engine/components/index.ts +4 -0
- package/src/server/plugins/engine/components/markdownParser.ts +40 -0
- package/src/server/plugins/engine/components/types.ts +14 -0
- package/src/server/plugins/engine/outputFormatters/adapter/v1.location.test.ts +356 -0
- package/src/server/plugins/engine/pageControllers/helpers/helpers.test.ts +4 -0
- package/src/server/plugins/engine/pageControllers/helpers/pages.ts +8 -0
- package/src/server/plugins/engine/types/index.ts +2 -0
- package/src/server/plugins/engine/types.ts +4 -0
- package/src/server/plugins/engine/views/components/_location-field-base.html +53 -0
- package/src/server/plugins/engine/views/components/eastingnorthingfield.html +5 -0
- package/src/server/plugins/engine/views/components/latlongfield.html +5 -0
- package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +13 -0
- package/src/server/plugins/engine/views/components/osgridreffield.html +13 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ComponentType,
|
|
3
|
+
type EastingNorthingFieldComponent
|
|
4
|
+
} from '@defra/forms-model'
|
|
5
|
+
|
|
6
|
+
import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'
|
|
7
|
+
import { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'
|
|
8
|
+
import {
|
|
9
|
+
getAnswer,
|
|
10
|
+
type Field
|
|
11
|
+
} from '~/src/server/plugins/engine/components/helpers/components.js'
|
|
12
|
+
import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
|
|
13
|
+
import definition from '~/test/form/definitions/blank.js'
|
|
14
|
+
|
|
15
|
+
describe('EastingNorthingField', () => {
|
|
16
|
+
let model: FormModel
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
model = new FormModel(definition, {
|
|
20
|
+
basePath: 'test'
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('Defaults', () => {
|
|
25
|
+
let def: EastingNorthingFieldComponent
|
|
26
|
+
let collection: ComponentCollection
|
|
27
|
+
let field: Field
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
def = {
|
|
31
|
+
title: 'Example easting northing',
|
|
32
|
+
shortDescription: 'Example location',
|
|
33
|
+
name: 'myComponent',
|
|
34
|
+
type: ComponentType.EastingNorthingField,
|
|
35
|
+
options: {},
|
|
36
|
+
schema: {}
|
|
37
|
+
} satisfies EastingNorthingFieldComponent
|
|
38
|
+
|
|
39
|
+
collection = new ComponentCollection([def], { model })
|
|
40
|
+
field = collection.fields[0]
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
describe('Schema', () => {
|
|
44
|
+
it('uses collection titles as labels', () => {
|
|
45
|
+
const { formSchema } = collection
|
|
46
|
+
const { keys } = formSchema.describe()
|
|
47
|
+
|
|
48
|
+
expect(keys).toHaveProperty(
|
|
49
|
+
'myComponent__easting',
|
|
50
|
+
expect.objectContaining({
|
|
51
|
+
flags: expect.objectContaining({ label: 'Easting' })
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
expect(keys).toHaveProperty(
|
|
56
|
+
'myComponent__northing',
|
|
57
|
+
expect.objectContaining({
|
|
58
|
+
flags: expect.objectContaining({ label: 'Northing' })
|
|
59
|
+
})
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('uses collection names as keys', () => {
|
|
64
|
+
const { formSchema } = collection
|
|
65
|
+
const { keys } = formSchema.describe()
|
|
66
|
+
|
|
67
|
+
expect(field.keys).toEqual([
|
|
68
|
+
'myComponent',
|
|
69
|
+
'myComponent__easting',
|
|
70
|
+
'myComponent__northing'
|
|
71
|
+
])
|
|
72
|
+
|
|
73
|
+
expect(field.collection?.keys).not.toHaveProperty('myComponent')
|
|
74
|
+
|
|
75
|
+
for (const key of field.collection?.keys ?? []) {
|
|
76
|
+
expect(keys).toHaveProperty(key)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('is required by default', () => {
|
|
81
|
+
const { formSchema } = collection
|
|
82
|
+
const { keys } = formSchema.describe()
|
|
83
|
+
|
|
84
|
+
expect(keys).toHaveProperty(
|
|
85
|
+
'myComponent__easting',
|
|
86
|
+
expect.objectContaining({
|
|
87
|
+
flags: expect.objectContaining({ presence: 'required' })
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
expect(keys).toHaveProperty(
|
|
92
|
+
'myComponent__northing',
|
|
93
|
+
expect.objectContaining({
|
|
94
|
+
flags: expect.objectContaining({ presence: 'required' })
|
|
95
|
+
})
|
|
96
|
+
)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('is optional when configured', () => {
|
|
100
|
+
const collectionOptional = new ComponentCollection(
|
|
101
|
+
[
|
|
102
|
+
{
|
|
103
|
+
title: 'Example easting northing',
|
|
104
|
+
name: 'myComponent',
|
|
105
|
+
type: ComponentType.EastingNorthingField,
|
|
106
|
+
options: { required: false },
|
|
107
|
+
schema: {}
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
{ model }
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
const { formSchema } = collectionOptional
|
|
114
|
+
const { keys } = formSchema.describe()
|
|
115
|
+
|
|
116
|
+
expect(keys).toHaveProperty(
|
|
117
|
+
'myComponent__easting',
|
|
118
|
+
expect.objectContaining({ allow: [''] })
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
expect(keys).toHaveProperty(
|
|
122
|
+
'myComponent__northing',
|
|
123
|
+
expect.objectContaining({ allow: [''] })
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
const result1 = collectionOptional.validate(
|
|
127
|
+
getFormData({
|
|
128
|
+
easting: '',
|
|
129
|
+
northing: ''
|
|
130
|
+
})
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
const result2 = collectionOptional.validate(
|
|
134
|
+
getFormData({
|
|
135
|
+
easting: '12345',
|
|
136
|
+
northing: ''
|
|
137
|
+
})
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
expect(result1.errors).toBeUndefined()
|
|
141
|
+
expect(result2.errors).toBeTruthy()
|
|
142
|
+
expect(result2.errors?.length).toBeGreaterThan(0)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('accepts valid values', () => {
|
|
146
|
+
const result1 = collection.validate(
|
|
147
|
+
getFormData({
|
|
148
|
+
easting: '12345',
|
|
149
|
+
northing: '1234567'
|
|
150
|
+
})
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
const result2 = collection.validate(
|
|
154
|
+
getFormData({
|
|
155
|
+
easting: '0',
|
|
156
|
+
northing: '0'
|
|
157
|
+
})
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
expect(result1.errors).toBeUndefined()
|
|
161
|
+
expect(result2.errors).toBeUndefined()
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('adds errors for empty value when short description exists', () => {
|
|
165
|
+
const result = collection.validate(
|
|
166
|
+
getFormData({
|
|
167
|
+
easting: '',
|
|
168
|
+
northing: ''
|
|
169
|
+
})
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
expect(result.errors).toBeTruthy()
|
|
173
|
+
expect(result.errors?.length).toBe(2)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('adds errors for invalid values', () => {
|
|
177
|
+
const result1 = collection.validate(
|
|
178
|
+
getFormData({
|
|
179
|
+
easting: 'invalid',
|
|
180
|
+
northing: 'invalid'
|
|
181
|
+
})
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
const result2 = collection.validate(
|
|
185
|
+
getFormData({
|
|
186
|
+
easting: '12345.5',
|
|
187
|
+
northing: '1234567.5'
|
|
188
|
+
})
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
expect(result1.errors).toBeTruthy()
|
|
192
|
+
expect(result2.errors).toBeTruthy()
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
describe('State', () => {
|
|
197
|
+
it('returns text from state', () => {
|
|
198
|
+
const state1 = getFormState({
|
|
199
|
+
easting: 12345,
|
|
200
|
+
northing: 1234567
|
|
201
|
+
})
|
|
202
|
+
const state2 = getFormState({})
|
|
203
|
+
|
|
204
|
+
const answer1 = getAnswer(field, state1)
|
|
205
|
+
const answer2 = getAnswer(field, state2)
|
|
206
|
+
|
|
207
|
+
expect(answer1).toBe('Northing: 1234567<br>Easting: 12345<br>')
|
|
208
|
+
expect(answer2).toBe('')
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('returns payload from state', () => {
|
|
212
|
+
const state1 = getFormState({
|
|
213
|
+
easting: 12345,
|
|
214
|
+
northing: 1234567
|
|
215
|
+
})
|
|
216
|
+
const state2 = getFormState({})
|
|
217
|
+
|
|
218
|
+
const payload1 = field.getFormDataFromState(state1)
|
|
219
|
+
const payload2 = field.getFormDataFromState(state2)
|
|
220
|
+
|
|
221
|
+
expect(payload1).toEqual(
|
|
222
|
+
getFormData({
|
|
223
|
+
easting: 12345,
|
|
224
|
+
northing: 1234567
|
|
225
|
+
})
|
|
226
|
+
)
|
|
227
|
+
expect(payload2).toEqual(getFormData({}))
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it('returns value from state', () => {
|
|
231
|
+
const state1 = getFormState({
|
|
232
|
+
easting: 12345,
|
|
233
|
+
northing: 1234567
|
|
234
|
+
})
|
|
235
|
+
const state2 = getFormState({})
|
|
236
|
+
|
|
237
|
+
const value1 = field.getFormValueFromState(state1)
|
|
238
|
+
const value2 = field.getFormValueFromState(state2)
|
|
239
|
+
|
|
240
|
+
expect(value1).toEqual({
|
|
241
|
+
easting: 12345,
|
|
242
|
+
northing: 1234567
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
expect(value2).toBeUndefined()
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
it('returns context for conditions and form submission', () => {
|
|
249
|
+
const state1 = getFormState({
|
|
250
|
+
easting: 12345,
|
|
251
|
+
northing: 1234567
|
|
252
|
+
})
|
|
253
|
+
const state2 = getFormState({})
|
|
254
|
+
|
|
255
|
+
const value1 = field.getContextValueFromState(state1)
|
|
256
|
+
const value2 = field.getContextValueFromState(state2)
|
|
257
|
+
|
|
258
|
+
expect(value1).toBe('Northing: 1234567\nEasting: 12345')
|
|
259
|
+
expect(value2).toBeNull()
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
it('returns state from payload', () => {
|
|
263
|
+
const payload1 = getFormData({
|
|
264
|
+
easting: 12345,
|
|
265
|
+
northing: 1234567
|
|
266
|
+
})
|
|
267
|
+
const payload2 = getFormData({})
|
|
268
|
+
|
|
269
|
+
const value1 = field.getStateFromValidForm(payload1)
|
|
270
|
+
const value2 = field.getStateFromValidForm(payload2)
|
|
271
|
+
|
|
272
|
+
expect(value1).toEqual(
|
|
273
|
+
getFormState({
|
|
274
|
+
easting: 12345,
|
|
275
|
+
northing: 1234567
|
|
276
|
+
})
|
|
277
|
+
)
|
|
278
|
+
expect(value2).toEqual(getFormState({}))
|
|
279
|
+
})
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
describe('View model', () => {
|
|
283
|
+
it('sets Nunjucks component defaults', () => {
|
|
284
|
+
const payload = getFormData({
|
|
285
|
+
easting: 12345,
|
|
286
|
+
northing: 1234567
|
|
287
|
+
})
|
|
288
|
+
const viewModel = field.getViewModel(payload)
|
|
289
|
+
|
|
290
|
+
expect(viewModel).toEqual(
|
|
291
|
+
expect.objectContaining({
|
|
292
|
+
fieldset: {
|
|
293
|
+
legend: {
|
|
294
|
+
text: def.title,
|
|
295
|
+
classes: 'govuk-fieldset__legend--m'
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
items: [
|
|
299
|
+
expect.objectContaining({
|
|
300
|
+
label: expect.objectContaining({ text: 'Easting' }),
|
|
301
|
+
name: 'myComponent__easting',
|
|
302
|
+
id: 'myComponent__easting',
|
|
303
|
+
value: 12345
|
|
304
|
+
}),
|
|
305
|
+
expect.objectContaining({
|
|
306
|
+
label: expect.objectContaining({ text: 'Northing' }),
|
|
307
|
+
name: 'myComponent__northing',
|
|
308
|
+
id: 'myComponent__northing',
|
|
309
|
+
value: 1234567
|
|
310
|
+
})
|
|
311
|
+
]
|
|
312
|
+
})
|
|
313
|
+
)
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
it('includes instruction text when provided', () => {
|
|
317
|
+
const componentWithInstruction = new EastingNorthingField(
|
|
318
|
+
{
|
|
319
|
+
...def,
|
|
320
|
+
options: { instructionText: 'Enter coordinates in **meters**' }
|
|
321
|
+
},
|
|
322
|
+
{ model }
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
const viewModel = componentWithInstruction.getViewModel(
|
|
326
|
+
getFormData({
|
|
327
|
+
easting: 12345,
|
|
328
|
+
northing: 1234567
|
|
329
|
+
})
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
const instructionText =
|
|
333
|
+
'instructionText' in viewModel ? viewModel.instructionText : undefined
|
|
334
|
+
expect(instructionText).toBeTruthy()
|
|
335
|
+
expect(instructionText).toContain('meters')
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('sets error classes when component has errors', () => {
|
|
339
|
+
const payload = getFormData({
|
|
340
|
+
easting: '',
|
|
341
|
+
northing: ''
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
const errors = [
|
|
345
|
+
{
|
|
346
|
+
name: 'myComponent',
|
|
347
|
+
text: 'Error message',
|
|
348
|
+
path: ['myComponent'],
|
|
349
|
+
href: '#myComponent'
|
|
350
|
+
}
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
const viewModel = field.getViewModel(payload, errors)
|
|
354
|
+
|
|
355
|
+
expect(viewModel.items?.[0]).toEqual(
|
|
356
|
+
expect.objectContaining({
|
|
357
|
+
classes: expect.stringContaining('govuk-input--error')
|
|
358
|
+
})
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
expect(viewModel.items?.[1]).toEqual(
|
|
362
|
+
expect.objectContaining({
|
|
363
|
+
classes: expect.stringContaining('govuk-input--error')
|
|
364
|
+
})
|
|
365
|
+
)
|
|
366
|
+
})
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
describe('AllPossibleErrors', () => {
|
|
370
|
+
it('should return errors from instance method', () => {
|
|
371
|
+
const errors = field.getAllPossibleErrors()
|
|
372
|
+
expect(errors.baseErrors).not.toBeEmpty()
|
|
373
|
+
expect(errors.advancedSettingsErrors).not.toBeEmpty()
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
it('should return errors from static method', () => {
|
|
377
|
+
const staticErrors = EastingNorthingField.getAllPossibleErrors()
|
|
378
|
+
expect(staticErrors.baseErrors).not.toBeEmpty()
|
|
379
|
+
expect(staticErrors.advancedSettingsErrors).not.toBeEmpty()
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('instance method should delegate to static method', () => {
|
|
383
|
+
const staticResult = EastingNorthingField.getAllPossibleErrors()
|
|
384
|
+
const instanceResult = field.getAllPossibleErrors()
|
|
385
|
+
|
|
386
|
+
expect(instanceResult).toEqual(staticResult)
|
|
387
|
+
})
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
describe('Validation', () => {
|
|
392
|
+
describe.each([
|
|
393
|
+
{
|
|
394
|
+
description: 'Trim empty spaces',
|
|
395
|
+
component: {
|
|
396
|
+
title: 'Example easting northing',
|
|
397
|
+
name: 'myComponent',
|
|
398
|
+
type: ComponentType.EastingNorthingField,
|
|
399
|
+
options: {},
|
|
400
|
+
schema: {}
|
|
401
|
+
} satisfies EastingNorthingFieldComponent,
|
|
402
|
+
assertions: [
|
|
403
|
+
{
|
|
404
|
+
input: getFormData({
|
|
405
|
+
easting: ' 12345',
|
|
406
|
+
northing: ' 1234567'
|
|
407
|
+
}),
|
|
408
|
+
output: {
|
|
409
|
+
value: getFormData({
|
|
410
|
+
easting: 12345,
|
|
411
|
+
northing: 1234567
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
input: getFormData({
|
|
417
|
+
easting: '12345 ',
|
|
418
|
+
northing: '1234567 '
|
|
419
|
+
}),
|
|
420
|
+
output: {
|
|
421
|
+
value: getFormData({
|
|
422
|
+
easting: 12345,
|
|
423
|
+
northing: 1234567
|
|
424
|
+
})
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
]
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
description: 'Schema min and max for easting',
|
|
431
|
+
component: {
|
|
432
|
+
title: 'Example easting northing',
|
|
433
|
+
name: 'myComponent',
|
|
434
|
+
type: ComponentType.EastingNorthingField,
|
|
435
|
+
options: {},
|
|
436
|
+
schema: {
|
|
437
|
+
easting: {
|
|
438
|
+
min: 1000,
|
|
439
|
+
max: 60000
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
} satisfies EastingNorthingFieldComponent,
|
|
443
|
+
assertions: [
|
|
444
|
+
{
|
|
445
|
+
input: getFormData({
|
|
446
|
+
easting: '999',
|
|
447
|
+
northing: '1234567'
|
|
448
|
+
}),
|
|
449
|
+
output: {
|
|
450
|
+
value: getFormData({
|
|
451
|
+
easting: 999,
|
|
452
|
+
northing: 1234567
|
|
453
|
+
}),
|
|
454
|
+
errors: [
|
|
455
|
+
expect.objectContaining({
|
|
456
|
+
text: expect.stringMatching(
|
|
457
|
+
/Easting for .* must be between 1000 and 60000/
|
|
458
|
+
)
|
|
459
|
+
})
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
input: getFormData({
|
|
465
|
+
easting: '60001',
|
|
466
|
+
northing: '1234567'
|
|
467
|
+
}),
|
|
468
|
+
output: {
|
|
469
|
+
value: getFormData({
|
|
470
|
+
easting: 60001,
|
|
471
|
+
northing: 1234567
|
|
472
|
+
}),
|
|
473
|
+
errors: [
|
|
474
|
+
expect.objectContaining({
|
|
475
|
+
text: expect.stringMatching(
|
|
476
|
+
/Easting for .* must be between 1000 and 60000/
|
|
477
|
+
)
|
|
478
|
+
})
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
]
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
description: 'Schema min and max for northing',
|
|
486
|
+
component: {
|
|
487
|
+
title: 'Example easting northing',
|
|
488
|
+
name: 'myComponent',
|
|
489
|
+
type: ComponentType.EastingNorthingField,
|
|
490
|
+
options: {},
|
|
491
|
+
schema: {
|
|
492
|
+
northing: {
|
|
493
|
+
min: 1000,
|
|
494
|
+
max: 1200000
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
} satisfies EastingNorthingFieldComponent,
|
|
498
|
+
assertions: [
|
|
499
|
+
{
|
|
500
|
+
input: getFormData({
|
|
501
|
+
easting: '12345',
|
|
502
|
+
northing: '999'
|
|
503
|
+
}),
|
|
504
|
+
output: {
|
|
505
|
+
value: getFormData({
|
|
506
|
+
easting: 12345,
|
|
507
|
+
northing: 999
|
|
508
|
+
}),
|
|
509
|
+
errors: [
|
|
510
|
+
expect.objectContaining({
|
|
511
|
+
text: expect.stringMatching(
|
|
512
|
+
/Northing for .* must be between 1000 and 1200000/
|
|
513
|
+
)
|
|
514
|
+
})
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
input: getFormData({
|
|
520
|
+
easting: '12345',
|
|
521
|
+
northing: '1200001'
|
|
522
|
+
}),
|
|
523
|
+
output: {
|
|
524
|
+
value: getFormData({
|
|
525
|
+
easting: 12345,
|
|
526
|
+
northing: 1200001
|
|
527
|
+
}),
|
|
528
|
+
errors: [
|
|
529
|
+
expect.objectContaining({
|
|
530
|
+
text: expect.stringMatching(
|
|
531
|
+
/Northing for .* must be between 1000 and 1200000/
|
|
532
|
+
)
|
|
533
|
+
})
|
|
534
|
+
]
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
]
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
description: 'Precision validation',
|
|
541
|
+
component: {
|
|
542
|
+
title: 'Example easting northing',
|
|
543
|
+
name: 'myComponent',
|
|
544
|
+
type: ComponentType.EastingNorthingField,
|
|
545
|
+
options: {},
|
|
546
|
+
schema: {}
|
|
547
|
+
} satisfies EastingNorthingFieldComponent,
|
|
548
|
+
assertions: [
|
|
549
|
+
{
|
|
550
|
+
input: getFormData({
|
|
551
|
+
easting: '12345.5',
|
|
552
|
+
northing: '1234567'
|
|
553
|
+
}),
|
|
554
|
+
output: {
|
|
555
|
+
value: getFormData({
|
|
556
|
+
easting: 12345.5,
|
|
557
|
+
northing: 1234567
|
|
558
|
+
}),
|
|
559
|
+
errors: [
|
|
560
|
+
expect.objectContaining({
|
|
561
|
+
text: expect.stringMatching(
|
|
562
|
+
/Easting for .* must be between 1 and 5 digits/
|
|
563
|
+
)
|
|
564
|
+
})
|
|
565
|
+
]
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
input: getFormData({
|
|
570
|
+
easting: '12345',
|
|
571
|
+
northing: '1234567.5'
|
|
572
|
+
}),
|
|
573
|
+
output: {
|
|
574
|
+
value: getFormData({
|
|
575
|
+
easting: 12345,
|
|
576
|
+
northing: 1234567.5
|
|
577
|
+
}),
|
|
578
|
+
errors: [
|
|
579
|
+
expect.objectContaining({
|
|
580
|
+
text: expect.stringMatching(
|
|
581
|
+
/Northing for .* must be between 1 and 7 digits/
|
|
582
|
+
)
|
|
583
|
+
})
|
|
584
|
+
]
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
]
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
description: 'Optional field',
|
|
591
|
+
component: {
|
|
592
|
+
title: 'Example easting northing',
|
|
593
|
+
name: 'myComponent',
|
|
594
|
+
type: ComponentType.EastingNorthingField,
|
|
595
|
+
options: {
|
|
596
|
+
required: false
|
|
597
|
+
},
|
|
598
|
+
schema: {}
|
|
599
|
+
} satisfies EastingNorthingFieldComponent,
|
|
600
|
+
assertions: [
|
|
601
|
+
{
|
|
602
|
+
input: getFormData({
|
|
603
|
+
easting: '',
|
|
604
|
+
northing: ''
|
|
605
|
+
}),
|
|
606
|
+
output: {
|
|
607
|
+
value: getFormData({
|
|
608
|
+
easting: '',
|
|
609
|
+
northing: ''
|
|
610
|
+
})
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
]
|
|
614
|
+
}
|
|
615
|
+
])('$description', ({ component: def, assertions }) => {
|
|
616
|
+
let collection: ComponentCollection
|
|
617
|
+
|
|
618
|
+
beforeEach(() => {
|
|
619
|
+
collection = new ComponentCollection([def], { model })
|
|
620
|
+
})
|
|
621
|
+
|
|
622
|
+
it.each([...assertions])(
|
|
623
|
+
'validates custom example',
|
|
624
|
+
({ input, output }) => {
|
|
625
|
+
const result = collection.validate(input)
|
|
626
|
+
expect(result).toEqual(output)
|
|
627
|
+
}
|
|
628
|
+
)
|
|
629
|
+
})
|
|
630
|
+
})
|
|
631
|
+
})
|
|
632
|
+
|
|
633
|
+
function getFormData(
|
|
634
|
+
value:
|
|
635
|
+
| { easting?: string | number; northing?: string | number }
|
|
636
|
+
| Record<string, never>
|
|
637
|
+
) {
|
|
638
|
+
if ('easting' in value || 'northing' in value) {
|
|
639
|
+
return {
|
|
640
|
+
myComponent__easting: value.easting,
|
|
641
|
+
myComponent__northing: value.northing
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return {}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function getFormState(
|
|
648
|
+
value:
|
|
649
|
+
| {
|
|
650
|
+
easting?: number
|
|
651
|
+
northing?: number
|
|
652
|
+
}
|
|
653
|
+
| Record<string, never>
|
|
654
|
+
) {
|
|
655
|
+
if ('easting' in value || 'northing' in value) {
|
|
656
|
+
return {
|
|
657
|
+
myComponent__easting: value.easting ?? null,
|
|
658
|
+
myComponent__northing: value.northing ?? null
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return {
|
|
662
|
+
myComponent__easting: null,
|
|
663
|
+
myComponent__northing: null
|
|
664
|
+
}
|
|
665
|
+
}
|