@sanity/validation 2.30.1-purple-unicorn.964 → 3.0.0-dev-preview.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/lib/dts/src/Rule.js +317 -312
- package/lib/dts/src/ValidationError.js +16 -16
- package/lib/dts/src/index.js +7 -7
- package/lib/dts/src/inferFromSchema.js +11 -11
- package/lib/dts/src/inferFromSchemaType.js +24 -24
- package/lib/dts/src/util/convertToValidationMarker.js +44 -53
- package/lib/dts/src/util/deepEquals.js +50 -49
- package/lib/dts/src/util/escapeRegex.js +4 -4
- package/lib/dts/src/util/normalizeValidationRules.js +87 -78
- package/lib/dts/src/util/normalizeValidationRules.test.d.ts +2 -2
- package/lib/dts/src/util/normalizeValidationRules.test.js +149 -149
- package/lib/dts/src/util/pathToString.js +16 -16
- package/lib/dts/src/util/typeString.js +17 -14
- package/lib/dts/src/util/typeString.test.d.ts +2 -2
- package/lib/dts/src/util/typeString.test.js +23 -24
- package/lib/dts/src/validateDocument.js +132 -157
- package/lib/dts/src/validateDocument.test.d.ts +2 -2
- package/lib/dts/src/validateDocument.test.js +664 -678
- package/lib/dts/src/validators/arrayValidator.js +75 -75
- package/lib/dts/src/validators/booleanValidator.js +11 -11
- package/lib/dts/src/validators/dateValidator.js +74 -68
- package/lib/dts/src/validators/genericValidator.js +89 -87
- package/lib/dts/src/validators/numberValidator.js +46 -48
- package/lib/dts/src/validators/objectValidator.js +47 -47
- package/lib/dts/src/validators/slugValidator.js +68 -74
- package/lib/dts/src/validators/stringValidator.js +93 -93
- package/lib/dts/test/array.test.d.ts +2 -2
- package/lib/dts/test/array.test.js +54 -78
- package/lib/dts/test/children.test.d.ts +2 -2
- package/lib/dts/test/children.test.js +69 -87
- package/lib/dts/test/createSchema.d.ts +6 -3
- package/lib/dts/test/createSchema.js +17 -17
- package/lib/dts/test/generics.test.d.ts +2 -2
- package/lib/dts/test/generics.test.js +59 -59
- package/lib/dts/test/infer.test.d.ts +2 -2
- package/lib/dts/test/infer.test.js +236 -285
- package/lib/dts/test/mocks/mockSanityClient.d.ts +4 -5
- package/lib/dts/test/mocks/mockSanityClient.d.ts.map +1 -1
- package/lib/dts/test/mocks/mockSanityClient.js +6 -6
- package/lib/dts/test/nullExport.d.ts +3 -3
- package/lib/dts/test/nullExport.js +2 -2
- package/lib/dts/test/numbers.test.d.ts +2 -2
- package/lib/dts/test/numbers.test.js +56 -62
- package/lib/dts/test/strings.test.d.ts +2 -2
- package/lib/dts/test/strings.test.js +99 -150
- package/lib/dts/tsconfig.lib.tsbuildinfo +1 -1
- package/lib/dts/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -1,292 +1,243 @@
|
|
|
1
|
-
import SchemaBuilder from '@sanity/schema'
|
|
2
|
-
import inferFromSchema from '../src/inferFromSchema'
|
|
3
|
-
import validateDocument from '../src/validateDocument'
|
|
4
|
-
import {createSchema} from './createSchema'
|
|
5
|
-
import {createMockSanityClient} from './mocks/mockSanityClient'
|
|
6
|
-
const client = createMockSanityClient()
|
|
1
|
+
import SchemaBuilder from '@sanity/schema';
|
|
2
|
+
import inferFromSchema from '../src/inferFromSchema';
|
|
3
|
+
import validateDocument from '../src/validateDocument';
|
|
4
|
+
import { createSchema } from './createSchema';
|
|
5
|
+
import { createMockSanityClient } from './mocks/mockSanityClient';
|
|
6
|
+
const client = createMockSanityClient();
|
|
7
7
|
describe('schema validation inference', () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
8
|
+
describe('object with `options.list` and `value` field', () => {
|
|
9
|
+
const listOptions = [
|
|
10
|
+
{ value: '#f00', title: 'Red' },
|
|
11
|
+
{ value: '#0f0', title: 'Green' },
|
|
12
|
+
{ value: '#00f', title: 'Blue' },
|
|
13
|
+
];
|
|
14
|
+
const schema = SchemaBuilder.compile({
|
|
15
|
+
types: [
|
|
16
|
+
{
|
|
17
|
+
name: 'colorList',
|
|
18
|
+
type: 'object',
|
|
19
|
+
fields: [
|
|
20
|
+
{ name: 'value', type: 'string' },
|
|
21
|
+
{ name: 'title', type: 'string' },
|
|
22
|
+
],
|
|
23
|
+
options: {
|
|
24
|
+
list: listOptions,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
test('allowed value', async () => {
|
|
30
|
+
const type = inferFromSchema(schema).get('colorList');
|
|
31
|
+
await expectNoError(type.validation, listOptions[0]);
|
|
32
|
+
});
|
|
33
|
+
test('disallowed value', async () => {
|
|
34
|
+
const type = inferFromSchema(schema).get('colorList');
|
|
35
|
+
await expectError(type.validation, { value: '#ccc', title: 'Gray' }, 'Value did not match any allowed value');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe('field validations', () => {
|
|
39
|
+
const fieldValidationInferReproDoc = {
|
|
40
|
+
name: 'fieldValidationInferReproDoc',
|
|
41
|
+
type: 'document',
|
|
42
|
+
title: 'FieldValidationRepro',
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
44
|
+
validation: (Rule) => Rule.fields({
|
|
45
|
+
stringField: (fieldRule) => fieldRule.required(),
|
|
46
|
+
}),
|
|
47
|
+
fields: [
|
|
48
|
+
{
|
|
49
|
+
name: 'stringField',
|
|
50
|
+
type: 'string',
|
|
51
|
+
title: 'Field of someObjectType with validation',
|
|
52
|
+
description: 'First field should be required',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
const schema = SchemaBuilder.compile({
|
|
57
|
+
types: [fieldValidationInferReproDoc],
|
|
58
|
+
});
|
|
59
|
+
test('field validations defined on an object type does not affect the field type validation', () => {
|
|
60
|
+
const documentType = inferFromSchema(schema).get('fieldValidationInferReproDoc');
|
|
61
|
+
const fieldWithoutValidation = documentType.fields.find((field) => field.name === 'stringField');
|
|
62
|
+
// The first field should only have the validation rules that comes with its type
|
|
63
|
+
expect(fieldWithoutValidation?.type.validation.flatMap(
|
|
64
|
+
// eslint-disable-next-line dot-notation
|
|
65
|
+
(validation) => validation['_rules'])).toEqual([{ flag: 'type', constraint: 'String' }]);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('slug validation', () => {
|
|
69
|
+
const slugField = {
|
|
70
|
+
type: 'document',
|
|
71
|
+
name: 'documentWithSlug',
|
|
72
|
+
title: 'Document with Slug',
|
|
73
|
+
fields: [
|
|
74
|
+
{
|
|
75
|
+
name: 'slugField',
|
|
76
|
+
type: 'slug',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
const schema = createSchema({
|
|
81
|
+
types: [slugField],
|
|
82
|
+
});
|
|
83
|
+
const mockDocument = {
|
|
84
|
+
_id: 'mockDocument',
|
|
85
|
+
_type: 'documentWithSlug',
|
|
86
|
+
slugField: { current: 'example-value' },
|
|
87
|
+
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
88
|
+
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
89
|
+
_rev: 'example-rev',
|
|
90
|
+
};
|
|
91
|
+
afterEach(() => {
|
|
92
|
+
client.fetch.mockReset();
|
|
93
|
+
});
|
|
94
|
+
test('slug is valid if uniqueness queries returns true', async () => {
|
|
95
|
+
client.fetch.mockImplementation(() => Promise.resolve(
|
|
96
|
+
// return true to mock a unique result (valid)
|
|
97
|
+
true));
|
|
98
|
+
await expect(validateDocument(client, mockDocument, schema)).resolves.toEqual([]);
|
|
99
|
+
expect(client.fetch).toHaveBeenCalledTimes(1);
|
|
100
|
+
expect(client.fetch.mock.calls[0]).toEqual([
|
|
101
|
+
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
102
|
+
{
|
|
103
|
+
docType: 'documentWithSlug',
|
|
104
|
+
draft: 'drafts.mockDocument',
|
|
105
|
+
published: 'mockDocument',
|
|
106
|
+
slug: 'example-value',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
tag: 'validation.slug-is-unique',
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
test('slug is invalid if uniqueness queries returns false', async () => {
|
|
114
|
+
client.fetch.mockReset();
|
|
115
|
+
client.fetch.mockImplementation(() => Promise.resolve(
|
|
116
|
+
// return false to mock a non-unique result (invalid)
|
|
117
|
+
false));
|
|
118
|
+
await expect(validateDocument(client, mockDocument, schema)).resolves.toMatchObject([
|
|
119
|
+
{
|
|
120
|
+
path: ['slugField'],
|
|
121
|
+
level: 'error',
|
|
122
|
+
item: { message: 'Slug is already in use', paths: [] },
|
|
123
|
+
},
|
|
124
|
+
]);
|
|
125
|
+
expect(client.fetch).toHaveBeenCalledTimes(1);
|
|
126
|
+
expect(client.fetch.mock.calls[0]).toEqual([
|
|
127
|
+
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
128
|
+
{
|
|
129
|
+
docType: 'documentWithSlug',
|
|
130
|
+
draft: 'drafts.mockDocument',
|
|
131
|
+
published: 'mockDocument',
|
|
132
|
+
slug: 'example-value',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
tag: 'validation.slug-is-unique',
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
describe('reference validation', () => {
|
|
141
|
+
const documentWithReference = {
|
|
142
|
+
type: 'document',
|
|
143
|
+
name: 'documentWithReference',
|
|
144
|
+
title: 'Document with Reference',
|
|
145
|
+
fields: [
|
|
146
|
+
{
|
|
147
|
+
name: 'referenceField',
|
|
148
|
+
type: 'reference',
|
|
149
|
+
to: [{ type: 'documentWithReference' }],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'referenceFieldWeak',
|
|
153
|
+
type: 'reference',
|
|
154
|
+
weak: true,
|
|
155
|
+
to: [{ type: 'documentWithReference' }],
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
const schema = createSchema({
|
|
160
|
+
types: [documentWithReference],
|
|
161
|
+
});
|
|
162
|
+
const mockDocument = {
|
|
163
|
+
_id: 'mockDocument',
|
|
164
|
+
_type: 'documentWithReference',
|
|
165
|
+
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
166
|
+
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
167
|
+
_rev: 'example-rev',
|
|
168
|
+
};
|
|
169
|
+
afterEach(() => {
|
|
170
|
+
client.fetch.mockReset();
|
|
171
|
+
});
|
|
172
|
+
test('referenced document must exist (unless weak)', async () => {
|
|
173
|
+
const mockGetDocumentExists = jest.fn(() => Promise.resolve(false));
|
|
174
|
+
await expect(validateDocument(client, {
|
|
175
|
+
...mockDocument,
|
|
176
|
+
referenceField: {
|
|
177
|
+
_ref: 'example-id',
|
|
178
|
+
},
|
|
179
|
+
}, schema, { getDocumentExists: mockGetDocumentExists })).resolves.toMatchObject([
|
|
180
|
+
{
|
|
181
|
+
item: { message: /.+/ },
|
|
182
|
+
level: 'error',
|
|
183
|
+
path: ['referenceField'],
|
|
184
|
+
},
|
|
185
|
+
]);
|
|
186
|
+
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{ id: 'example-id' }]]);
|
|
187
|
+
});
|
|
188
|
+
test('reference is valid if schema type is marked as weak', async () => {
|
|
189
|
+
await expect(validateDocument(client, {
|
|
190
|
+
...mockDocument,
|
|
191
|
+
referenceFieldWeak: { _ref: 'example-id' },
|
|
192
|
+
}, schema)).resolves.toEqual([]);
|
|
193
|
+
});
|
|
194
|
+
test('throws if `getDocumentExists` is not present', async () => {
|
|
195
|
+
const result = await validateDocument(client, {
|
|
196
|
+
...mockDocument,
|
|
197
|
+
referenceField: {
|
|
198
|
+
_ref: 'example-id',
|
|
199
|
+
},
|
|
200
|
+
}, schema, { getDocumentExists: undefined });
|
|
201
|
+
expect(result).toHaveLength(1);
|
|
202
|
+
expect(result[0].item.message.includes('`getDocumentExists` was not provided in validation context')).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
test('reference is valid if schema type is strong and document does exists', async () => {
|
|
205
|
+
const mockGetDocumentExists = jest.fn(() => Promise.resolve(true));
|
|
206
|
+
await expect(validateDocument(client, {
|
|
207
|
+
...mockDocument,
|
|
208
|
+
referenceField: {
|
|
209
|
+
_ref: 'example-id',
|
|
210
|
+
},
|
|
211
|
+
}, schema, { getDocumentExists: mockGetDocumentExists })).resolves.toEqual([]);
|
|
212
|
+
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{ id: 'example-id' }]]);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
async function expectNoError(validations, value) {
|
|
217
|
+
const errors = (await Promise.all(validations.map((rule) => rule.validate(value, { client: {} })))).flat();
|
|
218
|
+
if (errors.length === 0) {
|
|
219
|
+
// This shouldn't actually be needed, but counts against an assertion in jest-terms
|
|
220
|
+
expect(errors).toHaveLength(0);
|
|
221
|
+
return;
|
|
89
222
|
}
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
98
|
-
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
99
|
-
_rev: 'example-rev',
|
|
223
|
+
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ');
|
|
224
|
+
throw new Error(`Expected no errors, but found ${errors.length}:\n- ${messages}`);
|
|
225
|
+
}
|
|
226
|
+
async function expectError(validations, value, message, level = 'error') {
|
|
227
|
+
const errors = (await Promise.all(validations.map((rule) => rule.validate(value, { client: {} })))).flat();
|
|
228
|
+
if (!errors.length) {
|
|
229
|
+
throw new Error(`Expected error matching "${message}", but no errors were returned.`);
|
|
100
230
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
client.fetch.mockImplementation(() =>
|
|
106
|
-
Promise.resolve(
|
|
107
|
-
// return true to mock a unique result (valid)
|
|
108
|
-
true
|
|
109
|
-
)
|
|
110
|
-
)
|
|
111
|
-
await expect(validateDocument(client, mockDocument, schema)).resolves.toEqual([])
|
|
112
|
-
expect(client.fetch).toHaveBeenCalledTimes(1)
|
|
113
|
-
expect(client.fetch.mock.calls[0]).toEqual([
|
|
114
|
-
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
115
|
-
{
|
|
116
|
-
docType: 'documentWithSlug',
|
|
117
|
-
draft: 'drafts.mockDocument',
|
|
118
|
-
published: 'mockDocument',
|
|
119
|
-
slug: 'example-value',
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
tag: 'validation.slug-is-unique',
|
|
123
|
-
},
|
|
124
|
-
])
|
|
125
|
-
})
|
|
126
|
-
test('slug is invalid if uniqueness queries returns false', async () => {
|
|
127
|
-
client.fetch.mockReset()
|
|
128
|
-
client.fetch.mockImplementation(() =>
|
|
129
|
-
Promise.resolve(
|
|
130
|
-
// return false to mock a non-unique result (invalid)
|
|
131
|
-
false
|
|
132
|
-
)
|
|
133
|
-
)
|
|
134
|
-
await expect(validateDocument(client, mockDocument, schema)).resolves.toMatchObject([
|
|
135
|
-
{
|
|
136
|
-
path: ['slugField'],
|
|
137
|
-
level: 'error',
|
|
138
|
-
item: {message: 'Slug is already in use', paths: []},
|
|
139
|
-
},
|
|
140
|
-
])
|
|
141
|
-
expect(client.fetch).toHaveBeenCalledTimes(1)
|
|
142
|
-
expect(client.fetch.mock.calls[0]).toEqual([
|
|
143
|
-
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
144
|
-
{
|
|
145
|
-
docType: 'documentWithSlug',
|
|
146
|
-
draft: 'drafts.mockDocument',
|
|
147
|
-
published: 'mockDocument',
|
|
148
|
-
slug: 'example-value',
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
tag: 'validation.slug-is-unique',
|
|
152
|
-
},
|
|
153
|
-
])
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
describe('reference validation', () => {
|
|
157
|
-
const documentWithReference = {
|
|
158
|
-
type: 'document',
|
|
159
|
-
name: 'documentWithReference',
|
|
160
|
-
title: 'Document with Reference',
|
|
161
|
-
fields: [
|
|
162
|
-
{
|
|
163
|
-
name: 'referenceField',
|
|
164
|
-
type: 'reference',
|
|
165
|
-
to: [{type: 'documentWithReference'}],
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
name: 'referenceFieldWeak',
|
|
169
|
-
type: 'reference',
|
|
170
|
-
weak: true,
|
|
171
|
-
to: [{type: 'documentWithReference'}],
|
|
172
|
-
},
|
|
173
|
-
],
|
|
231
|
+
const matches = errors.filter((err) => err.item && err.item.message.includes(message));
|
|
232
|
+
if (matches.length === 0) {
|
|
233
|
+
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ');
|
|
234
|
+
throw new Error(`Expected error matching "${message}" not found. Errors found:\n- ${messages}`);
|
|
174
235
|
}
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const mockDocument = {
|
|
179
|
-
_id: 'mockDocument',
|
|
180
|
-
_type: 'documentWithReference',
|
|
181
|
-
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
182
|
-
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
183
|
-
_rev: 'example-rev',
|
|
236
|
+
const levelMatch = matches.find((err) => err.level === level);
|
|
237
|
+
if (!levelMatch) {
|
|
238
|
+
throw new Error(`Expected error to have level "${level}", got ${matches[0].level}`);
|
|
184
239
|
}
|
|
185
|
-
afterEach(() => {
|
|
186
|
-
client.fetch.mockReset()
|
|
187
|
-
})
|
|
188
|
-
test('referenced document must exist (unless weak)', async () => {
|
|
189
|
-
const mockGetDocumentExists = jest.fn(() => Promise.resolve(false))
|
|
190
|
-
await expect(
|
|
191
|
-
validateDocument(
|
|
192
|
-
client,
|
|
193
|
-
{
|
|
194
|
-
...mockDocument,
|
|
195
|
-
referenceField: {
|
|
196
|
-
_ref: 'example-id',
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
schema,
|
|
200
|
-
{getDocumentExists: mockGetDocumentExists}
|
|
201
|
-
)
|
|
202
|
-
).resolves.toMatchObject([
|
|
203
|
-
{
|
|
204
|
-
item: {message: /.+/},
|
|
205
|
-
level: 'error',
|
|
206
|
-
path: ['referenceField'],
|
|
207
|
-
},
|
|
208
|
-
])
|
|
209
|
-
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{id: 'example-id'}]])
|
|
210
|
-
})
|
|
211
|
-
test('reference is valid if schema type is marked as weak', async () => {
|
|
212
|
-
await expect(
|
|
213
|
-
validateDocument(
|
|
214
|
-
client,
|
|
215
|
-
{
|
|
216
|
-
...mockDocument,
|
|
217
|
-
referenceFieldWeak: {_ref: 'example-id'},
|
|
218
|
-
},
|
|
219
|
-
schema
|
|
220
|
-
)
|
|
221
|
-
).resolves.toEqual([])
|
|
222
|
-
})
|
|
223
|
-
test('throws if `getDocumentExists` is not present', async () => {
|
|
224
|
-
const result = await validateDocument(
|
|
225
|
-
client,
|
|
226
|
-
{
|
|
227
|
-
...mockDocument,
|
|
228
|
-
referenceField: {
|
|
229
|
-
_ref: 'example-id',
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
schema,
|
|
233
|
-
{getDocumentExists: undefined}
|
|
234
|
-
)
|
|
235
|
-
expect(result).toHaveLength(1)
|
|
236
|
-
expect(
|
|
237
|
-
result[0].item.message.includes(
|
|
238
|
-
'`getDocumentExists` was not provided in validation context'
|
|
239
|
-
)
|
|
240
|
-
).toBe(true)
|
|
241
|
-
})
|
|
242
|
-
test('reference is valid if schema type is strong and document does exists', async () => {
|
|
243
|
-
const mockGetDocumentExists = jest.fn(() => Promise.resolve(true))
|
|
244
|
-
await expect(
|
|
245
|
-
validateDocument(
|
|
246
|
-
client,
|
|
247
|
-
{
|
|
248
|
-
...mockDocument,
|
|
249
|
-
referenceField: {
|
|
250
|
-
_ref: 'example-id',
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
schema,
|
|
254
|
-
{getDocumentExists: mockGetDocumentExists}
|
|
255
|
-
)
|
|
256
|
-
).resolves.toEqual([])
|
|
257
|
-
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{id: 'example-id'}]])
|
|
258
|
-
})
|
|
259
|
-
})
|
|
260
|
-
})
|
|
261
|
-
async function expectNoError(validations, value) {
|
|
262
|
-
const errors = (
|
|
263
|
-
await Promise.all(validations.map((rule) => rule.validate(value, {client: {}})))
|
|
264
|
-
).flat()
|
|
265
|
-
if (errors.length === 0) {
|
|
266
240
|
// This shouldn't actually be needed, but counts against an assertion in jest-terms
|
|
267
|
-
expect(
|
|
268
|
-
return
|
|
269
|
-
}
|
|
270
|
-
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ')
|
|
271
|
-
throw new Error(`Expected no errors, but found ${errors.length}:\n- ${messages}`)
|
|
272
|
-
}
|
|
273
|
-
async function expectError(validations, value, message, level = 'error') {
|
|
274
|
-
const errors = (
|
|
275
|
-
await Promise.all(validations.map((rule) => rule.validate(value, {client: {}})))
|
|
276
|
-
).flat()
|
|
277
|
-
if (!errors.length) {
|
|
278
|
-
throw new Error(`Expected error matching "${message}", but no errors were returned.`)
|
|
279
|
-
}
|
|
280
|
-
const matches = errors.filter((err) => err.item && err.item.message.includes(message))
|
|
281
|
-
if (matches.length === 0) {
|
|
282
|
-
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ')
|
|
283
|
-
throw new Error(`Expected error matching "${message}" not found. Errors found:\n- ${messages}`)
|
|
284
|
-
}
|
|
285
|
-
const levelMatch = matches.find((err) => err.level === level)
|
|
286
|
-
if (!levelMatch) {
|
|
287
|
-
throw new Error(`Expected error to have level "${level}", got ${matches[0].level}`)
|
|
288
|
-
}
|
|
289
|
-
// This shouldn't actually be needed, but counts against an assertion in jest-terms
|
|
290
|
-
expect(levelMatch.item.message).toMatch(message)
|
|
241
|
+
expect(levelMatch.item.message).toMatch(message);
|
|
291
242
|
}
|
|
292
|
-
//# sourceMappingURL=infer.test.js.map
|
|
243
|
+
//# sourceMappingURL=infer.test.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/// <reference types="jest" />
|
|
2
1
|
export declare function createMockSanityClient(): {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
//# sourceMappingURL=mockSanityClient.d.ts.map
|
|
2
|
+
fetch: jest.Mock<Promise<any>, [query: string]>;
|
|
3
|
+
withConfig: () => any;
|
|
4
|
+
};
|
|
5
|
+
//# sourceMappingURL=mockSanityClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockSanityClient.d.ts","sourceRoot":"","sources":["../../../../test/mocks/mockSanityClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mockSanityClient.d.ts","sourceRoot":"","sources":["../../../../test/mocks/mockSanityClient.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB;;;EAUrC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export function createMockSanityClient() {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
const _client = {
|
|
3
|
+
fetch: jest.fn((query) => Promise.resolve(null)),
|
|
4
|
+
withConfig: () => _client,
|
|
5
|
+
};
|
|
6
|
+
return _client;
|
|
7
7
|
}
|
|
8
|
-
//# sourceMappingURL=mockSanityClient.js.map
|
|
8
|
+
//# sourceMappingURL=mockSanityClient.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const _default: null
|
|
2
|
-
export default _default
|
|
3
|
-
//# sourceMappingURL=nullExport.d.ts.map
|
|
1
|
+
declare const _default: null;
|
|
2
|
+
export default _default;
|
|
3
|
+
//# sourceMappingURL=nullExport.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {}
|
|
2
|
-
//# sourceMappingURL=numbers.test.d.ts.map
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=numbers.test.d.ts.map
|