@kravc/schema 2.7.5 → 2.8.0-alpha.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/README.md +19 -14
- package/dist/CredentialFactory.d.ts +345 -0
- package/dist/CredentialFactory.d.ts.map +1 -0
- package/dist/CredentialFactory.js +381 -0
- package/dist/CredentialFactory.js.map +1 -0
- package/dist/Schema.d.ts +448 -0
- package/dist/Schema.d.ts.map +1 -0
- package/dist/Schema.js +506 -0
- package/dist/Schema.js.map +1 -0
- package/dist/ValidationError.d.ts +70 -0
- package/dist/ValidationError.d.ts.map +1 -0
- package/dist/ValidationError.js +78 -0
- package/dist/ValidationError.js.map +1 -0
- package/dist/Validator.d.ts +483 -0
- package/dist/Validator.d.ts.map +1 -0
- package/dist/Validator.js +570 -0
- package/dist/Validator.js.map +1 -0
- package/dist/helpers/JsonSchema.d.ts +99 -0
- package/dist/helpers/JsonSchema.d.ts.map +1 -0
- package/dist/helpers/JsonSchema.js +3 -0
- package/dist/helpers/JsonSchema.js.map +1 -0
- package/dist/helpers/cleanupAttributes.d.ts +34 -0
- package/dist/helpers/cleanupAttributes.d.ts.map +1 -0
- package/dist/helpers/cleanupAttributes.js +113 -0
- package/dist/helpers/cleanupAttributes.js.map +1 -0
- package/dist/helpers/cleanupNulls.d.ts +27 -0
- package/dist/helpers/cleanupNulls.d.ts.map +1 -0
- package/dist/helpers/cleanupNulls.js +96 -0
- package/dist/helpers/cleanupNulls.js.map +1 -0
- package/dist/helpers/getReferenceIds.d.ts +169 -0
- package/dist/helpers/getReferenceIds.d.ts.map +1 -0
- package/dist/helpers/getReferenceIds.js +241 -0
- package/dist/helpers/getReferenceIds.js.map +1 -0
- package/dist/helpers/got.d.ts +60 -0
- package/dist/helpers/got.d.ts.map +1 -0
- package/dist/helpers/got.js +72 -0
- package/dist/helpers/got.js.map +1 -0
- package/dist/helpers/mapObjectProperties.d.ts +150 -0
- package/dist/helpers/mapObjectProperties.d.ts.map +1 -0
- package/dist/helpers/mapObjectProperties.js +229 -0
- package/dist/helpers/mapObjectProperties.js.map +1 -0
- package/dist/helpers/normalizeAttributes.d.ts +213 -0
- package/dist/helpers/normalizeAttributes.d.ts.map +1 -0
- package/dist/helpers/normalizeAttributes.js +243 -0
- package/dist/helpers/normalizeAttributes.js.map +1 -0
- package/dist/helpers/normalizeProperties.d.ts +168 -0
- package/dist/helpers/normalizeProperties.d.ts.map +1 -0
- package/dist/helpers/normalizeProperties.js +223 -0
- package/dist/helpers/normalizeProperties.js.map +1 -0
- package/dist/helpers/normalizeRequired.d.ts +159 -0
- package/dist/helpers/normalizeRequired.d.ts.map +1 -0
- package/dist/helpers/normalizeRequired.js +206 -0
- package/dist/helpers/normalizeRequired.js.map +1 -0
- package/dist/helpers/normalizeType.d.ts +81 -0
- package/dist/helpers/normalizeType.d.ts.map +1 -0
- package/dist/helpers/normalizeType.js +210 -0
- package/dist/helpers/normalizeType.js.map +1 -0
- package/dist/helpers/nullifyEmptyValues.d.ts +139 -0
- package/dist/helpers/nullifyEmptyValues.d.ts.map +1 -0
- package/dist/helpers/nullifyEmptyValues.js +191 -0
- package/dist/helpers/nullifyEmptyValues.js.map +1 -0
- package/dist/helpers/removeRequiredAndDefault.d.ts +106 -0
- package/dist/helpers/removeRequiredAndDefault.d.ts.map +1 -0
- package/dist/helpers/removeRequiredAndDefault.js +138 -0
- package/dist/helpers/removeRequiredAndDefault.js.map +1 -0
- package/dist/helpers/validateId.d.ts +39 -0
- package/dist/helpers/validateId.d.ts.map +1 -0
- package/dist/helpers/validateId.js +51 -0
- package/dist/helpers/validateId.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/ld/documentLoader.d.ts +8 -0
- package/dist/ld/documentLoader.d.ts.map +1 -0
- package/dist/ld/documentLoader.js +24 -0
- package/dist/ld/documentLoader.js.map +1 -0
- package/dist/ld/getLinkedDataAttributeType.d.ts +10 -0
- package/dist/ld/getLinkedDataAttributeType.d.ts.map +1 -0
- package/dist/ld/getLinkedDataAttributeType.js +32 -0
- package/dist/ld/getLinkedDataAttributeType.js.map +1 -0
- package/dist/ld/getLinkedDataContext.d.ts +19 -0
- package/dist/ld/getLinkedDataContext.d.ts.map +1 -0
- package/dist/ld/getLinkedDataContext.js +50 -0
- package/dist/ld/getLinkedDataContext.js.map +1 -0
- package/eslint.config.mjs +32 -52
- package/examples/credentials/createAccountCredential.ts +27 -0
- package/examples/credentials/createMineSweeperScoreCredential.ts +115 -0
- package/examples/index.ts +7 -0
- package/examples/schemas/FavoriteItemSchema.ts +27 -0
- package/examples/{Preferences.yaml → schemas/Preferences.yaml} +2 -0
- package/examples/schemas/PreferencesSchema.ts +29 -0
- package/examples/schemas/ProfileSchema.ts +91 -0
- package/examples/schemas/Status.yaml +3 -0
- package/examples/schemas/StatusSchema.ts +12 -0
- package/jest.config.mjs +5 -0
- package/package.json +28 -21
- package/src/CredentialFactory.ts +392 -0
- package/src/Schema.ts +583 -0
- package/src/ValidationError.ts +90 -0
- package/src/Validator.ts +603 -0
- package/src/__tests__/CredentialFactory.test.ts +588 -0
- package/src/__tests__/Schema.test.ts +371 -0
- package/src/__tests__/ValidationError.test.ts +235 -0
- package/src/__tests__/Validator.test.ts +787 -0
- package/src/helpers/JsonSchema.ts +119 -0
- package/src/helpers/__tests__/cleanupAttributes.test.ts +943 -0
- package/src/helpers/__tests__/cleanupNulls.test.ts +772 -0
- package/src/helpers/__tests__/getReferenceIds.test.ts +975 -0
- package/src/helpers/__tests__/got.test.ts +193 -0
- package/src/helpers/__tests__/mapObjectProperties.test.ts +1126 -0
- package/src/helpers/__tests__/normalizeAttributes.test.ts +1435 -0
- package/src/helpers/__tests__/normalizeProperties.test.ts +727 -0
- package/src/helpers/__tests__/normalizeRequired.test.ts +669 -0
- package/src/helpers/__tests__/normalizeType.test.ts +772 -0
- package/src/helpers/__tests__/nullifyEmptyValues.test.ts +735 -0
- package/src/helpers/__tests__/removeRequiredAndDefault.test.ts +734 -0
- package/src/helpers/__tests__/validateId.test.ts +118 -0
- package/src/helpers/cleanupAttributes.ts +151 -0
- package/src/helpers/cleanupNulls.ts +106 -0
- package/src/helpers/getReferenceIds.ts +273 -0
- package/src/helpers/got.ts +73 -0
- package/src/helpers/mapObjectProperties.ts +272 -0
- package/src/helpers/normalizeAttributes.ts +247 -0
- package/src/helpers/normalizeProperties.ts +249 -0
- package/src/helpers/normalizeRequired.ts +233 -0
- package/src/helpers/normalizeType.ts +235 -0
- package/src/helpers/nullifyEmptyValues.ts +207 -0
- package/src/helpers/removeRequiredAndDefault.ts +151 -0
- package/src/helpers/validateId.ts +53 -0
- package/src/index.ts +13 -0
- package/src/ld/__tests__/documentLoader.test.ts +57 -0
- package/src/ld/__tests__/getLinkedDataAttributeType.test.ts +212 -0
- package/src/ld/__tests__/getLinkedDataContext.test.ts +378 -0
- package/src/ld/documentLoader.ts +28 -0
- package/src/ld/getLinkedDataAttributeType.ts +46 -0
- package/src/ld/getLinkedDataContext.ts +80 -0
- package/tsconfig.json +27 -0
- package/types/credentials-context.d.ts +14 -0
- package/types/security-context.d.ts +6 -0
- package/examples/Status.yaml +0 -3
- package/examples/createAccountCredential.js +0 -27
- package/examples/createMineSweeperScoreCredential.js +0 -63
- package/examples/index.js +0 -9
- package/src/CredentialFactory.js +0 -67
- package/src/CredentialFactory.spec.js +0 -131
- package/src/Schema.js +0 -104
- package/src/Schema.spec.js +0 -172
- package/src/ValidationError.js +0 -31
- package/src/Validator.js +0 -128
- package/src/Validator.spec.js +0 -355
- package/src/helpers/cleanupAttributes.js +0 -71
- package/src/helpers/cleanupNulls.js +0 -42
- package/src/helpers/getReferenceIds.js +0 -71
- package/src/helpers/mapObject.js +0 -65
- package/src/helpers/normalizeAttributes.js +0 -28
- package/src/helpers/normalizeProperties.js +0 -61
- package/src/helpers/normalizeRequired.js +0 -37
- package/src/helpers/normalizeType.js +0 -41
- package/src/helpers/nullifyEmptyValues.js +0 -57
- package/src/helpers/removeRequiredAndDefault.js +0 -30
- package/src/helpers/validateId.js +0 -19
- package/src/index.d.ts +0 -25
- package/src/index.js +0 -8
- package/src/ld/documentLoader.js +0 -25
- package/src/ld/documentLoader.spec.js +0 -12
- package/src/ld/getLinkedDataContext.js +0 -63
- package/src/ld/getLinkedDataType.js +0 -38
- /package/examples/{FavoriteItem.yaml → schemas/FavoriteItem.yaml} +0 -0
- /package/examples/{Profile.yaml → schemas/Profile.yaml} +0 -0
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
import nullifyEmptyValues from '../nullifyEmptyValues';
|
|
2
|
+
import { schemaSymbol, jsonSymbol } from 'z-schema';
|
|
3
|
+
import type { SchemaErrorDetail } from 'z-schema';
|
|
4
|
+
|
|
5
|
+
describe('nullifyEmptyValues(object, validationErrors)', () => {
|
|
6
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
7
|
+
const createMockError = (
|
|
8
|
+
code: string,
|
|
9
|
+
path: string,
|
|
10
|
+
json: unknown,
|
|
11
|
+
schema: unknown = {}
|
|
12
|
+
): SchemaErrorDetail => {
|
|
13
|
+
const error = {
|
|
14
|
+
code,
|
|
15
|
+
path,
|
|
16
|
+
message: `Error at ${path}`,
|
|
17
|
+
params: [],
|
|
18
|
+
description: `Error at ${path}`,
|
|
19
|
+
inner: [],
|
|
20
|
+
} as SchemaErrorDetail;
|
|
21
|
+
|
|
22
|
+
// Attach symbols to the error object
|
|
23
|
+
(error as SchemaErrorDetail)[schemaSymbol] = schema;
|
|
24
|
+
(error as SchemaErrorDetail)[jsonSymbol] = json;
|
|
25
|
+
|
|
26
|
+
return error;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe('format errors with empty strings', () => {
|
|
30
|
+
it('should replace empty string with null for PATTERN error', () => {
|
|
31
|
+
const object = { field: '' };
|
|
32
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
33
|
+
const validationErrors = [error];
|
|
34
|
+
|
|
35
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
36
|
+
|
|
37
|
+
expect(result.field).toBeNull();
|
|
38
|
+
expect(remainingErrors).toHaveLength(0);
|
|
39
|
+
// Original object should not be modified
|
|
40
|
+
expect(object.field).toBe('');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should replace empty string with null for ENUM_MISMATCH error', () => {
|
|
44
|
+
const object = { field: '' };
|
|
45
|
+
const error = createMockError('ENUM_MISMATCH', '#/field', object);
|
|
46
|
+
const validationErrors = [error];
|
|
47
|
+
|
|
48
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
49
|
+
|
|
50
|
+
expect(result.field).toBeNull();
|
|
51
|
+
expect(remainingErrors).toHaveLength(0);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should replace empty string with null for INVALID_FORMAT error', () => {
|
|
55
|
+
const object = { field: '' };
|
|
56
|
+
const error = createMockError('INVALID_FORMAT', '#/field', object);
|
|
57
|
+
const validationErrors = [error];
|
|
58
|
+
|
|
59
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
60
|
+
|
|
61
|
+
expect(result.field).toBeNull();
|
|
62
|
+
expect(remainingErrors).toHaveLength(0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should handle nested paths', () => {
|
|
66
|
+
const object = { nested: { field: '' } };
|
|
67
|
+
const error = createMockError('PATTERN', '#/nested/field', object);
|
|
68
|
+
const validationErrors = [error];
|
|
69
|
+
|
|
70
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
71
|
+
|
|
72
|
+
expect(result.nested.field).toBeNull();
|
|
73
|
+
expect(remainingErrors).toHaveLength(0);
|
|
74
|
+
expect(object.nested.field).toBe('');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should handle deeply nested paths', () => {
|
|
78
|
+
const object = { level1: { level2: { level3: { field: '' } } } };
|
|
79
|
+
const error = createMockError('PATTERN', '#/level1/level2/level3/field', object);
|
|
80
|
+
const validationErrors = [error];
|
|
81
|
+
|
|
82
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
83
|
+
|
|
84
|
+
expect(result.level1.level2.level3.field).toBeNull();
|
|
85
|
+
expect(remainingErrors).toHaveLength(0);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should handle multiple empty string fields', () => {
|
|
89
|
+
const object = { field1: '', field2: '', field3: 'value' };
|
|
90
|
+
const error1 = createMockError('PATTERN', '#/field1', object);
|
|
91
|
+
const error2 = createMockError('ENUM_MISMATCH', '#/field2', object);
|
|
92
|
+
const validationErrors = [error1, error2];
|
|
93
|
+
|
|
94
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
95
|
+
|
|
96
|
+
expect(result.field1).toBeNull();
|
|
97
|
+
expect(result.field2).toBeNull();
|
|
98
|
+
expect(result.field3).toBe('value');
|
|
99
|
+
expect(remainingErrors).toHaveLength(0);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should handle array paths', () => {
|
|
103
|
+
const object = { items: ['', 'value', ''] };
|
|
104
|
+
const error1 = createMockError('PATTERN', '#/items/0', object);
|
|
105
|
+
const error2 = createMockError('PATTERN', '#/items/2', object);
|
|
106
|
+
const validationErrors = [error1, error2];
|
|
107
|
+
|
|
108
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
109
|
+
|
|
110
|
+
expect(result.items[0]).toBeNull();
|
|
111
|
+
expect(result.items[1]).toBe('value');
|
|
112
|
+
expect(result.items[2]).toBeNull();
|
|
113
|
+
expect(remainingErrors).toHaveLength(0);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('required attributes', () => {
|
|
118
|
+
it('should not nullify empty string if attribute is required', () => {
|
|
119
|
+
const object = { field: '' };
|
|
120
|
+
const schema = { 'x-required': true };
|
|
121
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
122
|
+
const validationErrors = [error];
|
|
123
|
+
|
|
124
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
125
|
+
|
|
126
|
+
expect(result.field).toBe('');
|
|
127
|
+
expect(remainingErrors).toHaveLength(1);
|
|
128
|
+
expect(remainingErrors[0]).toBe(error);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should not nullify if x-required is false', () => {
|
|
132
|
+
const object = { field: '' };
|
|
133
|
+
const schema = { 'x-required': false };
|
|
134
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
135
|
+
const validationErrors = [error];
|
|
136
|
+
|
|
137
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
138
|
+
|
|
139
|
+
expect(result.field).toBeNull();
|
|
140
|
+
expect(remainingErrors).toHaveLength(0);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should not nullify if x-required is undefined', () => {
|
|
144
|
+
const object = { field: '' };
|
|
145
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
146
|
+
const validationErrors = [error];
|
|
147
|
+
|
|
148
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
149
|
+
|
|
150
|
+
expect(result.field).toBeNull();
|
|
151
|
+
expect(remainingErrors).toHaveLength(0);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('non-format errors', () => {
|
|
156
|
+
it('should not nullify for INVALID_TYPE error', () => {
|
|
157
|
+
const object = { field: '' };
|
|
158
|
+
const error = createMockError('INVALID_TYPE', '#/field', object);
|
|
159
|
+
const validationErrors = [error];
|
|
160
|
+
|
|
161
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
162
|
+
|
|
163
|
+
expect(result.field).toBe('');
|
|
164
|
+
expect(remainingErrors).toHaveLength(1);
|
|
165
|
+
expect(remainingErrors[0]).toBe(error);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should not nullify for MIN_LENGTH error', () => {
|
|
169
|
+
const object = { field: '' };
|
|
170
|
+
const error = createMockError('MIN_LENGTH', '#/field', object);
|
|
171
|
+
const validationErrors = [error];
|
|
172
|
+
|
|
173
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
174
|
+
|
|
175
|
+
expect(result.field).toBe('');
|
|
176
|
+
expect(remainingErrors).toHaveLength(1);
|
|
177
|
+
expect(remainingErrors[0]).toBe(error);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should not nullify for MAX_LENGTH error', () => {
|
|
181
|
+
const object = { field: '' };
|
|
182
|
+
const error = createMockError('MAX_LENGTH', '#/field', object);
|
|
183
|
+
const validationErrors = [error];
|
|
184
|
+
|
|
185
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
186
|
+
|
|
187
|
+
expect(result.field).toBe('');
|
|
188
|
+
expect(remainingErrors).toHaveLength(1);
|
|
189
|
+
expect(remainingErrors[0]).toBe(error);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe('non-empty values', () => {
|
|
194
|
+
it('should not nullify non-empty string values', () => {
|
|
195
|
+
const object = { field: 'value' };
|
|
196
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
197
|
+
const validationErrors = [error];
|
|
198
|
+
|
|
199
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
200
|
+
|
|
201
|
+
expect(result.field).toBe('value');
|
|
202
|
+
expect(remainingErrors).toHaveLength(1);
|
|
203
|
+
expect(remainingErrors[0]).toBe(error);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should not nullify number values', () => {
|
|
207
|
+
const object = { field: 0 };
|
|
208
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
209
|
+
const validationErrors = [error];
|
|
210
|
+
|
|
211
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
212
|
+
|
|
213
|
+
expect(result.field).toBe(0);
|
|
214
|
+
expect(remainingErrors).toHaveLength(1);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should not nullify null values', () => {
|
|
218
|
+
const object = { field: null };
|
|
219
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
220
|
+
const validationErrors = [error];
|
|
221
|
+
|
|
222
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
223
|
+
|
|
224
|
+
expect(result.field).toBeNull();
|
|
225
|
+
expect(remainingErrors).toHaveLength(1);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should not nullify boolean values', () => {
|
|
229
|
+
const object = { field: false };
|
|
230
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
231
|
+
const validationErrors = [error];
|
|
232
|
+
|
|
233
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
234
|
+
|
|
235
|
+
expect(result.field).toBe(false);
|
|
236
|
+
expect(remainingErrors).toHaveLength(1);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe('mixed scenarios', () => {
|
|
241
|
+
it('should handle mix of nullifiable and non-nullifiable errors', () => {
|
|
242
|
+
const object = { field1: '', field2: '', field3: 'value' };
|
|
243
|
+
const error1 = createMockError('PATTERN', '#/field1', object);
|
|
244
|
+
const error2 = createMockError('INVALID_TYPE', '#/field2', object);
|
|
245
|
+
const error3 = createMockError('PATTERN', '#/field3', object);
|
|
246
|
+
const validationErrors = [error1, error2, error3];
|
|
247
|
+
|
|
248
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
249
|
+
|
|
250
|
+
expect(result.field1).toBeNull();
|
|
251
|
+
expect(result.field2).toBe('');
|
|
252
|
+
expect(result.field3).toBe('value');
|
|
253
|
+
expect(remainingErrors).toHaveLength(2);
|
|
254
|
+
expect(remainingErrors).toContain(error2);
|
|
255
|
+
expect(remainingErrors).toContain(error3);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('should handle required and non-required errors', () => {
|
|
259
|
+
const object = { requiredField: '', optionalField: '' };
|
|
260
|
+
const schema1 = { 'x-required': true };
|
|
261
|
+
const schema2 = {};
|
|
262
|
+
const error1 = createMockError('PATTERN', '#/requiredField', object, schema1);
|
|
263
|
+
const error2 = createMockError('PATTERN', '#/optionalField', object, schema2);
|
|
264
|
+
const validationErrors = [error1, error2];
|
|
265
|
+
|
|
266
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
267
|
+
|
|
268
|
+
expect(result.requiredField).toBe('');
|
|
269
|
+
expect(result.optionalField).toBeNull();
|
|
270
|
+
expect(remainingErrors).toHaveLength(1);
|
|
271
|
+
expect(remainingErrors[0]).toBe(error1);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('should handle format errors with empty and non-empty values', () => {
|
|
275
|
+
const object = { emptyField: '', nonEmptyField: 'invalid' };
|
|
276
|
+
const error1 = createMockError('PATTERN', '#/emptyField', object);
|
|
277
|
+
const error2 = createMockError('PATTERN', '#/nonEmptyField', object);
|
|
278
|
+
const validationErrors = [error1, error2];
|
|
279
|
+
|
|
280
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
281
|
+
|
|
282
|
+
expect(result.emptyField).toBeNull();
|
|
283
|
+
expect(result.nonEmptyField).toBe('invalid');
|
|
284
|
+
expect(remainingErrors).toHaveLength(1);
|
|
285
|
+
expect(remainingErrors[0]).toBe(error2);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
describe('edge cases', () => {
|
|
290
|
+
it('should return deep copy of object', () => {
|
|
291
|
+
const object = { field: 'value', nested: { deep: 'value' } };
|
|
292
|
+
const validationErrors: SchemaErrorDetail[] = [];
|
|
293
|
+
|
|
294
|
+
const [result] = nullifyEmptyValues(object, validationErrors);
|
|
295
|
+
|
|
296
|
+
expect(result).not.toBe(object);
|
|
297
|
+
expect(result).toEqual(object);
|
|
298
|
+
expect(result.nested).not.toBe(object.nested);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should handle empty validation errors array', () => {
|
|
302
|
+
const object = { field: 'value' };
|
|
303
|
+
const validationErrors: SchemaErrorDetail[] = [];
|
|
304
|
+
|
|
305
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
306
|
+
|
|
307
|
+
expect(result).toEqual(object);
|
|
308
|
+
expect(remainingErrors).toHaveLength(0);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('should handle empty object', () => {
|
|
312
|
+
const object = {};
|
|
313
|
+
const validationErrors: SchemaErrorDetail[] = [];
|
|
314
|
+
|
|
315
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
316
|
+
|
|
317
|
+
expect(result).toEqual({});
|
|
318
|
+
expect(remainingErrors).toHaveLength(0);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it('should handle complex nested structures', () => {
|
|
322
|
+
const object = {
|
|
323
|
+
level1: {
|
|
324
|
+
level2: {
|
|
325
|
+
empty: '',
|
|
326
|
+
nonEmpty: 'value',
|
|
327
|
+
array: ['', 'value', ''],
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
const error1 = createMockError('PATTERN', '#/level1/level2/empty', object);
|
|
332
|
+
const error2 = createMockError('PATTERN', '#/level1/level2/array/0', object);
|
|
333
|
+
const error3 = createMockError('PATTERN', '#/level1/level2/array/2', object);
|
|
334
|
+
const validationErrors = [error1, error2, error3];
|
|
335
|
+
|
|
336
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
337
|
+
|
|
338
|
+
expect(result.level1.level2.empty).toBeNull();
|
|
339
|
+
expect(result.level1.level2.nonEmpty).toBe('value');
|
|
340
|
+
expect(result.level1.level2.array[0]).toBeNull();
|
|
341
|
+
expect(result.level1.level2.array[1]).toBe('value');
|
|
342
|
+
expect(result.level1.level2.array[2]).toBeNull();
|
|
343
|
+
expect(remainingErrors).toHaveLength(0);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('should handle path without #/ prefix', () => {
|
|
347
|
+
const object = { field: '' };
|
|
348
|
+
const error = createMockError('PATTERN', 'field', object);
|
|
349
|
+
const validationErrors = [error];
|
|
350
|
+
|
|
351
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
352
|
+
|
|
353
|
+
// The function replaces '#/' with '', so 'field' becomes ['field']
|
|
354
|
+
expect(result.field).toBeNull();
|
|
355
|
+
expect(remainingErrors).toHaveLength(0);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('should preserve other object properties', () => {
|
|
359
|
+
const object = {
|
|
360
|
+
emptyField: '',
|
|
361
|
+
numberField: 42,
|
|
362
|
+
booleanField: true,
|
|
363
|
+
nullField: null,
|
|
364
|
+
objectField: { nested: 'value' },
|
|
365
|
+
};
|
|
366
|
+
const error = createMockError('PATTERN', '#/emptyField', object);
|
|
367
|
+
const validationErrors = [error];
|
|
368
|
+
|
|
369
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
370
|
+
|
|
371
|
+
expect(result.emptyField).toBeNull();
|
|
372
|
+
expect(result.numberField).toBe(42);
|
|
373
|
+
expect(result.booleanField).toBe(true);
|
|
374
|
+
expect(result.nullField).toBeNull();
|
|
375
|
+
expect(result.objectField).toEqual({ nested: 'value' });
|
|
376
|
+
expect(remainingErrors).toHaveLength(0);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('should handle empty path string', () => {
|
|
380
|
+
const object = { field: '' };
|
|
381
|
+
const error = createMockError('PATTERN', '', object);
|
|
382
|
+
const validationErrors = [error];
|
|
383
|
+
|
|
384
|
+
const [, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
385
|
+
|
|
386
|
+
// Empty path should result in empty array after filter, which lodash.set handles
|
|
387
|
+
expect(remainingErrors).toHaveLength(1);
|
|
388
|
+
expect(remainingErrors[0]).toBe(error);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('should handle root level path #/', () => {
|
|
392
|
+
const object = '';
|
|
393
|
+
const error = createMockError('PATTERN', '#/', object);
|
|
394
|
+
const validationErrors = [error];
|
|
395
|
+
|
|
396
|
+
const [, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
397
|
+
|
|
398
|
+
// Root level path should result in empty array after filter
|
|
399
|
+
expect(remainingErrors).toHaveLength(1);
|
|
400
|
+
expect(remainingErrors[0]).toBe(error);
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should handle path that does not exist in object', () => {
|
|
404
|
+
const object = { field: 'value' };
|
|
405
|
+
const error = createMockError('PATTERN', '#/nonexistent', object);
|
|
406
|
+
const validationErrors = [error];
|
|
407
|
+
|
|
408
|
+
const [, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
409
|
+
|
|
410
|
+
// Path doesn't exist, value is undefined, should not nullify
|
|
411
|
+
expect(remainingErrors).toHaveLength(1);
|
|
412
|
+
expect(remainingErrors[0]).toBe(error);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it('should handle multiple errors for the same path', () => {
|
|
416
|
+
const object = { field: '' };
|
|
417
|
+
const error1 = createMockError('PATTERN', '#/field', object);
|
|
418
|
+
const error2 = createMockError('ENUM_MISMATCH', '#/field', object);
|
|
419
|
+
const validationErrors = [error1, error2];
|
|
420
|
+
|
|
421
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
422
|
+
|
|
423
|
+
// Both errors should be processed and field should be nullified
|
|
424
|
+
expect(result.field).toBeNull();
|
|
425
|
+
expect(remainingErrors).toHaveLength(0);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('should handle array index out of bounds', () => {
|
|
429
|
+
const object = { items: ['value'] };
|
|
430
|
+
const error = createMockError('PATTERN', '#/items/5', object);
|
|
431
|
+
const validationErrors = [error];
|
|
432
|
+
|
|
433
|
+
const [, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
434
|
+
|
|
435
|
+
// Index out of bounds, value is undefined, should not nullify
|
|
436
|
+
expect(remainingErrors).toHaveLength(1);
|
|
437
|
+
expect(remainingErrors[0]).toBe(error);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('should handle whitespace-only strings', () => {
|
|
441
|
+
const object = { field: ' ' };
|
|
442
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
443
|
+
const validationErrors = [error];
|
|
444
|
+
|
|
445
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
446
|
+
|
|
447
|
+
// Whitespace is not empty string, should not nullify
|
|
448
|
+
expect(result.field).toBe(' ');
|
|
449
|
+
expect(remainingErrors).toHaveLength(1);
|
|
450
|
+
expect(remainingErrors[0]).toBe(error);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('should handle empty array', () => {
|
|
454
|
+
const object = { items: [] };
|
|
455
|
+
const error = createMockError('PATTERN', '#/items', object);
|
|
456
|
+
const validationErrors = [error];
|
|
457
|
+
|
|
458
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
459
|
+
|
|
460
|
+
// Empty array is not empty string, should not nullify
|
|
461
|
+
expect(result.items).toEqual([]);
|
|
462
|
+
expect(remainingErrors).toHaveLength(1);
|
|
463
|
+
expect(remainingErrors[0]).toBe(error);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it('should handle empty object', () => {
|
|
467
|
+
const object = { field: {} };
|
|
468
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
469
|
+
const validationErrors = [error];
|
|
470
|
+
|
|
471
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
472
|
+
|
|
473
|
+
// Empty object is not empty string, should not nullify
|
|
474
|
+
expect(result.field).toEqual({});
|
|
475
|
+
expect(remainingErrors).toHaveLength(1);
|
|
476
|
+
expect(remainingErrors[0]).toBe(error);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it('should handle x-required as string "true"', () => {
|
|
480
|
+
const object = { field: '' };
|
|
481
|
+
const schema = { 'x-required': 'true' };
|
|
482
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
483
|
+
const validationErrors = [error];
|
|
484
|
+
|
|
485
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
486
|
+
|
|
487
|
+
// String 'true' is not boolean true, should nullify
|
|
488
|
+
expect(result.field).toBeNull();
|
|
489
|
+
expect(remainingErrors).toHaveLength(0);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('should handle x-required as number 1', () => {
|
|
493
|
+
const object = { field: '' };
|
|
494
|
+
const schema = { 'x-required': 1 };
|
|
495
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
496
|
+
const validationErrors = [error];
|
|
497
|
+
|
|
498
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
499
|
+
|
|
500
|
+
// Number 1 is not boolean true, should nullify
|
|
501
|
+
expect(result.field).toBeNull();
|
|
502
|
+
expect(remainingErrors).toHaveLength(0);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
it('should handle x-required as null', () => {
|
|
506
|
+
const object = { field: '' };
|
|
507
|
+
const schema = { 'x-required': null };
|
|
508
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
509
|
+
const validationErrors = [error];
|
|
510
|
+
|
|
511
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
512
|
+
|
|
513
|
+
// null is not boolean true, should nullify
|
|
514
|
+
expect(result.field).toBeNull();
|
|
515
|
+
expect(remainingErrors).toHaveLength(0);
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('should handle missing schema symbol', () => {
|
|
519
|
+
const object = { field: '' };
|
|
520
|
+
const error = {
|
|
521
|
+
code: 'PATTERN',
|
|
522
|
+
path: '#/field',
|
|
523
|
+
message: 'Error at #/field',
|
|
524
|
+
params: [],
|
|
525
|
+
description: 'Error at #/field',
|
|
526
|
+
inner: [],
|
|
527
|
+
} as SchemaErrorDetail;
|
|
528
|
+
|
|
529
|
+
// Don't attach schemaSymbol
|
|
530
|
+
(error as SchemaErrorDetail)[jsonSymbol] = object;
|
|
531
|
+
const validationErrors = [error];
|
|
532
|
+
|
|
533
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
534
|
+
|
|
535
|
+
// Missing schema should be treated as not required, should nullify
|
|
536
|
+
expect(result.field).toBeNull();
|
|
537
|
+
expect(remainingErrors).toHaveLength(0);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('should handle missing json symbol', () => {
|
|
541
|
+
const object = { field: '' };
|
|
542
|
+
const error = {
|
|
543
|
+
code: 'PATTERN',
|
|
544
|
+
path: '#/field',
|
|
545
|
+
message: 'Error at #/field',
|
|
546
|
+
params: [],
|
|
547
|
+
description: 'Error at #/field',
|
|
548
|
+
inner: [],
|
|
549
|
+
} as SchemaErrorDetail;
|
|
550
|
+
|
|
551
|
+
// Don't attach jsonSymbol
|
|
552
|
+
(error as SchemaErrorDetail)[schemaSymbol] = {};
|
|
553
|
+
const validationErrors = [error];
|
|
554
|
+
|
|
555
|
+
const [, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
556
|
+
|
|
557
|
+
// Missing json symbol means value is undefined, should not nullify
|
|
558
|
+
expect(remainingErrors).toHaveLength(1);
|
|
559
|
+
expect(remainingErrors[0]).toBe(error);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it('should handle all format error codes together', () => {
|
|
563
|
+
const object = { field1: '', field2: '', field3: '' };
|
|
564
|
+
const error1 = createMockError('PATTERN', '#/field1', object);
|
|
565
|
+
const error2 = createMockError('ENUM_MISMATCH', '#/field2', object);
|
|
566
|
+
const error3 = createMockError('INVALID_FORMAT', '#/field3', object);
|
|
567
|
+
const validationErrors = [error1, error2, error3];
|
|
568
|
+
|
|
569
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
570
|
+
|
|
571
|
+
expect(result.field1).toBeNull();
|
|
572
|
+
expect(result.field2).toBeNull();
|
|
573
|
+
expect(result.field3).toBeNull();
|
|
574
|
+
expect(remainingErrors).toHaveLength(0);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it('should handle nested arrays with empty strings', () => {
|
|
578
|
+
const object = {
|
|
579
|
+
items: [
|
|
580
|
+
{ name: '', value: 'test' },
|
|
581
|
+
{ name: 'test', value: '' },
|
|
582
|
+
],
|
|
583
|
+
};
|
|
584
|
+
const error1 = createMockError('PATTERN', '#/items/0/name', object);
|
|
585
|
+
const error2 = createMockError('PATTERN', '#/items/1/value', object);
|
|
586
|
+
const validationErrors = [error1, error2];
|
|
587
|
+
|
|
588
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
589
|
+
|
|
590
|
+
expect(result.items[0].name).toBeNull();
|
|
591
|
+
expect(result.items[0].value).toBe('test');
|
|
592
|
+
expect(result.items[1].name).toBe('test');
|
|
593
|
+
expect(result.items[1].value).toBeNull();
|
|
594
|
+
expect(remainingErrors).toHaveLength(0);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
it('should handle path with multiple consecutive slashes', () => {
|
|
598
|
+
const object = { field: '' };
|
|
599
|
+
const error = createMockError('PATTERN', '#//field', object);
|
|
600
|
+
const validationErrors = [error];
|
|
601
|
+
|
|
602
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
603
|
+
|
|
604
|
+
// Multiple slashes should be filtered out, path becomes ['field']
|
|
605
|
+
expect(result.field).toBeNull();
|
|
606
|
+
expect(remainingErrors).toHaveLength(0);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it('should handle path with trailing slash', () => {
|
|
610
|
+
const object = { field: '' };
|
|
611
|
+
const error = createMockError('PATTERN', '#/field/', object);
|
|
612
|
+
const validationErrors = [error];
|
|
613
|
+
|
|
614
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
615
|
+
|
|
616
|
+
// Trailing slash should be filtered out
|
|
617
|
+
expect(result.field).toBeNull();
|
|
618
|
+
expect(remainingErrors).toHaveLength(0);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('should handle undefined value in object', () => {
|
|
622
|
+
const object: Record<string, unknown> = { field: undefined };
|
|
623
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
624
|
+
const validationErrors = [error];
|
|
625
|
+
|
|
626
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
627
|
+
|
|
628
|
+
// undefined is not empty string, should not nullify
|
|
629
|
+
expect(result.field).toBeUndefined();
|
|
630
|
+
expect(remainingErrors).toHaveLength(1);
|
|
631
|
+
expect(remainingErrors[0]).toBe(error);
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
it('should handle value 0 (falsy but not empty)', () => {
|
|
635
|
+
const object = { field: 0 };
|
|
636
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
637
|
+
const validationErrors = [error];
|
|
638
|
+
|
|
639
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
640
|
+
|
|
641
|
+
// 0 is not empty string, should not nullify
|
|
642
|
+
expect(result.field).toBe(0);
|
|
643
|
+
expect(remainingErrors).toHaveLength(1);
|
|
644
|
+
expect(remainingErrors[0]).toBe(error);
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
it('should handle value false (falsy but not empty)', () => {
|
|
648
|
+
const object = { field: false };
|
|
649
|
+
const error = createMockError('PATTERN', '#/field', object);
|
|
650
|
+
const validationErrors = [error];
|
|
651
|
+
|
|
652
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
653
|
+
|
|
654
|
+
// false is not empty string, should not nullify
|
|
655
|
+
expect(result.field).toBe(false);
|
|
656
|
+
expect(remainingErrors).toHaveLength(1);
|
|
657
|
+
expect(remainingErrors[0]).toBe(error);
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
it('should handle very long nested paths', () => {
|
|
661
|
+
const object = {
|
|
662
|
+
level1: {
|
|
663
|
+
level2: {
|
|
664
|
+
level3: {
|
|
665
|
+
level4: {
|
|
666
|
+
level5: {
|
|
667
|
+
level6: {
|
|
668
|
+
level7: {
|
|
669
|
+
level8: {
|
|
670
|
+
level9: {
|
|
671
|
+
level10: { field: '' },
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
},
|
|
681
|
+
};
|
|
682
|
+
const error = createMockError(
|
|
683
|
+
'PATTERN',
|
|
684
|
+
'#/level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/field',
|
|
685
|
+
object
|
|
686
|
+
);
|
|
687
|
+
const validationErrors = [error];
|
|
688
|
+
|
|
689
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
690
|
+
|
|
691
|
+
expect(result.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.field).toBeNull();
|
|
692
|
+
expect(remainingErrors).toHaveLength(0);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it('should handle mixed format and non-format errors for same field', () => {
|
|
696
|
+
const object = { field: '' };
|
|
697
|
+
const formatError = createMockError('PATTERN', '#/field', object);
|
|
698
|
+
const typeError = createMockError('INVALID_TYPE', '#/field', object);
|
|
699
|
+
const validationErrors = [formatError, typeError];
|
|
700
|
+
|
|
701
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
702
|
+
|
|
703
|
+
// Format error should nullify, type error should remain
|
|
704
|
+
expect(result.field).toBeNull();
|
|
705
|
+
expect(remainingErrors).toHaveLength(1);
|
|
706
|
+
expect(remainingErrors[0]).toBe(typeError);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('should handle schema with x-required as empty object', () => {
|
|
710
|
+
const object = { field: '' };
|
|
711
|
+
const schema = {};
|
|
712
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
713
|
+
const validationErrors = [error];
|
|
714
|
+
|
|
715
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
716
|
+
|
|
717
|
+
// Empty schema object means not required, should nullify
|
|
718
|
+
expect(result.field).toBeNull();
|
|
719
|
+
expect(remainingErrors).toHaveLength(0);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it('should handle schema with x-required as undefined property', () => {
|
|
723
|
+
const object = { field: '' };
|
|
724
|
+
const schema = { 'x-required': undefined };
|
|
725
|
+
const error = createMockError('PATTERN', '#/field', object, schema);
|
|
726
|
+
const validationErrors = [error];
|
|
727
|
+
|
|
728
|
+
const [result, remainingErrors] = nullifyEmptyValues(object, validationErrors);
|
|
729
|
+
|
|
730
|
+
// undefined is not boolean true, should nullify
|
|
731
|
+
expect(result.field).toBeNull();
|
|
732
|
+
expect(remainingErrors).toHaveLength(0);
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
});
|