Skip to content

Commit 366034f

Browse files
Merge pull request #282 from open-formulieren/feature/5247-map-component-lat-lng-validation
Map component coordinates validation
2 parents 2104f00 + db3e987 commit 366034f

File tree

2 files changed

+217
-3
lines changed

2 files changed

+217
-3
lines changed

src/registry/map/validationSchema.spec.ts

Lines changed: 213 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('map component validation', () => {
3030
null,
3131
{
3232
type: 'Point',
33-
coordinates: [52.3857386, 4.8417475],
33+
coordinates: [4.8417475, 52.3857386],
3434
},
3535
{
3636
type: 'LineString',
@@ -186,10 +186,221 @@ describe('map component validation', () => {
186186

187187
const value = {
188188
type: 'Point',
189-
coordinates: [52.3857386, 4.8417475],
189+
coordinates: [4.8417475, 52.3857386],
190190
};
191191
const {success} = await schema.safeParseAsync(value);
192192

193193
expect(success).toBe(valid);
194194
});
195195
});
196+
197+
describe('map component coordinates bounds validation', () => {
198+
test.each([
199+
[
200+
// Latitude and longitude in wrong order
201+
{
202+
type: 'Point',
203+
coordinates: [52.3857386, 4.8417475],
204+
},
205+
false,
206+
],
207+
[
208+
// Latitude out of Dutch bounds
209+
{
210+
type: 'Point',
211+
coordinates: [4.8417475, 56.3857386],
212+
},
213+
false,
214+
],
215+
[
216+
// Longitude out of Dutch bounds
217+
{
218+
type: 'Point',
219+
coordinates: [9.8417475, 52.3857386],
220+
},
221+
false,
222+
],
223+
[
224+
// Latitude and longitude out of Dutch bounds
225+
{
226+
type: 'Point',
227+
coordinates: [9.8417475, 56.3857386],
228+
},
229+
false,
230+
],
231+
[
232+
// Latitude and longitude in Dutch bounds
233+
{
234+
type: 'Point',
235+
coordinates: [4.8417475, 52.3857386],
236+
},
237+
true,
238+
],
239+
])('Point geometry coordinate bounds %s (expected %s)', (value, expected) => {
240+
const component: MapComponentSchema = {
241+
...BASE_COMPONENT,
242+
interactions: {marker: true, polyline: true, polygon: true},
243+
};
244+
const schema = buildValidationSchema(component);
245+
246+
const {success} = schema.safeParse(value);
247+
248+
expect(success).toBe(expected);
249+
});
250+
251+
test.each([
252+
[
253+
// Latitude and longitude in wrong order
254+
{
255+
type: 'LineString',
256+
coordinates: [
257+
[52.6405471, 4.7493255],
258+
[52.4405471, 4.6493255],
259+
[52.2405471, 4.5493255],
260+
],
261+
},
262+
false,
263+
],
264+
[
265+
// Latitude out of Dutch bounds
266+
{
267+
type: 'LineString',
268+
coordinates: [
269+
[4.7493255, 56.6405471],
270+
[4.6493255, 56.4405471],
271+
[4.5493255, 56.2405471],
272+
],
273+
},
274+
false,
275+
],
276+
[
277+
// Longitude out of Dutch bounds
278+
{
279+
type: 'LineString',
280+
coordinates: [
281+
[9.7493255, 52.6405471],
282+
[9.6493255, 52.4405471],
283+
[9.5493255, 52.2405471],
284+
],
285+
},
286+
false,
287+
],
288+
[
289+
// Latitude and longitude out of Dutch bounds
290+
{
291+
type: 'LineString',
292+
coordinates: [
293+
[9.7493255, 56.6405471],
294+
[9.6493255, 56.4405471],
295+
[9.5493255, 56.2405471],
296+
],
297+
},
298+
false,
299+
],
300+
[
301+
// Latitude and longitude in Dutch bounds
302+
{
303+
type: 'LineString',
304+
coordinates: [
305+
[4.7493255, 52.6405471],
306+
[4.6493255, 52.4405471],
307+
[4.5493255, 52.2405471],
308+
],
309+
},
310+
true,
311+
],
312+
])('Line geometry coordinate bounds %s (expected %s)', (value, expected) => {
313+
const component: MapComponentSchema = {
314+
...BASE_COMPONENT,
315+
interactions: {marker: true, polyline: true, polygon: true},
316+
};
317+
const schema = buildValidationSchema(component);
318+
319+
const {success} = schema.safeParse(value);
320+
321+
expect(success).toBe(expected);
322+
});
323+
324+
test.each([
325+
[
326+
// Latitude and longitude in wrong order
327+
{
328+
type: 'Polygon',
329+
coordinates: [
330+
[
331+
[52.1326332, 5.291266],
332+
[52.128332, 5.091266],
333+
[52.48332, 5.591266],
334+
],
335+
],
336+
},
337+
false,
338+
],
339+
[
340+
// Latitude out of Dutch bounds
341+
{
342+
type: 'Polygon',
343+
coordinates: [
344+
[
345+
[5.291266, 56.1326332],
346+
[5.091266, 56.128332],
347+
[5.591266, 56.48332],
348+
],
349+
],
350+
},
351+
false,
352+
],
353+
[
354+
// Longitude out of Dutch bounds
355+
{
356+
type: 'Polygon',
357+
coordinates: [
358+
[
359+
[9.291266, 52.1326332],
360+
[9.091266, 52.128332],
361+
[9.591266, 52.48332],
362+
],
363+
],
364+
},
365+
false,
366+
],
367+
[
368+
// Latitude and longitude out of Dutch bounds
369+
{
370+
type: 'Polygon',
371+
coordinates: [
372+
[
373+
[9.291266, 56.1326332],
374+
[9.091266, 56.128332],
375+
[9.591266, 56.48332],
376+
],
377+
],
378+
},
379+
false,
380+
],
381+
[
382+
// Latitude and longitude in Dutch bounds
383+
{
384+
type: 'Polygon',
385+
coordinates: [
386+
[
387+
[5.291266, 52.1326332],
388+
[5.091266, 52.128332],
389+
[5.591266, 52.48332],
390+
],
391+
],
392+
},
393+
true,
394+
],
395+
])('Polygon geometry coordinate bounds %s (expected %s)', (value, expected) => {
396+
const component: MapComponentSchema = {
397+
...BASE_COMPONENT,
398+
interactions: {marker: true, polyline: true, polygon: true},
399+
};
400+
const schema = buildValidationSchema(component);
401+
402+
const {success} = schema.safeParse(value);
403+
404+
expect(success).toBe(expected);
405+
});
406+
});

src/registry/map/validationSchema.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import {buildRequiredMessage} from '@/validationSchemas/errorMessages';
66

77
import {DEFAULT_INTERACTIONS} from './constants';
88

9-
const coordinatesSchema = z.array(z.number()).length(2);
9+
// The coordinates must be in the order of lng/lat, use the WGS84 projection,
10+
// and must be within the bounds of the Netherlands.
11+
// https://epsg.io/28992
12+
const coordinatesSchema = z.tuple([z.number().gte(3).lte(7.5), z.number().gt(50.5).lte(54)]);
1013

1114
const pointSchema = z.object({
1215
type: z.literal('Point'),

0 commit comments

Comments
 (0)