@remoteoss/json-schema-form 0.10.1-beta.0 → 0.11.0-beta.0
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/CHANGELOG.md +20 -1
- package/dist/index.cjs +203 -15
- package/dist/index.js +203 -15
- package/dist/standalone.js +373 -23
- package/package.json +1 -1
- package/src/tests/modify.test.js +528 -12
package/src/tests/modify.test.js
CHANGED
|
@@ -53,12 +53,15 @@ const schemaPet = {
|
|
|
53
53
|
properties: {
|
|
54
54
|
street: {
|
|
55
55
|
title: 'Street',
|
|
56
|
+
'x-jsf-presentation': {
|
|
57
|
+
inputType: 'text',
|
|
58
|
+
},
|
|
56
59
|
},
|
|
57
60
|
},
|
|
58
61
|
},
|
|
59
62
|
},
|
|
60
63
|
required: ['has_pet'],
|
|
61
|
-
'x-jsf-order': ['has_pet', 'pet_name'],
|
|
64
|
+
'x-jsf-order': ['has_pet', 'pet_name', 'pet_age', 'pet_fat', 'pet_address'],
|
|
62
65
|
allOf: [
|
|
63
66
|
{
|
|
64
67
|
id: 'pet_conditional_id',
|
|
@@ -102,6 +105,36 @@ const schemaAddress = {
|
|
|
102
105
|
},
|
|
103
106
|
};
|
|
104
107
|
|
|
108
|
+
beforeAll(() => {
|
|
109
|
+
jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
afterAll(() => {
|
|
113
|
+
console.warn.mockRestore();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('modify() - warnings', () => {
|
|
117
|
+
it('logs a warning by default', () => {
|
|
118
|
+
const result = modify(schemaPet, {});
|
|
119
|
+
|
|
120
|
+
expect(console.warn).toBeCalledWith(
|
|
121
|
+
'json-schema-form modify(): We highly recommend you to handle/report the returned `warnings` as they highlight possible bugs in your modifications. To mute this log, pass `muteLogging: true` to the config.'
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
console.warn.mockClear();
|
|
125
|
+
expect(result.warnings).toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('given muteLogging, it does not log the warning', () => {
|
|
129
|
+
const result = modify(schemaPet, {
|
|
130
|
+
muteLogging: true,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
expect(console.warn).not.toBeCalled();
|
|
134
|
+
expect(result.warnings).toEqual([]);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
105
138
|
describe('modify() - basic mutations', () => {
|
|
106
139
|
it('replace base field', () => {
|
|
107
140
|
const result = modify(schemaPet, {
|
|
@@ -119,7 +152,7 @@ describe('modify() - basic mutations', () => {
|
|
|
119
152
|
},
|
|
120
153
|
});
|
|
121
154
|
|
|
122
|
-
expect(result).toMatchObject({
|
|
155
|
+
expect(result.schema).toMatchObject({
|
|
123
156
|
properties: {
|
|
124
157
|
pet_name: {
|
|
125
158
|
title: 'Your pet name',
|
|
@@ -135,24 +168,30 @@ describe('modify() - basic mutations', () => {
|
|
|
135
168
|
it('replace nested field', () => {
|
|
136
169
|
const result = modify(schemaAddress, {
|
|
137
170
|
fields: {
|
|
171
|
+
// You can use dot notation
|
|
138
172
|
'address.street': {
|
|
139
173
|
title: 'Street name',
|
|
140
174
|
},
|
|
141
175
|
'address.city': () => ({
|
|
142
176
|
title: 'City name',
|
|
143
177
|
}),
|
|
144
|
-
|
|
178
|
+
// Or pass the native object
|
|
179
|
+
address: (fieldAttrs) => {
|
|
145
180
|
return {
|
|
146
181
|
properties: {
|
|
147
|
-
number:
|
|
182
|
+
number: (nestedAttrs) => {
|
|
183
|
+
return {
|
|
184
|
+
'x-test-siblings': Object.keys(fieldAttrs.properties),
|
|
185
|
+
title: `Door ${nestedAttrs.title}`,
|
|
186
|
+
};
|
|
187
|
+
},
|
|
148
188
|
},
|
|
149
189
|
};
|
|
150
190
|
},
|
|
151
|
-
// TODO: write test to nested field
|
|
152
191
|
},
|
|
153
192
|
});
|
|
154
193
|
|
|
155
|
-
expect(result).toMatchObject({
|
|
194
|
+
expect(result.schema).toMatchObject({
|
|
156
195
|
properties: {
|
|
157
196
|
address: {
|
|
158
197
|
properties: {
|
|
@@ -160,7 +199,8 @@ describe('modify() - basic mutations', () => {
|
|
|
160
199
|
title: 'Street name',
|
|
161
200
|
},
|
|
162
201
|
number: {
|
|
163
|
-
title: 'Door
|
|
202
|
+
title: 'Door Number',
|
|
203
|
+
'x-test-siblings': ['street', 'number', 'city'],
|
|
164
204
|
},
|
|
165
205
|
city: {
|
|
166
206
|
title: 'City name',
|
|
@@ -171,6 +211,44 @@ describe('modify() - basic mutations', () => {
|
|
|
171
211
|
});
|
|
172
212
|
});
|
|
173
213
|
|
|
214
|
+
it('replace fields that dont exist gets ignored', () => {
|
|
215
|
+
// IMPORTANT NOTE on this behavior:
|
|
216
|
+
// Context: At Remote we have a lot of global customization that run equally across multiple different JSON Schemas.
|
|
217
|
+
// With this, we avoid applying customizations to non-existing fields. (aka create fields)
|
|
218
|
+
// That's why we have the "create" config, specific to create new fields.
|
|
219
|
+
const result = modify(schemaPet, {
|
|
220
|
+
fields: {
|
|
221
|
+
unknown_field: {
|
|
222
|
+
title: 'This field does not exist in the original schema',
|
|
223
|
+
},
|
|
224
|
+
'nested.field': {
|
|
225
|
+
title: 'Nop',
|
|
226
|
+
},
|
|
227
|
+
pet_name: {
|
|
228
|
+
title: 'New pet title',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
expect(result.schema.properties.unknown_field).toBeUndefined();
|
|
234
|
+
expect(result.schema.properties.nested).toBeUndefined();
|
|
235
|
+
expect(result.schema.properties.pet_name).toEqual({
|
|
236
|
+
...schemaPet.properties.pet_name,
|
|
237
|
+
title: 'New pet title',
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
expect(result.warnings).toEqual([
|
|
241
|
+
{
|
|
242
|
+
type: 'FIELD_TO_CHANGE_NOT_FOUND',
|
|
243
|
+
message: 'Changing field "unknown_field" was ignored because it does not exist.',
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
type: 'FIELD_TO_CHANGE_NOT_FOUND',
|
|
247
|
+
message: 'Changing field "nested.field" was ignored because it does not exist.',
|
|
248
|
+
},
|
|
249
|
+
]);
|
|
250
|
+
});
|
|
251
|
+
|
|
174
252
|
it('replace all fields', () => {
|
|
175
253
|
const result = modify(schemaPet, {
|
|
176
254
|
allFields: (fieldName, fieldAttrs) => {
|
|
@@ -188,7 +266,7 @@ describe('modify() - basic mutations', () => {
|
|
|
188
266
|
},
|
|
189
267
|
});
|
|
190
268
|
|
|
191
|
-
expect(result).toMatchObject({
|
|
269
|
+
expect(result.schema).toMatchObject({
|
|
192
270
|
properties: {
|
|
193
271
|
has_pet: {
|
|
194
272
|
dataFoo: 'abc',
|
|
@@ -203,6 +281,7 @@ describe('modify() - basic mutations', () => {
|
|
|
203
281
|
styleDecimals: 2,
|
|
204
282
|
},
|
|
205
283
|
pet_address: {
|
|
284
|
+
// assert recursivity
|
|
206
285
|
properties: {
|
|
207
286
|
street: {
|
|
208
287
|
dataFoo: 'abc',
|
|
@@ -213,7 +292,7 @@ describe('modify() - basic mutations', () => {
|
|
|
213
292
|
});
|
|
214
293
|
});
|
|
215
294
|
|
|
216
|
-
it('replace field
|
|
295
|
+
it('replace field attrs that are arrays (partial)', () => {
|
|
217
296
|
const result = modify(schemaPet, {
|
|
218
297
|
fields: {
|
|
219
298
|
has_pet: (fieldAttrs) => {
|
|
@@ -239,7 +318,7 @@ describe('modify() - basic mutations', () => {
|
|
|
239
318
|
},
|
|
240
319
|
});
|
|
241
320
|
|
|
242
|
-
expect(result).toMatchObject({
|
|
321
|
+
expect(result.schema).toMatchObject({
|
|
243
322
|
properties: {
|
|
244
323
|
has_pet: {
|
|
245
324
|
oneOf: [
|
|
@@ -257,7 +336,30 @@ describe('modify() - basic mutations', () => {
|
|
|
257
336
|
});
|
|
258
337
|
});
|
|
259
338
|
|
|
260
|
-
it('
|
|
339
|
+
it('replace field attrs that are arrays (full)', () => {
|
|
340
|
+
const result = modify(schemaPet, {
|
|
341
|
+
fields: {
|
|
342
|
+
has_pet: {
|
|
343
|
+
oneOf: [{ const: 'yaaas', title: 'YAAS!' }],
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
expect(result.schema).toMatchObject({
|
|
349
|
+
properties: {
|
|
350
|
+
has_pet: {
|
|
351
|
+
oneOf: [
|
|
352
|
+
{
|
|
353
|
+
const: 'yaaas',
|
|
354
|
+
title: 'YAAS!',
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('customize x-jsf-errorMessage (shorthand)', () => {
|
|
261
363
|
const result = modify(schemaPet, {
|
|
262
364
|
fields: {
|
|
263
365
|
pet_age: (fieldAttrs) => {
|
|
@@ -277,7 +379,7 @@ describe('modify() - basic mutations', () => {
|
|
|
277
379
|
// ...
|
|
278
380
|
});
|
|
279
381
|
|
|
280
|
-
expect(result).toMatchObject({
|
|
382
|
+
expect(result.schema).toMatchObject({
|
|
281
383
|
properties: {
|
|
282
384
|
pet_age: {
|
|
283
385
|
'x-jsf-errorMessage': {
|
|
@@ -297,4 +399,418 @@ describe('modify() - basic mutations', () => {
|
|
|
297
399
|
},
|
|
298
400
|
});
|
|
299
401
|
});
|
|
402
|
+
|
|
403
|
+
it('customize x-jsf-presentation (shorthand)', () => {
|
|
404
|
+
const result = modify(schemaPet, {
|
|
405
|
+
fields: {
|
|
406
|
+
pet_age: () => {
|
|
407
|
+
return {
|
|
408
|
+
presentation: {
|
|
409
|
+
'data-foo': 123,
|
|
410
|
+
},
|
|
411
|
+
};
|
|
412
|
+
},
|
|
413
|
+
'pet_address.street': {
|
|
414
|
+
presentation: {
|
|
415
|
+
'data-foo': 456,
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const originalPetAgePresentation = schemaPet.properties.pet_age['x-jsf-presentation'];
|
|
422
|
+
expect(originalPetAgePresentation).toBeDefined();
|
|
423
|
+
|
|
424
|
+
const originalPetStreetPresentation =
|
|
425
|
+
schemaPet.properties.pet_address.properties.street['x-jsf-presentation'];
|
|
426
|
+
expect(originalPetStreetPresentation).toBeDefined();
|
|
427
|
+
|
|
428
|
+
expect(result.schema).toMatchObject({
|
|
429
|
+
properties: {
|
|
430
|
+
pet_age: {
|
|
431
|
+
'x-jsf-presentation': {
|
|
432
|
+
...originalPetAgePresentation,
|
|
433
|
+
'data-foo': 123,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
pet_address: {
|
|
437
|
+
properties: {
|
|
438
|
+
street: {
|
|
439
|
+
'x-jsf-presentation': {
|
|
440
|
+
...originalPetStreetPresentation,
|
|
441
|
+
'data-foo': 456,
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
const schemaTickets = {
|
|
452
|
+
properties: {
|
|
453
|
+
age: {
|
|
454
|
+
title: 'Age',
|
|
455
|
+
type: 'integer',
|
|
456
|
+
},
|
|
457
|
+
quantity: {
|
|
458
|
+
title: 'Quantity',
|
|
459
|
+
type: 'integer',
|
|
460
|
+
},
|
|
461
|
+
has_premium: {
|
|
462
|
+
title: 'Has premium',
|
|
463
|
+
type: 'string',
|
|
464
|
+
},
|
|
465
|
+
premium_id: {
|
|
466
|
+
title: 'Premium ID',
|
|
467
|
+
type: 'boolean',
|
|
468
|
+
},
|
|
469
|
+
reason: {
|
|
470
|
+
title: 'Why not premium?',
|
|
471
|
+
type: 'string',
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
'x-jsf-order': ['age', 'quantity', 'has_premium', 'premium_id', 'reason'],
|
|
475
|
+
allOf: [
|
|
476
|
+
{
|
|
477
|
+
// Empty conditional to sanity test empty cases
|
|
478
|
+
if: {},
|
|
479
|
+
then: {},
|
|
480
|
+
else: {},
|
|
481
|
+
},
|
|
482
|
+
// Create two conditionals to test both get matched
|
|
483
|
+
{
|
|
484
|
+
if: {
|
|
485
|
+
has_premium: {
|
|
486
|
+
const: 'yes',
|
|
487
|
+
},
|
|
488
|
+
required: ['has_premium'],
|
|
489
|
+
},
|
|
490
|
+
then: {
|
|
491
|
+
required: ['premium_id'],
|
|
492
|
+
},
|
|
493
|
+
else: {},
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
if: {
|
|
497
|
+
properties: {
|
|
498
|
+
has_premium: {
|
|
499
|
+
const: 'no',
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
required: ['has_premium'],
|
|
503
|
+
},
|
|
504
|
+
then: {
|
|
505
|
+
properties: {
|
|
506
|
+
reason: false,
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
else: {},
|
|
510
|
+
},
|
|
511
|
+
],
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
describe('modify() - reoder fields', () => {
|
|
515
|
+
it('reorder fields - basic usage', () => {
|
|
516
|
+
const baseExample = {
|
|
517
|
+
properties: {
|
|
518
|
+
/* does not matter */
|
|
519
|
+
},
|
|
520
|
+
'x-jsf-order': ['field_a', 'field_b', 'field_c', 'field_d'],
|
|
521
|
+
};
|
|
522
|
+
const result = modify(baseExample, {
|
|
523
|
+
orderRoot: ['field_c', 'field_b'],
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// 💡 Note how the missing field (field_d) was added to the end as safety measure.
|
|
527
|
+
expect(result.schema).toMatchObject({
|
|
528
|
+
'x-jsf-order': ['field_c', 'field_b', 'field_a', 'field_d'],
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
expect(result.warnings).toMatchObject([
|
|
532
|
+
{
|
|
533
|
+
type: 'ORDER_MISSING_FIELDS',
|
|
534
|
+
message:
|
|
535
|
+
'Some fields got forgotten in the new order. They were automatically appended: field_a, field_d',
|
|
536
|
+
},
|
|
537
|
+
]);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('reorder fields - basic usage fallback', () => {
|
|
541
|
+
const baseExample = {
|
|
542
|
+
properties: {
|
|
543
|
+
/* does not matter */
|
|
544
|
+
},
|
|
545
|
+
};
|
|
546
|
+
const result = modify(baseExample, {
|
|
547
|
+
orderRoot: ['field_c', 'field_b'],
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// Does not explode if it doesn't have an original order.
|
|
551
|
+
expect(result.schema).toMatchObject({
|
|
552
|
+
'x-jsf-order': ['field_c', 'field_b'],
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
expect(result.warnings).toEqual([]);
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
it('reorder fields - as callback based on original order', () => {
|
|
559
|
+
const baseExample = {
|
|
560
|
+
properties: {
|
|
561
|
+
/* does not matter */
|
|
562
|
+
},
|
|
563
|
+
'x-jsf-order': ['field_a', 'field_b', 'field_c', 'field_d'],
|
|
564
|
+
};
|
|
565
|
+
const result = modify(baseExample, {
|
|
566
|
+
orderRoot: (original) => original.reverse(),
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
expect(result.schema).toMatchObject({
|
|
570
|
+
'x-jsf-order': ['field_d', 'field_c', 'field_b', 'field_a'],
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it('reorder fields in fieldsets (through config.fields)', () => {
|
|
575
|
+
// NOTE: A better API is needed but we decided to not implement it yet
|
|
576
|
+
// as we didn't agreed on the best DX. Check PR #78 for proposed APIs.
|
|
577
|
+
// Until then this is the workaround.
|
|
578
|
+
// Note the warning "ORDER_MISSING_FIELDS" won't be added.
|
|
579
|
+
|
|
580
|
+
const baseExample = {
|
|
581
|
+
properties: {
|
|
582
|
+
address: {
|
|
583
|
+
properties: {
|
|
584
|
+
/* does not matter */
|
|
585
|
+
},
|
|
586
|
+
'x-jsf-order': ['first_line', 'zipcode', 'city'],
|
|
587
|
+
},
|
|
588
|
+
age: {
|
|
589
|
+
/* ... */
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
'x-jsf-order': ['address', 'age'],
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const result = modify(baseExample, {
|
|
596
|
+
fields: {
|
|
597
|
+
address: (attrs) => {
|
|
598
|
+
// eslint-disable-next-line no-unused-vars
|
|
599
|
+
const [_firstLine, ...restOrder] = attrs['x-jsf-order'];
|
|
600
|
+
return { 'x-jsf-order': restOrder.reverse() }; // ['city', 'zipcode']
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
expect(result.schema).toMatchObject({
|
|
606
|
+
properties: {
|
|
607
|
+
address: {
|
|
608
|
+
// Note how first_line was NOT appended
|
|
609
|
+
'x-jsf-order': ['city', 'zipcode'],
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
});
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
describe('modify() - create fields', () => {
|
|
617
|
+
it('create base field', () => {
|
|
618
|
+
const result = modify(schemaAddress, {
|
|
619
|
+
create: {
|
|
620
|
+
new_field: {
|
|
621
|
+
title: 'New field',
|
|
622
|
+
type: 'string',
|
|
623
|
+
},
|
|
624
|
+
address: {
|
|
625
|
+
someAttr: 'foo',
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
expect(result.schema).toMatchObject({
|
|
631
|
+
properties: {
|
|
632
|
+
new_field: {
|
|
633
|
+
title: 'New field',
|
|
634
|
+
type: 'string',
|
|
635
|
+
},
|
|
636
|
+
address: schemaAddress.properties.address,
|
|
637
|
+
},
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
// this is ignored because the field already exists
|
|
641
|
+
expect(result.schema.properties.address.someAttr).toBe(undefined);
|
|
642
|
+
|
|
643
|
+
expect(result.warnings).toEqual([
|
|
644
|
+
{
|
|
645
|
+
type: 'FIELD_TO_CREATE_EXISTS',
|
|
646
|
+
message: 'Creating field "address" was ignored because it already exists.',
|
|
647
|
+
},
|
|
648
|
+
]);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('create nested field', () => {
|
|
652
|
+
const result = modify(schemaAddress, {
|
|
653
|
+
create: {
|
|
654
|
+
// Pointer as string
|
|
655
|
+
'address.state': {
|
|
656
|
+
title: 'State',
|
|
657
|
+
},
|
|
658
|
+
// Pointer as object
|
|
659
|
+
address: {
|
|
660
|
+
someAttr: 'foo',
|
|
661
|
+
properties: {
|
|
662
|
+
district: {
|
|
663
|
+
title: 'District',
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
},
|
|
667
|
+
// Ignore field street because the field already exists [1]
|
|
668
|
+
'address.street': {
|
|
669
|
+
title: 'Foo',
|
|
670
|
+
},
|
|
671
|
+
},
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
expect(result.schema.properties.address.properties).toMatchObject({
|
|
675
|
+
...schemaAddress.properties.address.properties,
|
|
676
|
+
state: {
|
|
677
|
+
title: 'State',
|
|
678
|
+
},
|
|
679
|
+
district: {
|
|
680
|
+
title: 'District',
|
|
681
|
+
},
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
// Ignore address.someAttr because the address itself already exists.
|
|
685
|
+
expect(result.schema.properties.address.someAttr).toBeUndefined();
|
|
686
|
+
|
|
687
|
+
// Ignore field street because it already exists [1]
|
|
688
|
+
expect(result.schema.properties.address.properties.street.title).toBe('Street');
|
|
689
|
+
|
|
690
|
+
expect(result.warnings).toEqual([
|
|
691
|
+
{
|
|
692
|
+
type: 'FIELD_TO_CREATE_EXISTS',
|
|
693
|
+
message: 'Creating field "address" was ignored because it already exists.',
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
type: 'FIELD_TO_CREATE_EXISTS',
|
|
697
|
+
message: 'Creating field "address.street" was ignored because it already exists.',
|
|
698
|
+
},
|
|
699
|
+
]);
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
describe('modify() - pick fields', () => {
|
|
704
|
+
it('basic usage', () => {
|
|
705
|
+
const { schema, warnings } = modify(schemaTickets, {
|
|
706
|
+
pick: ['quantity'],
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// Note how the other fields got removed from
|
|
710
|
+
// from the root properties, the "order" and "allOf".
|
|
711
|
+
expect(schema.properties).toEqual({
|
|
712
|
+
quantity: {
|
|
713
|
+
title: 'Quantity',
|
|
714
|
+
type: 'integer',
|
|
715
|
+
},
|
|
716
|
+
});
|
|
717
|
+
expect(schema.properties.age).toBeUndefined();
|
|
718
|
+
expect(schema.properties.has_premium).toBeUndefined();
|
|
719
|
+
expect(schema.properties.premium_id).toBeUndefined();
|
|
720
|
+
|
|
721
|
+
expect(schema['x-jsf-order']).toEqual(['quantity']);
|
|
722
|
+
expect(schema.allOf).toEqual([]); // conditional got removed.
|
|
723
|
+
|
|
724
|
+
expect(warnings).toHaveLength(0);
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
it('related conditionals are kept - (else)', () => {
|
|
728
|
+
const { schema, warnings } = modify(schemaTickets, {
|
|
729
|
+
pick: ['has_premium'],
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
expect(schema).toMatchObject({
|
|
733
|
+
properties: {
|
|
734
|
+
has_premium: {
|
|
735
|
+
title: 'Has premium',
|
|
736
|
+
},
|
|
737
|
+
premium_id: {
|
|
738
|
+
title: 'Premium ID',
|
|
739
|
+
},
|
|
740
|
+
reason: {
|
|
741
|
+
title: 'Why not premium?',
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
allOf: [schemaTickets.allOf[1], schemaTickets.allOf[2]],
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
expect(schema.properties.quantity).toBeUndefined();
|
|
748
|
+
expect(schema.properties.age).toBeUndefined();
|
|
749
|
+
expect(warnings).toEqual([
|
|
750
|
+
{
|
|
751
|
+
type: 'PICK_MISSED_FIELD',
|
|
752
|
+
message:
|
|
753
|
+
'The picked fields are in conditionals that refeer other fields. They added automatically: "premium_id", "reason". Check "meta" for more details.',
|
|
754
|
+
meta: { premium_id: { path: 'allOf[1].then' }, reason: { path: 'allOf[2].then' } },
|
|
755
|
+
},
|
|
756
|
+
]);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('related conditionals are kept - (if)', () => {
|
|
760
|
+
const { schema, warnings } = modify(schemaTickets, {
|
|
761
|
+
pick: ['premium_id'],
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
expect(schema).toMatchObject({
|
|
765
|
+
properties: {
|
|
766
|
+
has_premium: {
|
|
767
|
+
title: 'Has premium',
|
|
768
|
+
},
|
|
769
|
+
premium_id: {
|
|
770
|
+
title: 'Premium ID',
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
allOf: [schemaTickets.allOf[0]],
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
expect(schema.properties.quantity).toBeUndefined();
|
|
777
|
+
expect(schema.properties.age).toBeUndefined();
|
|
778
|
+
expect(warnings).toEqual([
|
|
779
|
+
{
|
|
780
|
+
type: 'PICK_MISSED_FIELD',
|
|
781
|
+
message:
|
|
782
|
+
'The picked fields are in conditionals that refeer other fields. They added automatically: "has_premium". Check "meta" for more details.',
|
|
783
|
+
meta: { has_premium: { path: 'allOf[1].if' } },
|
|
784
|
+
},
|
|
785
|
+
]);
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
it('reorder only handles the picked fields', () => {
|
|
789
|
+
const { schema, warnings } = modify(schemaTickets, {
|
|
790
|
+
pick: ['age', 'quantity'],
|
|
791
|
+
orderRoot: (original) => original.reverse(),
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
// The order only includes those 2 fields
|
|
795
|
+
expect(schema['x-jsf-order']).toEqual(['quantity', 'age']);
|
|
796
|
+
// There are no warnings about forgotten fields.
|
|
797
|
+
expect(warnings).toHaveLength(0);
|
|
798
|
+
|
|
799
|
+
// Sanity check the result
|
|
800
|
+
expect(schema.properties.quantity).toBeDefined();
|
|
801
|
+
expect(schema.properties.age).toBeDefined();
|
|
802
|
+
expect(schema.properties.has_premium).toBeUndefined();
|
|
803
|
+
expect(schema.properties.premium_id).toBeUndefined();
|
|
804
|
+
expect(schema.allOf).toEqual([]);
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// For later on when needed.
|
|
808
|
+
it.todo('ignore conditionals with unpicked fields');
|
|
809
|
+
|
|
810
|
+
it.todo('pick nested fields (fieldsets)');
|
|
811
|
+
/* Use cases:
|
|
812
|
+
- conditionals inside fieldstes. eg properties.family.allOf[0].if...
|
|
813
|
+
- conditional in the root pointing to nested fields: eg if properties.family.properties.simblings is 0 then hide properties.playTogether ...
|
|
814
|
+
- variations of each one of these similar to the existing tests.
|
|
815
|
+
*/
|
|
300
816
|
});
|