@dashevo/wasm-dpp 0.23.0-dev.10
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/.babelrc +5 -0
- package/.editorconfig +13 -0
- package/.eslintignore +1 -0
- package/.eslintrc +15 -0
- package/.mocharc.yml +4 -0
- package/CHANGELOG.md +397 -0
- package/LICENSE +20 -0
- package/README.md +37 -0
- package/karma.conf.js +53 -0
- package/package.json +107 -0
- package/test/.eslintrc +12 -0
- package/test/integration/DashPlatformProtocol.spec.js +53 -0
- package/test/integration/ajv/keywords/byteArray/addByteArrayKeyword.spec.js +148 -0
- package/test/integration/dataContract/DataContractFacade.spec.js +84 -0
- package/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +357 -0
- package/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +444 -0
- package/test/integration/dataContract/validation/validateDataContractFactory.spec.js +2191 -0
- package/test/integration/document/Document.spec.js +90 -0
- package/test/integration/document/DocumentFacade.spec.js +155 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js +83 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +1146 -0
- package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +294 -0
- package/test/integration/document/validation/validateDocumentFactory.spec.js +447 -0
- package/test/integration/error/consensus/createConsensusError.spec.js +21 -0
- package/test/integration/identity/IdentityFacade.spec.js +187 -0
- package/test/integration/identity/stateTransition/IdentityCreateTransition/validation/basic/validateIdentityCreateTransitionBasicFactory.spec.js +422 -0
- package/test/integration/identity/stateTransition/IdentityTopUpTransition/validation/basic/validateIdentityTopUpTransitionBasicFactory.spec.js +361 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js +595 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +299 -0
- package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validatePublicKeysState.spec.js +66 -0
- package/test/integration/identity/stateTransition/assetLockProof/chain/validateChainAssetLockProofStructureFactory.spec.js +415 -0
- package/test/integration/identity/stateTransition/assetLockProof/fetchAssetLockTransactionOutputFactory.spec.js +134 -0
- package/test/integration/identity/stateTransition/assetLockProof/instant/validateInstantAssetLockProofStructureFactory.spec.js +401 -0
- package/test/integration/identity/stateTransition/assetLockProof/validateAssetLockTransactionFactory.spec.js +205 -0
- package/test/integration/identity/stateTransition/validatePublicKeySignaturesFactory.spec.js +127 -0
- package/test/integration/identity/validation/validateIdentityFactory.spec.js +370 -0
- package/test/integration/identity/validation/validatePublicKeysFactory.spec.js +497 -0
- package/test/integration/stateTransition/AbstractStateTransitionIdentitySigned.spec.js +507 -0
- package/test/integration/stateTransition/StateTransitionFacade.spec.js +418 -0
- package/test/integration/stateTransition/calculateStateTransitionFee.spec.js +35 -0
- package/test/integration/util/generateEntropy.spec.js +17 -0
- package/test/integration/util/serializer.spec.js +24 -0
- package/test/unit/DashPlatformProtocol.spec.js +79 -0
- package/test/unit/Identifier.spec.js +123 -0
- package/test/unit/Metadata.spec.js +37 -0
- package/test/unit/dataContract/DataContract.spec.js +407 -0
- package/test/unit/dataContract/DataContractFactory.spec.js +178 -0
- package/test/unit/dataContract/createDataContract.spec.js +57 -0
- package/test/unit/dataContract/errors/InvalidDataContractError.spec.js +46 -0
- package/test/unit/dataContract/generateDataContractId.spec.js +19 -0
- package/test/unit/dataContract/getBinaryPropertiesFromSchema.spec.js +103 -0
- package/test/unit/dataContract/getPropertyDefinitionByPath.spec.js +84 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition.spec.js +160 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/applyDataContractCreateTransitionFactory.spec.js +48 -0
- package/test/unit/dataContract/stateTransition/DataContractCreateTransition/validation/state/validateDataContractCreateTransitionStateFactory.spec.js +85 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition.spec.js +158 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory.spec.js +47 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible.spec.js +121 -0
- package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +111 -0
- package/test/unit/dataContract/validation/validateDataContractMaxDepthFactory.spec.js +93 -0
- package/test/unit/dataContract/validation/validateDataContractPatternsFactory.spec.js +64 -0
- package/test/unit/dataTrigger/DataTrigger.spec.js +132 -0
- package/test/unit/dataTrigger/DataTriggerExecutionContext.spec.js +29 -0
- package/test/unit/dataTrigger/dashpayDataTriggers/createContactRequestDataTrigger.spec.js +109 -0
- package/test/unit/dataTrigger/dpnsTriggers/createDomainDataTrigger.spec.js +382 -0
- package/test/unit/dataTrigger/featureFlagDataTriggers/createFeatureFlagDataTrigger.spec.js +101 -0
- package/test/unit/dataTrigger/getDataTriggersFactory.spec.js +113 -0
- package/test/unit/dataTrigger/rejectDataTrigger.spec.js +51 -0
- package/test/unit/dataTrigger/rewardShareDataTriggers/createMasternodeRewardSharesDataTrigger.spec.js +200 -0
- package/test/unit/decodeProtocolEntityFactory.spec.js +75 -0
- package/test/unit/document/Document.spec.js +444 -0
- package/test/unit/document/DocumentFactory.spec.js +376 -0
- package/test/unit/document/errors/InvalidDocumentError.spec.js +46 -0
- package/test/unit/document/fetchAndValidateDataContractFactory.spec.js +66 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +168 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +171 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/documentTransition/DocumentCreateTransition.spec.js +25 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js +31 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +122 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/validatePartialCompoundIndices.spec.js +75 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +128 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +811 -0
- package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +279 -0
- package/test/unit/errors/consensus/codes.spec.js +102 -0
- package/test/unit/identity/Identity.spec.js +243 -0
- package/test/unit/identity/IdentityFactory.spec.js +274 -0
- package/test/unit/identity/IdentityPublicKey.spec.js +273 -0
- package/test/unit/identity/creditsConverter.spec.js +34 -0
- package/test/unit/identity/errors/InvalidIdentityError.spec.js +46 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/IdentityCreateTransition.spec.js +184 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/applyIdentityCreateTransitionFactory.spec.js +90 -0
- package/test/unit/identity/stateTransition/IdentityCreateTransition/validation/state/validateIdentityCreateTransitionStateFactory.spec.js +71 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/IdentityTopUpTransition.spec.js +137 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/applyIdentityTopUpTransitionFactory.spec.js +108 -0
- package/test/unit/identity/stateTransition/IdentityTopUpTransition/validation/state/validateIdentityTopUpTransitionStateFactory.spec.js +22 -0
- package/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js +219 -0
- package/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +149 -0
- package/test/unit/identity/stateTransition/assetLockProof/createAssetLockProofInstance.spec.js +21 -0
- package/test/unit/identity/stateTransition/assetLockProof/fetchAssetLockPublicKeyHashFactory.spec.js +36 -0
- package/test/unit/identity/validation/validateRequiredPurposeAndSecurityLevelFactory.spec.js +47 -0
- package/test/unit/stateTransition/StateTransitionFactory.spec.js +160 -0
- package/test/unit/stateTransition/createStateTransitionFactory.spec.js +72 -0
- package/test/unit/stateTransition/errors/InvalidStateTransitionError.spec.js +51 -0
- package/test/unit/stateTransition/validation/validateStateTransitionBasicFactory.spec.js +138 -0
- package/test/unit/stateTransition/validation/validateStateTransitionFeeFactory.spec.js +372 -0
- package/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js +339 -0
- package/test/unit/stateTransition/validation/validateStateTransitionKeySignatureFactory.spec.js +86 -0
- package/test/unit/stateTransition/validation/validateStateTransitionStateFactory.spec.js +89 -0
- package/test/unit/version/validateProtocolVersionFactory.spec.js +80 -0
- package/webpack.config.js +49 -0
|
@@ -0,0 +1,2191 @@
|
|
|
1
|
+
const { getRE2Class } = require('@dashevo/wasm-re2');
|
|
2
|
+
const lodashCloneDeep = require('lodash.clonedeep');
|
|
3
|
+
|
|
4
|
+
const $RefParser = require('@apidevtools/json-schema-ref-parser');
|
|
5
|
+
|
|
6
|
+
const createAjv = require('../../../../lib/ajv/createAjv');
|
|
7
|
+
|
|
8
|
+
const JsonSchemaValidator = require('../../../../lib/validation/JsonSchemaValidator');
|
|
9
|
+
|
|
10
|
+
const ValidationResult = require('../../../../lib/validation/ValidationResult');
|
|
11
|
+
|
|
12
|
+
const validateDataContractFactory = require('../../../../lib/dataContract/validation/validateDataContractFactory');
|
|
13
|
+
const validateDataContractMaxDepthFactory = require('../../../../lib/dataContract/validation/validateDataContractMaxDepthFactory');
|
|
14
|
+
const enrichDataContractWithBaseSchema = require('../../../../lib/dataContract/enrichDataContractWithBaseSchema');
|
|
15
|
+
const validateDataContractPatternsFactory = require('../../../../lib/dataContract/validation/validateDataContractPatternsFactory');
|
|
16
|
+
|
|
17
|
+
const getDataContractFixture = require('../../../../lib/test/fixtures/getDataContractFixture');
|
|
18
|
+
|
|
19
|
+
const { expectJsonSchemaError, expectValidationError } = require('../../../../lib/test/expect/expectError');
|
|
20
|
+
|
|
21
|
+
const DuplicateIndexError = require('../../../../lib/errors/consensus/basic/dataContract/DuplicateIndexError');
|
|
22
|
+
const UndefinedIndexPropertyError = require('../../../../lib/errors/consensus/basic/dataContract/UndefinedIndexPropertyError');
|
|
23
|
+
const InvalidIndexPropertyTypeError = require('../../../../lib/errors/consensus/basic/dataContract/InvalidIndexPropertyTypeError');
|
|
24
|
+
const SystemPropertyIndexAlreadyPresentError = require('../../../../lib/errors/consensus/basic/dataContract/SystemPropertyIndexAlreadyPresentError');
|
|
25
|
+
const UniqueIndicesLimitReachedError = require('../../../../lib/errors/consensus/basic/dataContract/UniqueIndicesLimitReachedError');
|
|
26
|
+
const InvalidIndexedPropertyConstraintError = require('../../../../lib/errors/consensus/basic/dataContract/InvalidIndexedPropertyConstraintError');
|
|
27
|
+
const InvalidCompoundIndexError = require('../../../../lib/errors/consensus/basic/dataContract/InvalidCompoundIndexError');
|
|
28
|
+
const IncompatibleRe2PatternError = require('../../../../lib/errors/consensus/basic/dataContract/IncompatibleRe2PatternError');
|
|
29
|
+
const InvalidJsonSchemaRefError = require('../../../../lib/errors/consensus/basic/dataContract/InvalidJsonSchemaRefError');
|
|
30
|
+
const JsonSchemaCompilationError = require('../../../../lib/errors/consensus/basic/JsonSchemaCompilationError');
|
|
31
|
+
const SomeConsensusError = require('../../../../lib/test/mocks/SomeConsensusError');
|
|
32
|
+
const getPropertyDefinitionByPath = require('../../../../lib/dataContract/getPropertyDefinitionByPath');
|
|
33
|
+
|
|
34
|
+
describe('validateDataContractFactory', function main() {
|
|
35
|
+
this.timeout(15000);
|
|
36
|
+
|
|
37
|
+
let dataContract;
|
|
38
|
+
let rawDataContract;
|
|
39
|
+
let validateDataContract;
|
|
40
|
+
let RE2;
|
|
41
|
+
let validateProtocolVersionMock;
|
|
42
|
+
|
|
43
|
+
before(async () => {
|
|
44
|
+
RE2 = await getRE2Class();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
beforeEach(async function beforeEach() {
|
|
48
|
+
dataContract = getDataContractFixture();
|
|
49
|
+
rawDataContract = dataContract.toObject();
|
|
50
|
+
|
|
51
|
+
const ajv = createAjv(RE2);
|
|
52
|
+
const jsonSchemaValidator = new JsonSchemaValidator(ajv);
|
|
53
|
+
|
|
54
|
+
const validateDataContractMaxDepth = validateDataContractMaxDepthFactory($RefParser);
|
|
55
|
+
|
|
56
|
+
const validateDataContractPatterns = validateDataContractPatternsFactory(RE2);
|
|
57
|
+
|
|
58
|
+
validateProtocolVersionMock = this.sinonSandbox.stub().returns(new ValidationResult());
|
|
59
|
+
|
|
60
|
+
validateDataContract = validateDataContractFactory(
|
|
61
|
+
jsonSchemaValidator,
|
|
62
|
+
validateDataContractMaxDepth,
|
|
63
|
+
enrichDataContractWithBaseSchema,
|
|
64
|
+
validateDataContractPatterns,
|
|
65
|
+
validateProtocolVersionMock,
|
|
66
|
+
getPropertyDefinitionByPath,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('protocolVersion', () => {
|
|
71
|
+
it('should be present', async () => {
|
|
72
|
+
rawDataContract = {
|
|
73
|
+
documents: {
|
|
74
|
+
someDocument: {
|
|
75
|
+
type: 'object',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
delete rawDataContract.protocolVersion;
|
|
80
|
+
|
|
81
|
+
const result = await validateDataContract(rawDataContract);
|
|
82
|
+
|
|
83
|
+
expectJsonSchemaError(result);
|
|
84
|
+
|
|
85
|
+
const [error] = result.getErrors();
|
|
86
|
+
|
|
87
|
+
expect(error.getInstancePath()).to.equal('');
|
|
88
|
+
expect(error.getKeyword()).to.equal('required');
|
|
89
|
+
expect(error.getParams().missingProperty).to.equal('protocolVersion');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should be an integer', async () => {
|
|
93
|
+
rawDataContract.protocolVersion = '1';
|
|
94
|
+
|
|
95
|
+
const result = await validateDataContract(rawDataContract);
|
|
96
|
+
|
|
97
|
+
expectJsonSchemaError(result);
|
|
98
|
+
|
|
99
|
+
const [error] = result.getErrors();
|
|
100
|
+
|
|
101
|
+
expect(error.getInstancePath()).to.equal('/protocolVersion');
|
|
102
|
+
expect(error.getKeyword()).to.equal('type');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should be valid', async () => {
|
|
106
|
+
rawDataContract.protocolVersion = -1;
|
|
107
|
+
|
|
108
|
+
const protocolVersionError = new SomeConsensusError('test');
|
|
109
|
+
const protocolVersionResult = new ValidationResult([
|
|
110
|
+
protocolVersionError,
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
validateProtocolVersionMock.returns(protocolVersionResult);
|
|
114
|
+
|
|
115
|
+
const result = await validateDataContract(rawDataContract);
|
|
116
|
+
|
|
117
|
+
expectValidationError(result, SomeConsensusError);
|
|
118
|
+
|
|
119
|
+
const [error] = result.getErrors();
|
|
120
|
+
|
|
121
|
+
expect(error).to.equal(protocolVersionError);
|
|
122
|
+
|
|
123
|
+
expect(validateProtocolVersionMock).to.be.calledOnceWith(
|
|
124
|
+
rawDataContract.protocolVersion,
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('$schema', () => {
|
|
130
|
+
it('should be present', async () => {
|
|
131
|
+
delete rawDataContract.$schema;
|
|
132
|
+
|
|
133
|
+
const result = await validateDataContract(rawDataContract);
|
|
134
|
+
|
|
135
|
+
expectJsonSchemaError(result);
|
|
136
|
+
|
|
137
|
+
const [error] = result.getErrors();
|
|
138
|
+
|
|
139
|
+
expect(error.getInstancePath()).to.equal('');
|
|
140
|
+
expect(error.getKeyword()).to.equal('required');
|
|
141
|
+
expect(error.getParams().missingProperty).to.equal('$schema');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should be a string', async () => {
|
|
145
|
+
rawDataContract.$schema = 1;
|
|
146
|
+
|
|
147
|
+
const result = await validateDataContract(rawDataContract);
|
|
148
|
+
|
|
149
|
+
expectJsonSchemaError(result);
|
|
150
|
+
|
|
151
|
+
const [error] = result.getErrors();
|
|
152
|
+
|
|
153
|
+
expect(error.getInstancePath()).to.equal('/$schema');
|
|
154
|
+
expect(error.getKeyword()).to.equal('type');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should be a particular url', async () => {
|
|
158
|
+
rawDataContract.$schema = 'wrong';
|
|
159
|
+
|
|
160
|
+
const result = await validateDataContract(rawDataContract);
|
|
161
|
+
|
|
162
|
+
expectJsonSchemaError(result);
|
|
163
|
+
|
|
164
|
+
const [error] = result.getErrors();
|
|
165
|
+
|
|
166
|
+
expect(error.getKeyword()).to.equal('const');
|
|
167
|
+
expect(error.getInstancePath()).to.equal('/$schema');
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('ownerId', () => {
|
|
172
|
+
it('should be present', async () => {
|
|
173
|
+
delete rawDataContract.ownerId;
|
|
174
|
+
|
|
175
|
+
const result = await validateDataContract(rawDataContract);
|
|
176
|
+
|
|
177
|
+
expectJsonSchemaError(result);
|
|
178
|
+
|
|
179
|
+
const [error] = result.getErrors();
|
|
180
|
+
|
|
181
|
+
expect(error.getInstancePath()).to.equal('');
|
|
182
|
+
expect(error.getKeyword()).to.equal('required');
|
|
183
|
+
expect(error.getParams().missingProperty).to.equal('ownerId');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should be a byte array', async () => {
|
|
187
|
+
rawDataContract.ownerId = new Array(32).fill('string');
|
|
188
|
+
|
|
189
|
+
const result = await validateDataContract(rawDataContract);
|
|
190
|
+
|
|
191
|
+
expectJsonSchemaError(result, 2);
|
|
192
|
+
|
|
193
|
+
const [error, byteArrayError] = result.getErrors();
|
|
194
|
+
|
|
195
|
+
expect(error.getInstancePath()).to.equal('/ownerId/0');
|
|
196
|
+
expect(error.getKeyword()).to.equal('type');
|
|
197
|
+
|
|
198
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should be no less than 32 bytes', async () => {
|
|
202
|
+
rawDataContract.ownerId = Buffer.alloc(31);
|
|
203
|
+
|
|
204
|
+
const result = await validateDataContract(rawDataContract);
|
|
205
|
+
|
|
206
|
+
expectJsonSchemaError(result);
|
|
207
|
+
|
|
208
|
+
const [error] = result.getErrors();
|
|
209
|
+
|
|
210
|
+
expect(error.getInstancePath()).to.equal('/ownerId');
|
|
211
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should be no longer than 32 bytes', async () => {
|
|
215
|
+
rawDataContract.ownerId = Buffer.alloc(33);
|
|
216
|
+
|
|
217
|
+
const result = await validateDataContract(rawDataContract);
|
|
218
|
+
|
|
219
|
+
expectJsonSchemaError(result);
|
|
220
|
+
|
|
221
|
+
const [error] = result.getErrors();
|
|
222
|
+
|
|
223
|
+
expect(error.getInstancePath()).to.equal('/ownerId');
|
|
224
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe('$id', () => {
|
|
229
|
+
it('should be present', async () => {
|
|
230
|
+
delete rawDataContract.$id;
|
|
231
|
+
|
|
232
|
+
const result = await validateDataContract(rawDataContract);
|
|
233
|
+
|
|
234
|
+
expectJsonSchemaError(result);
|
|
235
|
+
|
|
236
|
+
const [error] = result.getErrors();
|
|
237
|
+
|
|
238
|
+
expect(error.getInstancePath()).to.equal('');
|
|
239
|
+
expect(error.getKeyword()).to.equal('required');
|
|
240
|
+
expect(error.getParams().missingProperty).to.equal('$id');
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should be a byte array', async () => {
|
|
244
|
+
rawDataContract.$id = new Array(32).fill('string');
|
|
245
|
+
|
|
246
|
+
const result = await validateDataContract(rawDataContract);
|
|
247
|
+
|
|
248
|
+
expectJsonSchemaError(result, 2);
|
|
249
|
+
|
|
250
|
+
const [error, byteArrayError] = result.getErrors();
|
|
251
|
+
|
|
252
|
+
expect(error.getInstancePath()).to.equal('/$id/0');
|
|
253
|
+
expect(error.getKeyword()).to.equal('type');
|
|
254
|
+
|
|
255
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('should be no less than 32 bytes', async () => {
|
|
259
|
+
rawDataContract.$id = Buffer.alloc(31);
|
|
260
|
+
|
|
261
|
+
const result = await validateDataContract(rawDataContract);
|
|
262
|
+
|
|
263
|
+
expectJsonSchemaError(result);
|
|
264
|
+
|
|
265
|
+
const [error] = result.getErrors();
|
|
266
|
+
|
|
267
|
+
expect(error.getInstancePath()).to.equal('/$id');
|
|
268
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should be no longer than 32 bytes', async () => {
|
|
272
|
+
rawDataContract.$id = Buffer.alloc(33);
|
|
273
|
+
|
|
274
|
+
const result = await validateDataContract(rawDataContract);
|
|
275
|
+
|
|
276
|
+
expectJsonSchemaError(result);
|
|
277
|
+
|
|
278
|
+
const [error] = result.getErrors();
|
|
279
|
+
|
|
280
|
+
expect(error.getInstancePath()).to.equal('/$id');
|
|
281
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
describe('$defs', () => {
|
|
286
|
+
it('may not be present', async () => {
|
|
287
|
+
delete rawDataContract.$defs;
|
|
288
|
+
delete rawDataContract.documents.prettyDocument;
|
|
289
|
+
|
|
290
|
+
const result = await validateDataContract(rawDataContract);
|
|
291
|
+
|
|
292
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
293
|
+
expect(result.isValid()).to.be.true();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should be an object', async () => {
|
|
297
|
+
rawDataContract.$defs = 1;
|
|
298
|
+
|
|
299
|
+
const result = await validateDataContract(rawDataContract);
|
|
300
|
+
|
|
301
|
+
expectJsonSchemaError(result);
|
|
302
|
+
|
|
303
|
+
const [error] = result.getErrors();
|
|
304
|
+
|
|
305
|
+
expect(error.getInstancePath()).to.equal('/$defs');
|
|
306
|
+
expect(error.getKeyword()).to.equal('type');
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should not be empty', async () => {
|
|
310
|
+
rawDataContract.$defs = {};
|
|
311
|
+
|
|
312
|
+
const result = await validateDataContract(rawDataContract);
|
|
313
|
+
|
|
314
|
+
expectJsonSchemaError(result);
|
|
315
|
+
|
|
316
|
+
const [error] = result.getErrors();
|
|
317
|
+
|
|
318
|
+
expect(error.getInstancePath()).to.equal('/$defs');
|
|
319
|
+
expect(error.getKeyword()).to.equal('minProperties');
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('should have no non-alphanumeric properties', async () => {
|
|
323
|
+
rawDataContract.$defs = {
|
|
324
|
+
$subSchema: {},
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const result = await validateDataContract(rawDataContract);
|
|
328
|
+
|
|
329
|
+
expectJsonSchemaError(result, 2);
|
|
330
|
+
|
|
331
|
+
const [patternError, propertyNamesError] = result.getErrors();
|
|
332
|
+
|
|
333
|
+
expect(patternError.getInstancePath()).to.equal('/$defs');
|
|
334
|
+
expect(patternError.getKeyword()).to.equal('pattern');
|
|
335
|
+
|
|
336
|
+
expect(propertyNamesError.getInstancePath()).to.equal('/$defs');
|
|
337
|
+
expect(propertyNamesError.getKeyword()).to.equal('propertyNames');
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('should have no more than 100 properties', async () => {
|
|
341
|
+
rawDataContract.$defs = {};
|
|
342
|
+
|
|
343
|
+
Array(101).fill({ type: 'string' }).forEach((item, i) => {
|
|
344
|
+
rawDataContract.$defs[i] = item;
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const result = await validateDataContract(rawDataContract);
|
|
348
|
+
|
|
349
|
+
expectJsonSchemaError(result);
|
|
350
|
+
|
|
351
|
+
const [error] = result.getErrors();
|
|
352
|
+
|
|
353
|
+
expect(error.getInstancePath()).to.equal('/$defs');
|
|
354
|
+
expect(error.getKeyword()).to.equal('maxProperties');
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('should have valid property names', async () => {
|
|
358
|
+
const validNames = ['validName', 'valid_name', 'valid-name', 'abc', 'ab12c', 'abc123', 'ValidName',
|
|
359
|
+
'abcdefghigklmnopqrstuvwxyz01234567890abcdefghigklmnopqrstuvwxyz', 'abc_gbf_gdb', 'abc-gbf-gdb',
|
|
360
|
+
'-validname', '_validname', 'validname-', 'validname_', 'a', 'ab', '1', '123', '123_', '-123', '_123'];
|
|
361
|
+
|
|
362
|
+
await Promise.all(
|
|
363
|
+
validNames.map(async (name) => {
|
|
364
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
365
|
+
|
|
366
|
+
clonedDataContract.$defs = {};
|
|
367
|
+
clonedDataContract.$defs[name] = {
|
|
368
|
+
type: 'string',
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
clonedDataContract.$defs[name] = {
|
|
372
|
+
type: 'string',
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const result = await validateDataContract(clonedDataContract);
|
|
376
|
+
|
|
377
|
+
expectJsonSchemaError(result, 0);
|
|
378
|
+
}),
|
|
379
|
+
);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('should return an invalid result if a property has invalid format', async () => {
|
|
383
|
+
const invalidNames = ['*(*&^', '$test', '.', '.a'];
|
|
384
|
+
|
|
385
|
+
await Promise.all(
|
|
386
|
+
invalidNames.map(async (name) => {
|
|
387
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
388
|
+
|
|
389
|
+
clonedDataContract.$defs = {};
|
|
390
|
+
clonedDataContract.$defs[name] = {
|
|
391
|
+
type: 'string',
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const result = await validateDataContract(clonedDataContract);
|
|
395
|
+
|
|
396
|
+
expectJsonSchemaError(result, 2);
|
|
397
|
+
|
|
398
|
+
const [error] = result.getErrors();
|
|
399
|
+
|
|
400
|
+
expect(error.getInstancePath()).to.equal('/$defs');
|
|
401
|
+
expect(error.getKeyword()).to.equal('pattern');
|
|
402
|
+
}),
|
|
403
|
+
);
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
describe('documents', () => {
|
|
408
|
+
it('should be present', async () => {
|
|
409
|
+
delete rawDataContract.documents;
|
|
410
|
+
|
|
411
|
+
const result = await validateDataContract(rawDataContract);
|
|
412
|
+
|
|
413
|
+
expectJsonSchemaError(result);
|
|
414
|
+
|
|
415
|
+
const [error] = result.getErrors();
|
|
416
|
+
|
|
417
|
+
expect(error.getInstancePath()).to.equal('');
|
|
418
|
+
expect(error.getKeyword()).to.equal('required');
|
|
419
|
+
expect(error.getParams().missingProperty).to.equal('documents');
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('should be an object', async () => {
|
|
423
|
+
rawDataContract.documents = 1;
|
|
424
|
+
|
|
425
|
+
const result = await validateDataContract(rawDataContract);
|
|
426
|
+
|
|
427
|
+
expectJsonSchemaError(result);
|
|
428
|
+
|
|
429
|
+
const [error] = result.getErrors();
|
|
430
|
+
|
|
431
|
+
expect(error.getInstancePath()).to.equal('/documents');
|
|
432
|
+
expect(error.getKeyword()).to.equal('type');
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('should not be empty', async () => {
|
|
436
|
+
rawDataContract.documents = {};
|
|
437
|
+
|
|
438
|
+
const result = await validateDataContract(rawDataContract);
|
|
439
|
+
|
|
440
|
+
expectJsonSchemaError(result);
|
|
441
|
+
|
|
442
|
+
const [error] = result.getErrors();
|
|
443
|
+
|
|
444
|
+
expect(error.getInstancePath()).to.equal('/documents');
|
|
445
|
+
expect(error.getKeyword()).to.equal('minProperties');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should have valid property names (document types)', async () => {
|
|
449
|
+
const validNames = ['validName', 'valid_name', 'valid-name', 'abc', 'a123123bc', 'ab123c', 'ValidName', 'validName',
|
|
450
|
+
'abcdefghigklmnopqrstuvwxyz01234567890abcdefghigklmnopqrstuvwxyz', 'abc_gbf_gdb', 'abc-gbf-gdb'];
|
|
451
|
+
|
|
452
|
+
await Promise.all(
|
|
453
|
+
validNames.map(async (name) => {
|
|
454
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
455
|
+
|
|
456
|
+
clonedDataContract.documents[name] = clonedDataContract.documents.niceDocument;
|
|
457
|
+
|
|
458
|
+
const result = await validateDataContract(clonedDataContract);
|
|
459
|
+
|
|
460
|
+
expectJsonSchemaError(result, 0);
|
|
461
|
+
}),
|
|
462
|
+
);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
it('should return an invalid result if a property (document type) has invalid format', async () => {
|
|
466
|
+
const invalidNames = ['*(*&^', '$test', '.', '.a'];
|
|
467
|
+
|
|
468
|
+
await Promise.all(
|
|
469
|
+
invalidNames.map(async (name) => {
|
|
470
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
471
|
+
|
|
472
|
+
clonedDataContract.documents[name] = clonedDataContract.documents.niceDocument;
|
|
473
|
+
|
|
474
|
+
const result = await validateDataContract(clonedDataContract);
|
|
475
|
+
|
|
476
|
+
expectJsonSchemaError(result, 2);
|
|
477
|
+
|
|
478
|
+
const [error] = result.getErrors();
|
|
479
|
+
|
|
480
|
+
expect(error.getInstancePath()).to.equal('/documents');
|
|
481
|
+
expect(error.getKeyword()).to.equal('pattern');
|
|
482
|
+
}),
|
|
483
|
+
);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should have no more than 100 properties', async () => {
|
|
487
|
+
const niceDocumentDefinition = rawDataContract.documents.niceDocument;
|
|
488
|
+
|
|
489
|
+
rawDataContract.documents = {};
|
|
490
|
+
|
|
491
|
+
Array(101).fill(niceDocumentDefinition).forEach((item, i) => {
|
|
492
|
+
rawDataContract.documents[i] = item;
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
const result = await validateDataContract(rawDataContract);
|
|
496
|
+
|
|
497
|
+
expectJsonSchemaError(result);
|
|
498
|
+
|
|
499
|
+
const [error] = result.getErrors();
|
|
500
|
+
|
|
501
|
+
expect(error.getInstancePath()).to.equal('/documents');
|
|
502
|
+
expect(error.getKeyword()).to.equal('maxProperties');
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
describe('Document schema', () => {
|
|
506
|
+
it('should not be empty', async () => {
|
|
507
|
+
rawDataContract.documents.niceDocument.properties = {};
|
|
508
|
+
|
|
509
|
+
const result = await validateDataContract(rawDataContract);
|
|
510
|
+
|
|
511
|
+
expectJsonSchemaError(result, 2);
|
|
512
|
+
|
|
513
|
+
const [error] = result.getErrors();
|
|
514
|
+
|
|
515
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/properties');
|
|
516
|
+
expect(error.getKeyword()).to.equal('minProperties');
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('should have type "object"', async () => {
|
|
520
|
+
rawDataContract.documents.niceDocument.type = 'string';
|
|
521
|
+
|
|
522
|
+
const result = await validateDataContract(rawDataContract);
|
|
523
|
+
|
|
524
|
+
expectJsonSchemaError(result);
|
|
525
|
+
|
|
526
|
+
const [error] = result.getErrors();
|
|
527
|
+
|
|
528
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/type');
|
|
529
|
+
expect(error.getKeyword()).to.equal('const');
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('should have "properties"', async () => {
|
|
533
|
+
delete rawDataContract.documents.niceDocument.properties;
|
|
534
|
+
|
|
535
|
+
const result = await validateDataContract(rawDataContract);
|
|
536
|
+
|
|
537
|
+
expectJsonSchemaError(result);
|
|
538
|
+
|
|
539
|
+
const [error] = result.getErrors();
|
|
540
|
+
|
|
541
|
+
expect(error.instancePath).to.equal('/documents/niceDocument');
|
|
542
|
+
expect(error.getKeyword()).to.equal('required');
|
|
543
|
+
expect(error.getParams().missingProperty).to.equal('properties');
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('should have nested "properties"', async () => {
|
|
547
|
+
rawDataContract.documents.niceDocument.properties.object = {
|
|
548
|
+
type: 'array',
|
|
549
|
+
prefixItems: [
|
|
550
|
+
{
|
|
551
|
+
type: 'object',
|
|
552
|
+
properties: {
|
|
553
|
+
something: {
|
|
554
|
+
type: 'object',
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
additionalProperties: false,
|
|
558
|
+
},
|
|
559
|
+
],
|
|
560
|
+
items: false,
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const result = await validateDataContract(rawDataContract);
|
|
564
|
+
|
|
565
|
+
expectJsonSchemaError(result, 3);
|
|
566
|
+
|
|
567
|
+
const [error] = result.getErrors();
|
|
568
|
+
|
|
569
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/properties/object/prefixItems/0/properties/something');
|
|
570
|
+
expect(error.getKeyword()).to.equal('required');
|
|
571
|
+
expect(error.getParams().missingProperty).to.equal('properties');
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it('should have valid property names', async () => {
|
|
575
|
+
const validNames = ['validName', 'valid_name', 'valid-name', 'abc', 'a123bc', 'abc123', 'ValidName', 'validName',
|
|
576
|
+
'abcdefghigklmnopqrstuvwxyz01234567890abcdefghigklmnopqrstuvwxyz', 'abc_gbf_gdb', 'abc-gbf-gdb'];
|
|
577
|
+
|
|
578
|
+
await Promise.all(
|
|
579
|
+
validNames.map(async (name) => {
|
|
580
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
581
|
+
|
|
582
|
+
clonedDataContract.documents.niceDocument.properties[name] = {
|
|
583
|
+
type: 'string',
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
const result = await validateDataContract(clonedDataContract);
|
|
587
|
+
|
|
588
|
+
expectJsonSchemaError(result, 0);
|
|
589
|
+
}),
|
|
590
|
+
);
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
it('should have valid nested property names', async () => {
|
|
594
|
+
const validNames = ['validName', 'valid_name', 'valid-name', 'abc', 'a123bc', 'abc123', 'ValidName', 'validName',
|
|
595
|
+
'abcdefghigklmnopqrstuvwxyz01234567890abcdefghigklmnopqrstuvwxyz', 'abc_gbf_gdb', 'abc-gbf-gdb'];
|
|
596
|
+
|
|
597
|
+
rawDataContract.documents.niceDocument.properties.something = {
|
|
598
|
+
type: 'object',
|
|
599
|
+
properties: {},
|
|
600
|
+
additionalProperties: false,
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
await Promise.all(
|
|
604
|
+
validNames.map(async (name) => {
|
|
605
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
606
|
+
|
|
607
|
+
clonedDataContract.documents.niceDocument.properties.something.properties[name] = {
|
|
608
|
+
type: 'string',
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const result = await validateDataContract(clonedDataContract);
|
|
612
|
+
|
|
613
|
+
expectJsonSchemaError(result, 0);
|
|
614
|
+
}),
|
|
615
|
+
);
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
it('should return an invalid result if a property has invalid format', async () => {
|
|
619
|
+
const invalidNames = ['*(*&^', '$test', '.', '.a'];
|
|
620
|
+
|
|
621
|
+
await Promise.all(
|
|
622
|
+
invalidNames.map(async (name) => {
|
|
623
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
624
|
+
|
|
625
|
+
clonedDataContract.documents.niceDocument.properties[name] = {};
|
|
626
|
+
|
|
627
|
+
const result = await validateDataContract(clonedDataContract);
|
|
628
|
+
|
|
629
|
+
expectJsonSchemaError(result, 3);
|
|
630
|
+
|
|
631
|
+
const errors = result.getErrors();
|
|
632
|
+
|
|
633
|
+
expect(errors[0].instancePath).to.equal('/documents/niceDocument/properties');
|
|
634
|
+
expect(errors[0].keyword).to.equal('pattern');
|
|
635
|
+
expect(errors[1].instancePath).to.equal('/documents/niceDocument/properties');
|
|
636
|
+
expect(errors[1].keyword).to.equal('propertyNames');
|
|
637
|
+
}),
|
|
638
|
+
);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
it('should return an invalid result if a nested property has invalid format', async () => {
|
|
642
|
+
const invalidNames = ['*(*&^', '$test', '.', '.a'];
|
|
643
|
+
|
|
644
|
+
rawDataContract.documents.niceDocument.properties.something = {
|
|
645
|
+
properties: {},
|
|
646
|
+
additionalProperties: false,
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
await Promise.all(
|
|
650
|
+
invalidNames.map(async (name) => {
|
|
651
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
652
|
+
|
|
653
|
+
clonedDataContract.documents.niceDocument.properties.something.properties[name] = {};
|
|
654
|
+
|
|
655
|
+
const result = await validateDataContract(clonedDataContract);
|
|
656
|
+
|
|
657
|
+
expectJsonSchemaError(result, 4);
|
|
658
|
+
|
|
659
|
+
const errors = result.getErrors();
|
|
660
|
+
|
|
661
|
+
expect(errors[0].instancePath).to.equal(
|
|
662
|
+
'/documents/niceDocument/properties/something/properties',
|
|
663
|
+
);
|
|
664
|
+
expect(errors[0].keyword).to.equal('pattern');
|
|
665
|
+
expect(errors[1].instancePath).to.equal(
|
|
666
|
+
'/documents/niceDocument/properties/something/properties',
|
|
667
|
+
);
|
|
668
|
+
expect(errors[1].keyword).to.equal('propertyNames');
|
|
669
|
+
}),
|
|
670
|
+
);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
it('should have "additionalProperties" defined', async () => {
|
|
674
|
+
delete rawDataContract.documents.niceDocument.additionalProperties;
|
|
675
|
+
|
|
676
|
+
const result = await validateDataContract(rawDataContract);
|
|
677
|
+
|
|
678
|
+
expectJsonSchemaError(result);
|
|
679
|
+
|
|
680
|
+
const [error] = result.getErrors();
|
|
681
|
+
|
|
682
|
+
expect(error.instancePath).to.equal('/documents/niceDocument');
|
|
683
|
+
expect(error.getKeyword()).to.equal('required');
|
|
684
|
+
expect(error.getParams().missingProperty).to.equal('additionalProperties');
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('should have "additionalProperties" defined to false', async () => {
|
|
688
|
+
rawDataContract.documents.niceDocument.additionalProperties = true;
|
|
689
|
+
|
|
690
|
+
const result = await validateDataContract(rawDataContract);
|
|
691
|
+
|
|
692
|
+
expectJsonSchemaError(result);
|
|
693
|
+
|
|
694
|
+
const [error] = result.getErrors();
|
|
695
|
+
|
|
696
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/additionalProperties');
|
|
697
|
+
expect(error.getKeyword()).to.equal('const');
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it('should have nested "additionalProperties" defined', async () => {
|
|
701
|
+
rawDataContract.documents.niceDocument.properties.object = {
|
|
702
|
+
type: 'array',
|
|
703
|
+
prefixItems: [
|
|
704
|
+
{
|
|
705
|
+
type: 'object',
|
|
706
|
+
properties: {
|
|
707
|
+
something: {
|
|
708
|
+
type: 'string',
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
],
|
|
713
|
+
items: false,
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
const result = await validateDataContract(rawDataContract);
|
|
717
|
+
|
|
718
|
+
expectJsonSchemaError(result, 2);
|
|
719
|
+
|
|
720
|
+
const [error] = result.getErrors();
|
|
721
|
+
|
|
722
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/properties/object/prefixItems/0');
|
|
723
|
+
expect(error.getKeyword()).to.equal('required');
|
|
724
|
+
expect(error.getParams().missingProperty).to.equal('additionalProperties');
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
it('should return invalid result if there are additional properties', async () => {
|
|
728
|
+
rawDataContract.additionalProperty = { };
|
|
729
|
+
|
|
730
|
+
const result = await validateDataContract(rawDataContract);
|
|
731
|
+
|
|
732
|
+
expectJsonSchemaError(result);
|
|
733
|
+
|
|
734
|
+
const [error] = result.getErrors();
|
|
735
|
+
|
|
736
|
+
expect(error.instancePath).to.equal('');
|
|
737
|
+
expect(error.getKeyword()).to.equal('additionalProperties');
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should have no more than 100 properties', async () => {
|
|
741
|
+
const propertyDefinition = { };
|
|
742
|
+
|
|
743
|
+
rawDataContract.documents.niceDocument.properties = {};
|
|
744
|
+
|
|
745
|
+
Array(101).fill(propertyDefinition).forEach((item, i) => {
|
|
746
|
+
rawDataContract.documents.niceDocument.properties[i] = item;
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
const result = await validateDataContract(rawDataContract);
|
|
750
|
+
|
|
751
|
+
expectJsonSchemaError(result, 2);
|
|
752
|
+
|
|
753
|
+
const [error] = result.getErrors();
|
|
754
|
+
|
|
755
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/properties');
|
|
756
|
+
expect(error.getKeyword()).to.equal('maxProperties');
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('should have defined items for arrays', async () => {
|
|
760
|
+
rawDataContract.documents.new = {
|
|
761
|
+
properties: {
|
|
762
|
+
something: {
|
|
763
|
+
type: 'array',
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
additionalProperties: false,
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
const result = await validateDataContract(rawDataContract);
|
|
770
|
+
|
|
771
|
+
expectJsonSchemaError(result, 2);
|
|
772
|
+
|
|
773
|
+
const [error] = result.getErrors();
|
|
774
|
+
|
|
775
|
+
expect(error.instancePath).to.equal('/documents/new/properties/something');
|
|
776
|
+
expect(error.getKeyword()).to.equal('required');
|
|
777
|
+
expect(error.getParams().missingProperty).to.equal('items');
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
it('should have sub schema in items for arrays', async () => {
|
|
781
|
+
rawDataContract.documents.new = {
|
|
782
|
+
properties: {
|
|
783
|
+
something: {
|
|
784
|
+
type: 'array',
|
|
785
|
+
items: [
|
|
786
|
+
{
|
|
787
|
+
type: 'string',
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
type: 'number',
|
|
791
|
+
},
|
|
792
|
+
],
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
additionalProperties: false,
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
const result = await validateDataContract(rawDataContract);
|
|
799
|
+
|
|
800
|
+
expectJsonSchemaError(result, 3);
|
|
801
|
+
|
|
802
|
+
const [error] = result.getErrors();
|
|
803
|
+
|
|
804
|
+
expect(error.instancePath).to.equal('/documents/new/properties/something/items');
|
|
805
|
+
expect(error.getKeyword()).to.equal('type');
|
|
806
|
+
expect(error.getParams().type).to.equal('object');
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
it('should have items if prefixItems is used for arrays', async () => {
|
|
810
|
+
rawDataContract.documents.new = {
|
|
811
|
+
type: 'object',
|
|
812
|
+
properties: {
|
|
813
|
+
something: {
|
|
814
|
+
type: 'array',
|
|
815
|
+
prefixItems: [
|
|
816
|
+
{
|
|
817
|
+
type: 'string',
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
type: 'number',
|
|
821
|
+
},
|
|
822
|
+
],
|
|
823
|
+
minItems: 2,
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
additionalProperties: false,
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
const result = await validateDataContract(rawDataContract);
|
|
830
|
+
|
|
831
|
+
expectJsonSchemaError(result, 2);
|
|
832
|
+
|
|
833
|
+
const [error] = result.getErrors();
|
|
834
|
+
|
|
835
|
+
expect(error.instancePath).to.equal('/documents/new/properties/something');
|
|
836
|
+
expect(error.getKeyword()).to.equal('required');
|
|
837
|
+
expect(error.getParams().missingProperty).to.equal('items');
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
it('should not have items disabled if prefixItems is used for arrays', async () => {
|
|
841
|
+
rawDataContract.documents.new = {
|
|
842
|
+
properties: {
|
|
843
|
+
something: {
|
|
844
|
+
type: 'array',
|
|
845
|
+
prefixItems: [
|
|
846
|
+
{
|
|
847
|
+
type: 'string',
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
type: 'number',
|
|
851
|
+
},
|
|
852
|
+
],
|
|
853
|
+
items: true,
|
|
854
|
+
},
|
|
855
|
+
},
|
|
856
|
+
additionalProperties: false,
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
const result = await validateDataContract(rawDataContract);
|
|
860
|
+
|
|
861
|
+
expectJsonSchemaError(result, 2);
|
|
862
|
+
|
|
863
|
+
const [error] = result.getErrors();
|
|
864
|
+
|
|
865
|
+
expect(error.instancePath).to.equal('/documents/new/properties/something/items');
|
|
866
|
+
expect(error.getKeyword()).to.equal('const');
|
|
867
|
+
expect(error.getParams().allowedValue).to.equal(false);
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it('should return invalid result if "default" keyword is used', async () => {
|
|
871
|
+
rawDataContract.documents.indexedDocument.properties.firstName.default = '1';
|
|
872
|
+
|
|
873
|
+
const result = await validateDataContract(rawDataContract);
|
|
874
|
+
|
|
875
|
+
expectJsonSchemaError(result, 2);
|
|
876
|
+
|
|
877
|
+
const [error] = result.getErrors();
|
|
878
|
+
|
|
879
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/firstName');
|
|
880
|
+
expect(error.getKeyword()).to.equal('unevaluatedProperties');
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
it.skip('should return invalid result if remote `$ref` is used', async () => {
|
|
884
|
+
rawDataContract.documents.indexedDocument = {
|
|
885
|
+
$ref: 'http://remote.com/schema#',
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
const result = await validateDataContract(rawDataContract);
|
|
889
|
+
|
|
890
|
+
expectJsonSchemaError(result);
|
|
891
|
+
|
|
892
|
+
const [error] = result.getErrors();
|
|
893
|
+
|
|
894
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/$ref');
|
|
895
|
+
expect(error.getKeyword()).to.equal('pattern');
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
it('should not have `propertyNames`', async () => {
|
|
899
|
+
rawDataContract.documents.indexedDocument = {
|
|
900
|
+
type: 'object',
|
|
901
|
+
properties: {
|
|
902
|
+
something: {
|
|
903
|
+
type: 'string',
|
|
904
|
+
},
|
|
905
|
+
},
|
|
906
|
+
propertyNames: {
|
|
907
|
+
pattern: 'abc',
|
|
908
|
+
},
|
|
909
|
+
additionalProperties: false,
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
const result = await validateDataContract(rawDataContract);
|
|
913
|
+
|
|
914
|
+
expectJsonSchemaError(result);
|
|
915
|
+
|
|
916
|
+
const [error] = result.getErrors();
|
|
917
|
+
|
|
918
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument');
|
|
919
|
+
expect(error.getKeyword()).to.equal('unevaluatedProperties');
|
|
920
|
+
expect(error.getParams().unevaluatedProperty).to.equal('propertyNames');
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
it('should have `maxItems` if `uniqueItems` is used', async () => {
|
|
924
|
+
rawDataContract.documents.indexedDocument = {
|
|
925
|
+
type: 'object',
|
|
926
|
+
properties: {
|
|
927
|
+
something: {
|
|
928
|
+
type: 'array',
|
|
929
|
+
uniqueItems: true,
|
|
930
|
+
},
|
|
931
|
+
},
|
|
932
|
+
additionalProperties: false,
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
const result = await validateDataContract(rawDataContract);
|
|
936
|
+
|
|
937
|
+
expectJsonSchemaError(result, 2);
|
|
938
|
+
|
|
939
|
+
const [error] = result.getErrors();
|
|
940
|
+
|
|
941
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something');
|
|
942
|
+
expect(error.getKeyword()).to.equal('required');
|
|
943
|
+
expect(error.getParams().missingProperty).to.equal('items');
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
it('should have `maxItems` no bigger than 100000 if `uniqueItems` is used', async () => {
|
|
947
|
+
rawDataContract.documents.indexedDocument = {
|
|
948
|
+
type: 'object',
|
|
949
|
+
properties: {
|
|
950
|
+
something: {
|
|
951
|
+
type: 'array',
|
|
952
|
+
uniqueItems: true,
|
|
953
|
+
maxItems: 200000,
|
|
954
|
+
items: {
|
|
955
|
+
type: 'object',
|
|
956
|
+
properties: {
|
|
957
|
+
property: {
|
|
958
|
+
type: 'string',
|
|
959
|
+
},
|
|
960
|
+
},
|
|
961
|
+
additionalProperties: false,
|
|
962
|
+
},
|
|
963
|
+
},
|
|
964
|
+
},
|
|
965
|
+
additionalProperties: false,
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
const result = await validateDataContract(rawDataContract);
|
|
969
|
+
|
|
970
|
+
expectJsonSchemaError(result, 2);
|
|
971
|
+
|
|
972
|
+
const [error] = result.getErrors();
|
|
973
|
+
|
|
974
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something/maxItems');
|
|
975
|
+
expect(error.getKeyword()).to.equal('maximum');
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
it('should return invalid result if document JSON Schema is not valid', async () => {
|
|
979
|
+
rawDataContract.documents.indexedDocument = {
|
|
980
|
+
type: 'object',
|
|
981
|
+
properties: {
|
|
982
|
+
something: {
|
|
983
|
+
type: 'string',
|
|
984
|
+
format: 'lalala',
|
|
985
|
+
maxLength: 100,
|
|
986
|
+
},
|
|
987
|
+
},
|
|
988
|
+
additionalProperties: false,
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
const result = await validateDataContract(rawDataContract);
|
|
992
|
+
|
|
993
|
+
expectValidationError(result, JsonSchemaCompilationError);
|
|
994
|
+
|
|
995
|
+
const [error] = result.getErrors();
|
|
996
|
+
|
|
997
|
+
expect(error.getCode()).to.equal(1004);
|
|
998
|
+
|
|
999
|
+
expect(error.message).to.be.a('string').and.satisfy((msg) => (
|
|
1000
|
+
msg.startsWith('unknown format "lalala" ignored in schema')
|
|
1001
|
+
));
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
it('should have `maxLength` if `pattern` is used', async () => {
|
|
1005
|
+
rawDataContract.documents.indexedDocument = {
|
|
1006
|
+
type: 'object',
|
|
1007
|
+
properties: {
|
|
1008
|
+
something: {
|
|
1009
|
+
type: 'string',
|
|
1010
|
+
pattern: 'a',
|
|
1011
|
+
},
|
|
1012
|
+
},
|
|
1013
|
+
additionalProperties: false,
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
const result = await validateDataContract(rawDataContract);
|
|
1017
|
+
|
|
1018
|
+
expectJsonSchemaError(result, 2);
|
|
1019
|
+
|
|
1020
|
+
const [error] = result.getErrors();
|
|
1021
|
+
|
|
1022
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something');
|
|
1023
|
+
expect(error.getKeyword()).to.equal('required');
|
|
1024
|
+
expect(error.getParams().missingProperty).to.equal('maxLength');
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
it('should have `maxLength` no bigger than 50000 if `pattern` is used', async () => {
|
|
1028
|
+
rawDataContract.documents.indexedDocument = {
|
|
1029
|
+
type: 'object',
|
|
1030
|
+
properties: {
|
|
1031
|
+
something: {
|
|
1032
|
+
type: 'string',
|
|
1033
|
+
pattern: 'a',
|
|
1034
|
+
maxLength: 60000,
|
|
1035
|
+
},
|
|
1036
|
+
},
|
|
1037
|
+
additionalProperties: false,
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
const result = await validateDataContract(rawDataContract);
|
|
1041
|
+
|
|
1042
|
+
expectJsonSchemaError(result, 2);
|
|
1043
|
+
|
|
1044
|
+
const [error] = result.getErrors();
|
|
1045
|
+
|
|
1046
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something/maxLength');
|
|
1047
|
+
expect(error.getKeyword()).to.equal('maximum');
|
|
1048
|
+
});
|
|
1049
|
+
|
|
1050
|
+
it('should have `maxLength` if `format` is used', async () => {
|
|
1051
|
+
rawDataContract.documents.indexedDocument = {
|
|
1052
|
+
type: 'object',
|
|
1053
|
+
properties: {
|
|
1054
|
+
something: {
|
|
1055
|
+
type: 'string',
|
|
1056
|
+
format: 'url',
|
|
1057
|
+
},
|
|
1058
|
+
},
|
|
1059
|
+
additionalProperties: false,
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
const result = await validateDataContract(rawDataContract);
|
|
1063
|
+
|
|
1064
|
+
expectJsonSchemaError(result, 2);
|
|
1065
|
+
|
|
1066
|
+
const [error] = result.getErrors();
|
|
1067
|
+
|
|
1068
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something');
|
|
1069
|
+
expect(error.getKeyword()).to.equal('required');
|
|
1070
|
+
expect(error.getParams().missingProperty).to.equal('maxLength');
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
it('should have `maxLength` no bigger than 50000 if `format` is used', async () => {
|
|
1074
|
+
rawDataContract.documents.indexedDocument = {
|
|
1075
|
+
type: 'object',
|
|
1076
|
+
properties: {
|
|
1077
|
+
something: {
|
|
1078
|
+
type: 'string',
|
|
1079
|
+
format: 'url',
|
|
1080
|
+
maxLength: 60000,
|
|
1081
|
+
},
|
|
1082
|
+
},
|
|
1083
|
+
additionalProperties: false,
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
const result = await validateDataContract(rawDataContract);
|
|
1087
|
+
|
|
1088
|
+
expectJsonSchemaError(result, 2);
|
|
1089
|
+
|
|
1090
|
+
const [error] = result.getErrors();
|
|
1091
|
+
|
|
1092
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/properties/something/maxLength');
|
|
1093
|
+
expect(error.getKeyword()).to.equal('maximum');
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
it('should not have incompatible patterns', async () => {
|
|
1097
|
+
rawDataContract.documents.indexedDocument = {
|
|
1098
|
+
type: 'object',
|
|
1099
|
+
properties: {
|
|
1100
|
+
something: {
|
|
1101
|
+
type: 'string',
|
|
1102
|
+
maxLength: 100,
|
|
1103
|
+
pattern: '^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$',
|
|
1104
|
+
},
|
|
1105
|
+
},
|
|
1106
|
+
additionalProperties: false,
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
const result = await validateDataContract(rawDataContract);
|
|
1110
|
+
|
|
1111
|
+
expectValidationError(result, IncompatibleRe2PatternError);
|
|
1112
|
+
|
|
1113
|
+
const [error] = result.getErrors();
|
|
1114
|
+
|
|
1115
|
+
expect(error.getCode()).to.equal(1009);
|
|
1116
|
+
expect(error.getPattern()).to.equal('^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$');
|
|
1117
|
+
expect(error.getPath()).to.equal('/documents/indexedDocument/properties/something');
|
|
1118
|
+
expect(error.getPatternError()).to.be.instanceOf(Error);
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
describe('byteArray', () => {
|
|
1122
|
+
it('should be a boolean', async () => {
|
|
1123
|
+
rawDataContract.documents.withByteArrays.properties.byteArrayField.byteArray = 1;
|
|
1124
|
+
|
|
1125
|
+
const result = await validateDataContract(rawDataContract);
|
|
1126
|
+
|
|
1127
|
+
expectJsonSchemaError(result, 2);
|
|
1128
|
+
|
|
1129
|
+
const [error] = result.getErrors();
|
|
1130
|
+
|
|
1131
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/byteArrayField/byteArray');
|
|
1132
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1133
|
+
expect(error.getParams().type).to.equal('boolean');
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
it('should equal to true', async () => {
|
|
1137
|
+
rawDataContract.documents.withByteArrays.properties.byteArrayField.byteArray = false;
|
|
1138
|
+
|
|
1139
|
+
const result = await validateDataContract(rawDataContract);
|
|
1140
|
+
|
|
1141
|
+
expectJsonSchemaError(result, 2);
|
|
1142
|
+
|
|
1143
|
+
const [error] = result.getErrors();
|
|
1144
|
+
|
|
1145
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/byteArrayField/byteArray');
|
|
1146
|
+
expect(error.getKeyword()).to.equal('const');
|
|
1147
|
+
expect(error.getParams().allowedValue).to.equal(true);
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
it('should be used with type `array`', async () => {
|
|
1151
|
+
rawDataContract.documents.withByteArrays.properties.byteArrayField.type = 'string';
|
|
1152
|
+
|
|
1153
|
+
const result = await validateDataContract(rawDataContract);
|
|
1154
|
+
|
|
1155
|
+
expectJsonSchemaError(result, 2);
|
|
1156
|
+
|
|
1157
|
+
const [error] = result.getErrors();
|
|
1158
|
+
|
|
1159
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/byteArrayField/type');
|
|
1160
|
+
expect(error.getKeyword()).to.equal('const');
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
it('should not be used with `items`', async () => {
|
|
1164
|
+
rawDataContract.documents.withByteArrays.properties.byteArrayField.items = {
|
|
1165
|
+
type: 'string',
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
const result = await validateDataContract(rawDataContract);
|
|
1169
|
+
|
|
1170
|
+
expectValidationError(result, JsonSchemaCompilationError);
|
|
1171
|
+
|
|
1172
|
+
const [error] = result.getErrors();
|
|
1173
|
+
|
|
1174
|
+
expect(error.getCode()).to.equal(1004);
|
|
1175
|
+
expect(error.message).to.equal("'byteArray' should not be used with 'items'");
|
|
1176
|
+
});
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1179
|
+
describe('contentMediaType', () => {
|
|
1180
|
+
describe('application/x.dash.dpp.identifier', () => {
|
|
1181
|
+
it('should be used with byte array only', async () => {
|
|
1182
|
+
delete rawDataContract.documents.withByteArrays.properties.identifierField.byteArray;
|
|
1183
|
+
|
|
1184
|
+
const result = await validateDataContract(rawDataContract);
|
|
1185
|
+
|
|
1186
|
+
expectJsonSchemaError(result, 2);
|
|
1187
|
+
|
|
1188
|
+
const [error] = result.getErrors();
|
|
1189
|
+
|
|
1190
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/identifierField');
|
|
1191
|
+
expect(error.getKeyword()).to.equal('required');
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1194
|
+
it('should be used with byte array not shorter than 32 bytes', async () => {
|
|
1195
|
+
rawDataContract.documents.withByteArrays.properties.identifierField.minItems = 31;
|
|
1196
|
+
|
|
1197
|
+
const result = await validateDataContract(rawDataContract);
|
|
1198
|
+
|
|
1199
|
+
expectJsonSchemaError(result, 2);
|
|
1200
|
+
|
|
1201
|
+
const [error] = result.getErrors();
|
|
1202
|
+
|
|
1203
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/identifierField/minItems');
|
|
1204
|
+
expect(error.getKeyword()).to.equal('const');
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
it('should be used with byte array not longer than 32 bytes', async () => {
|
|
1208
|
+
rawDataContract.documents.withByteArrays.properties.identifierField.maxItems = 31;
|
|
1209
|
+
|
|
1210
|
+
const result = await validateDataContract(rawDataContract);
|
|
1211
|
+
|
|
1212
|
+
expectJsonSchemaError(result, 2);
|
|
1213
|
+
|
|
1214
|
+
const [error] = result.getErrors();
|
|
1215
|
+
|
|
1216
|
+
expect(error.instancePath).to.equal('/documents/withByteArrays/properties/identifierField/maxItems');
|
|
1217
|
+
expect(error.getKeyword()).to.equal('const');
|
|
1218
|
+
});
|
|
1219
|
+
});
|
|
1220
|
+
});
|
|
1221
|
+
});
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
describe('indices', () => {
|
|
1225
|
+
it('should be an array', async () => {
|
|
1226
|
+
rawDataContract.documents.indexedDocument.indices = 'definitely not an array';
|
|
1227
|
+
|
|
1228
|
+
const result = await validateDataContract(rawDataContract);
|
|
1229
|
+
|
|
1230
|
+
expectJsonSchemaError(result);
|
|
1231
|
+
|
|
1232
|
+
const [error] = result.getErrors();
|
|
1233
|
+
|
|
1234
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/indices');
|
|
1235
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1236
|
+
});
|
|
1237
|
+
|
|
1238
|
+
it('should have at least one item', async () => {
|
|
1239
|
+
rawDataContract.documents.indexedDocument.indices = [];
|
|
1240
|
+
|
|
1241
|
+
const result = await validateDataContract(rawDataContract);
|
|
1242
|
+
|
|
1243
|
+
expectJsonSchemaError(result);
|
|
1244
|
+
|
|
1245
|
+
const [error] = result.getErrors();
|
|
1246
|
+
|
|
1247
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/indices');
|
|
1248
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
it('should return invalid result if there are duplicated indices', async () => {
|
|
1252
|
+
const indexDefinition = {
|
|
1253
|
+
...rawDataContract.documents.indexedDocument.indices[0],
|
|
1254
|
+
name: 'otherIndexName',
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
rawDataContract.documents.indexedDocument.indices.push(indexDefinition);
|
|
1258
|
+
|
|
1259
|
+
const result = await validateDataContract(rawDataContract);
|
|
1260
|
+
|
|
1261
|
+
expectValidationError(result, DuplicateIndexError);
|
|
1262
|
+
|
|
1263
|
+
const [error] = result.getErrors();
|
|
1264
|
+
|
|
1265
|
+
expect(error.getCode()).to.equal(1008);
|
|
1266
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1267
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
it('should return invalid result if there are duplicated index names', async () => {
|
|
1271
|
+
const indexDefinition = {
|
|
1272
|
+
...rawDataContract.documents.indexedDocument.indices[0],
|
|
1273
|
+
};
|
|
1274
|
+
|
|
1275
|
+
rawDataContract.documents.indexedDocument.indices.push(indexDefinition);
|
|
1276
|
+
|
|
1277
|
+
const result = await validateDataContract(rawDataContract);
|
|
1278
|
+
|
|
1279
|
+
expect(result.isValid()).to.be.false();
|
|
1280
|
+
|
|
1281
|
+
const [error] = result.getErrors();
|
|
1282
|
+
|
|
1283
|
+
expect(error.getCode()).to.equal(1048);
|
|
1284
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1285
|
+
expect(error.getDuplicateIndexName()).to.deep.equal('index1');
|
|
1286
|
+
});
|
|
1287
|
+
|
|
1288
|
+
describe('index', () => {
|
|
1289
|
+
it('should be an object', async () => {
|
|
1290
|
+
rawDataContract.documents.indexedDocument.indices = ['something else'];
|
|
1291
|
+
|
|
1292
|
+
const result = await validateDataContract(rawDataContract);
|
|
1293
|
+
|
|
1294
|
+
expectJsonSchemaError(result);
|
|
1295
|
+
|
|
1296
|
+
const [error] = result.getErrors();
|
|
1297
|
+
|
|
1298
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/indices/0');
|
|
1299
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
it('should have properties definition', async () => {
|
|
1303
|
+
rawDataContract.documents.indexedDocument.indices = [{}];
|
|
1304
|
+
|
|
1305
|
+
const result = await validateDataContract(rawDataContract);
|
|
1306
|
+
|
|
1307
|
+
expectJsonSchemaError(result);
|
|
1308
|
+
|
|
1309
|
+
const [error] = result.getErrors();
|
|
1310
|
+
|
|
1311
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/indices/0');
|
|
1312
|
+
expect(error.getParams().missingProperty).to.equal('properties');
|
|
1313
|
+
expect(error.getKeyword()).to.equal('required');
|
|
1314
|
+
});
|
|
1315
|
+
|
|
1316
|
+
describe('properties definition', () => {
|
|
1317
|
+
it('should be an array', async () => {
|
|
1318
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1319
|
+
.properties = 'something else';
|
|
1320
|
+
|
|
1321
|
+
const result = await validateDataContract(rawDataContract);
|
|
1322
|
+
|
|
1323
|
+
expectJsonSchemaError(result);
|
|
1324
|
+
|
|
1325
|
+
const [error] = result.getErrors();
|
|
1326
|
+
|
|
1327
|
+
expect(error.instancePath).to.equal(
|
|
1328
|
+
'/documents/indexedDocument/indices/0/properties',
|
|
1329
|
+
);
|
|
1330
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
it('should have at least one property defined', async () => {
|
|
1334
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1335
|
+
.properties = [];
|
|
1336
|
+
|
|
1337
|
+
const result = await validateDataContract(rawDataContract);
|
|
1338
|
+
|
|
1339
|
+
expectJsonSchemaError(result);
|
|
1340
|
+
|
|
1341
|
+
const [error] = result.getErrors();
|
|
1342
|
+
|
|
1343
|
+
expect(error.instancePath).to.equal(
|
|
1344
|
+
'/documents/indexedDocument/indices/0/properties',
|
|
1345
|
+
);
|
|
1346
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1349
|
+
it('should have no more than 10 property $defs', async () => {
|
|
1350
|
+
for (let i = 0; i < 10; i++) {
|
|
1351
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1352
|
+
.properties.push({ [`field${i}`]: 'asc' });
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
const result = await validateDataContract(rawDataContract);
|
|
1356
|
+
|
|
1357
|
+
expectJsonSchemaError(result);
|
|
1358
|
+
|
|
1359
|
+
const [error] = result.getErrors();
|
|
1360
|
+
|
|
1361
|
+
expect(error.instancePath).to.equal(
|
|
1362
|
+
'/documents/indexedDocument/indices/0/properties',
|
|
1363
|
+
);
|
|
1364
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
describe('property definition', () => {
|
|
1368
|
+
it('should be an object', async () => {
|
|
1369
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1370
|
+
.properties[0] = 'something else';
|
|
1371
|
+
|
|
1372
|
+
const result = await validateDataContract(rawDataContract);
|
|
1373
|
+
|
|
1374
|
+
expectJsonSchemaError(result);
|
|
1375
|
+
|
|
1376
|
+
const [error] = result.getErrors();
|
|
1377
|
+
|
|
1378
|
+
expect(error.instancePath).to.equal(
|
|
1379
|
+
'/documents/indexedDocument/indices/0/properties/0',
|
|
1380
|
+
);
|
|
1381
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1382
|
+
});
|
|
1383
|
+
|
|
1384
|
+
it('should have at least one property', async () => {
|
|
1385
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1386
|
+
.properties = [];
|
|
1387
|
+
|
|
1388
|
+
const result = await validateDataContract(rawDataContract);
|
|
1389
|
+
|
|
1390
|
+
expectJsonSchemaError(result);
|
|
1391
|
+
|
|
1392
|
+
const [error] = result.getErrors();
|
|
1393
|
+
|
|
1394
|
+
expect(error.instancePath).to.equal(
|
|
1395
|
+
'/documents/indexedDocument/indices/0/properties',
|
|
1396
|
+
);
|
|
1397
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
1398
|
+
});
|
|
1399
|
+
|
|
1400
|
+
it('should have no more than one property', async () => {
|
|
1401
|
+
const property = rawDataContract.documents.indexedDocument.indices[0]
|
|
1402
|
+
.properties[0];
|
|
1403
|
+
|
|
1404
|
+
property.anotherField = 'something';
|
|
1405
|
+
|
|
1406
|
+
const result = await validateDataContract(rawDataContract);
|
|
1407
|
+
|
|
1408
|
+
expectJsonSchemaError(result);
|
|
1409
|
+
|
|
1410
|
+
const [error] = result.getErrors();
|
|
1411
|
+
|
|
1412
|
+
expect(error.instancePath).to.equal(
|
|
1413
|
+
'/documents/indexedDocument/indices/0/properties/0',
|
|
1414
|
+
);
|
|
1415
|
+
expect(error.getKeyword()).to.equal('maxProperties');
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
it('should have property values only "asc" or "desc"', async () => {
|
|
1419
|
+
rawDataContract.documents.indexedDocument.indices[0]
|
|
1420
|
+
.properties[0].$ownerId = 'wrong';
|
|
1421
|
+
|
|
1422
|
+
const result = await validateDataContract(rawDataContract);
|
|
1423
|
+
|
|
1424
|
+
expectJsonSchemaError(result);
|
|
1425
|
+
|
|
1426
|
+
const [error] = result.getErrors();
|
|
1427
|
+
|
|
1428
|
+
expect(error.instancePath).to.equal(
|
|
1429
|
+
'/documents/indexedDocument/indices/0/properties/0/$ownerId',
|
|
1430
|
+
);
|
|
1431
|
+
expect(error.getKeyword()).to.equal('enum');
|
|
1432
|
+
});
|
|
1433
|
+
});
|
|
1434
|
+
});
|
|
1435
|
+
|
|
1436
|
+
describe('property names', () => {
|
|
1437
|
+
it('should have valid property names (indices)', async () => {
|
|
1438
|
+
const validNames = ['validName', 'valid_name', 'valid-name', 'abc', 'a123123bc', 'ab123c', 'ValidName', 'validName',
|
|
1439
|
+
'abcdefghigklmnopqrstuvwxyz01234567890abcdefghigklmnopqrstuvwxyz', 'abc_gbf_gdb', 'abc-gbf-gdb'];
|
|
1440
|
+
|
|
1441
|
+
await Promise.all(
|
|
1442
|
+
validNames.map(async (name) => {
|
|
1443
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
1444
|
+
|
|
1445
|
+
clonedDataContract.documents.indexedDocument.properties[name] = { type: 'string', maxLength: 63 };
|
|
1446
|
+
clonedDataContract.documents.indexedDocument.indices[0].properties.push({ [name]: 'asc' });
|
|
1447
|
+
clonedDataContract.documents.indexedDocument.required.push(name);
|
|
1448
|
+
|
|
1449
|
+
const result = await validateDataContract(clonedDataContract);
|
|
1450
|
+
|
|
1451
|
+
expectJsonSchemaError(result, 0);
|
|
1452
|
+
}),
|
|
1453
|
+
);
|
|
1454
|
+
});
|
|
1455
|
+
|
|
1456
|
+
it('should return an invalid result if a property (indices) has invalid format', async () => {
|
|
1457
|
+
const invalidNames = ['a.', '.a'];
|
|
1458
|
+
|
|
1459
|
+
rawDataContract.documents.indexedDocument = {
|
|
1460
|
+
type: 'object',
|
|
1461
|
+
properties: {
|
|
1462
|
+
a: {
|
|
1463
|
+
type: 'object',
|
|
1464
|
+
properties: {
|
|
1465
|
+
property: {
|
|
1466
|
+
type: 'string',
|
|
1467
|
+
maxLength: 63,
|
|
1468
|
+
},
|
|
1469
|
+
},
|
|
1470
|
+
additionalProperties: false,
|
|
1471
|
+
},
|
|
1472
|
+
},
|
|
1473
|
+
indices: [
|
|
1474
|
+
{
|
|
1475
|
+
name: 'index1',
|
|
1476
|
+
properties: [],
|
|
1477
|
+
unique: true,
|
|
1478
|
+
},
|
|
1479
|
+
],
|
|
1480
|
+
additionalProperties: false,
|
|
1481
|
+
};
|
|
1482
|
+
|
|
1483
|
+
await Promise.all(
|
|
1484
|
+
invalidNames.map(async (name) => {
|
|
1485
|
+
const clonedDataContract = lodashCloneDeep(rawDataContract);
|
|
1486
|
+
|
|
1487
|
+
clonedDataContract.documents.indexedDocument.indices[0].properties.push({ [name]: 'asc' });
|
|
1488
|
+
|
|
1489
|
+
const result = await validateDataContract(clonedDataContract);
|
|
1490
|
+
|
|
1491
|
+
expectValidationError(result, UndefinedIndexPropertyError, 1);
|
|
1492
|
+
}),
|
|
1493
|
+
);
|
|
1494
|
+
});
|
|
1495
|
+
});
|
|
1496
|
+
|
|
1497
|
+
it('should have "unique" flag to be of a boolean type', async () => {
|
|
1498
|
+
rawDataContract.documents.indexedDocument.indices[0].unique = 12;
|
|
1499
|
+
|
|
1500
|
+
const result = await validateDataContract(rawDataContract);
|
|
1501
|
+
|
|
1502
|
+
expectJsonSchemaError(result);
|
|
1503
|
+
|
|
1504
|
+
const [error] = result.getErrors();
|
|
1505
|
+
|
|
1506
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/indices/0/unique');
|
|
1507
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
it('should have no more than 10 indices', async () => {
|
|
1511
|
+
for (let i = 0; i < 10; i++) {
|
|
1512
|
+
const propertyName = `field${i}`;
|
|
1513
|
+
|
|
1514
|
+
rawDataContract.documents.indexedDocument.properties[propertyName] = { type: 'string' };
|
|
1515
|
+
|
|
1516
|
+
rawDataContract.documents.indexedDocument.indices.push({
|
|
1517
|
+
properties: [{ [propertyName]: 'asc' }],
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
const result = await validateDataContract(rawDataContract);
|
|
1522
|
+
|
|
1523
|
+
expectJsonSchemaError(result);
|
|
1524
|
+
|
|
1525
|
+
const [error] = result.getErrors();
|
|
1526
|
+
|
|
1527
|
+
expect(error.instancePath).to.equal(
|
|
1528
|
+
'/documents/indexedDocument/indices',
|
|
1529
|
+
);
|
|
1530
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
1531
|
+
});
|
|
1532
|
+
|
|
1533
|
+
it('should have no more than 3 unique indices', async () => {
|
|
1534
|
+
for (let i = 0; i < 4; i++) {
|
|
1535
|
+
const propertyName = `field${i}`;
|
|
1536
|
+
|
|
1537
|
+
rawDataContract.documents.indexedDocument.properties[propertyName] = {
|
|
1538
|
+
type: 'string',
|
|
1539
|
+
maxLength: 63,
|
|
1540
|
+
};
|
|
1541
|
+
|
|
1542
|
+
rawDataContract.documents.indexedDocument.indices.push({
|
|
1543
|
+
name: `index_${i}`,
|
|
1544
|
+
properties: [{ [propertyName]: 'asc' }],
|
|
1545
|
+
unique: true,
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
const result = await validateDataContract(rawDataContract);
|
|
1550
|
+
|
|
1551
|
+
expectValidationError(result, UniqueIndicesLimitReachedError);
|
|
1552
|
+
|
|
1553
|
+
const [error] = result.getErrors();
|
|
1554
|
+
|
|
1555
|
+
expect(error.getCode()).to.equal(1017);
|
|
1556
|
+
expect(error.getDocumentType()).to.equal('indexedDocument');
|
|
1557
|
+
});
|
|
1558
|
+
|
|
1559
|
+
it('should return invalid result if $id is specified as an indexed property', async () => {
|
|
1560
|
+
const indexDefinition = {
|
|
1561
|
+
name: 'index_1',
|
|
1562
|
+
properties: [
|
|
1563
|
+
{ $id: 'asc' },
|
|
1564
|
+
{ firstName: 'asc' },
|
|
1565
|
+
],
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
const indeciesDefinition = rawDataContract.documents.indexedDocument.indices;
|
|
1569
|
+
|
|
1570
|
+
indeciesDefinition.push(indexDefinition);
|
|
1571
|
+
|
|
1572
|
+
const result = await validateDataContract(rawDataContract);
|
|
1573
|
+
|
|
1574
|
+
expectValidationError(result, SystemPropertyIndexAlreadyPresentError);
|
|
1575
|
+
|
|
1576
|
+
const [error] = result.getErrors();
|
|
1577
|
+
|
|
1578
|
+
expect(error.getCode()).to.equal(1015);
|
|
1579
|
+
expect(error.getPropertyName()).to.equal('$id');
|
|
1580
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1581
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1582
|
+
});
|
|
1583
|
+
|
|
1584
|
+
it('should return invalid result if indices has undefined property', async () => {
|
|
1585
|
+
const indexDefinition = rawDataContract.documents.indexedDocument.indices[0];
|
|
1586
|
+
|
|
1587
|
+
indexDefinition.properties.push({
|
|
1588
|
+
missingProperty: 'asc',
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
const result = await validateDataContract(rawDataContract);
|
|
1592
|
+
|
|
1593
|
+
expectValidationError(result, UndefinedIndexPropertyError);
|
|
1594
|
+
|
|
1595
|
+
const [error] = result.getErrors();
|
|
1596
|
+
|
|
1597
|
+
expect(error.getCode()).to.equal(1016);
|
|
1598
|
+
expect(error.getPropertyName()).to.equal('missingProperty');
|
|
1599
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1600
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1601
|
+
});
|
|
1602
|
+
|
|
1603
|
+
it('should return invalid result if index property is object', async () => {
|
|
1604
|
+
const indexedDocumentDefinition = rawDataContract.documents.indexedDocument;
|
|
1605
|
+
|
|
1606
|
+
indexedDocumentDefinition.properties.objectProperty = {
|
|
1607
|
+
type: 'object',
|
|
1608
|
+
properties: {
|
|
1609
|
+
something: {
|
|
1610
|
+
type: 'string',
|
|
1611
|
+
},
|
|
1612
|
+
},
|
|
1613
|
+
additionalProperties: false,
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
indexedDocumentDefinition.required.push('objectProperty');
|
|
1617
|
+
|
|
1618
|
+
const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1619
|
+
|
|
1620
|
+
indexDefinition.properties.push({
|
|
1621
|
+
objectProperty: 'asc',
|
|
1622
|
+
});
|
|
1623
|
+
|
|
1624
|
+
const result = await validateDataContract(rawDataContract);
|
|
1625
|
+
|
|
1626
|
+
expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1627
|
+
|
|
1628
|
+
const [error] = result.getErrors();
|
|
1629
|
+
|
|
1630
|
+
expect(error.getCode()).to.equal(1013);
|
|
1631
|
+
expect(error.getPropertyName()).to.equal('objectProperty');
|
|
1632
|
+
expect(error.getPropertyType()).to.equal('object');
|
|
1633
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1634
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1635
|
+
});
|
|
1636
|
+
|
|
1637
|
+
it('should return invalid result if index property is an array', async () => {
|
|
1638
|
+
rawDataContract.documents.indexedArray = {
|
|
1639
|
+
type: 'object',
|
|
1640
|
+
indices: [
|
|
1641
|
+
{
|
|
1642
|
+
name: 'index1',
|
|
1643
|
+
properties: [
|
|
1644
|
+
{ mentions: 'asc' },
|
|
1645
|
+
],
|
|
1646
|
+
},
|
|
1647
|
+
],
|
|
1648
|
+
properties: {
|
|
1649
|
+
mentions: {
|
|
1650
|
+
type: 'array',
|
|
1651
|
+
prefixItems: [
|
|
1652
|
+
{
|
|
1653
|
+
type: 'string',
|
|
1654
|
+
maxLength: 100,
|
|
1655
|
+
},
|
|
1656
|
+
],
|
|
1657
|
+
minItems: 1,
|
|
1658
|
+
maxItems: 5,
|
|
1659
|
+
items: false,
|
|
1660
|
+
},
|
|
1661
|
+
},
|
|
1662
|
+
additionalProperties: false,
|
|
1663
|
+
};
|
|
1664
|
+
|
|
1665
|
+
const indexDefinition = rawDataContract.documents.indexedArray.indices[0];
|
|
1666
|
+
|
|
1667
|
+
const result = await validateDataContract(rawDataContract);
|
|
1668
|
+
|
|
1669
|
+
expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1670
|
+
|
|
1671
|
+
const [error] = result.getErrors();
|
|
1672
|
+
|
|
1673
|
+
expect(error.getCode()).to.equal(1013);
|
|
1674
|
+
expect(error.getPropertyName()).to.equal('mentions');
|
|
1675
|
+
expect(error.getPropertyType()).to.equal('array');
|
|
1676
|
+
expect(error.getDocumentType()).to.deep.equal('indexedArray');
|
|
1677
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1678
|
+
});
|
|
1679
|
+
|
|
1680
|
+
// it('should return invalid result if index property is array of objects', async () => {
|
|
1681
|
+
// const indexedDocumentDefinition = rawDataContract.documents.indexedDocument;
|
|
1682
|
+
//
|
|
1683
|
+
// indexedDocumentDefinition.properties.arrayProperty = {
|
|
1684
|
+
// type: 'array',
|
|
1685
|
+
// items: {
|
|
1686
|
+
// type: 'object',
|
|
1687
|
+
// properties: {
|
|
1688
|
+
// something: {
|
|
1689
|
+
// type: 'string',
|
|
1690
|
+
// },
|
|
1691
|
+
// },
|
|
1692
|
+
// additionalProperties: false,
|
|
1693
|
+
// },
|
|
1694
|
+
// };
|
|
1695
|
+
//
|
|
1696
|
+
// indexedDocumentDefinition.required.push('arrayProperty');
|
|
1697
|
+
//
|
|
1698
|
+
// const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1699
|
+
//
|
|
1700
|
+
// indexDefinition.properties.push({
|
|
1701
|
+
// arrayProperty: 'asc',
|
|
1702
|
+
// });
|
|
1703
|
+
//
|
|
1704
|
+
// const result = await validateDataContract(rawDataContract);
|
|
1705
|
+
//
|
|
1706
|
+
// expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1707
|
+
//
|
|
1708
|
+
// const [error] = result.getErrors();
|
|
1709
|
+
//
|
|
1710
|
+
// expect(error.getCode()).to.equal(1013);
|
|
1711
|
+
// expect(error.getPropertyName()).to.equal('arrayProperty');
|
|
1712
|
+
// expect(error.getPropertyType()).to.equal('array');
|
|
1713
|
+
// expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1714
|
+
// expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1715
|
+
// });
|
|
1716
|
+
|
|
1717
|
+
// it('should return invalid result if index property is an array of different types',
|
|
1718
|
+
// async () => {
|
|
1719
|
+
// const indexedDocumentDefinition = rawDataContract.documents.indexedArray;
|
|
1720
|
+
//
|
|
1721
|
+
// const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1722
|
+
//
|
|
1723
|
+
// rawDataContract.documents.indexedArray.properties.mentions.prefixItems = [
|
|
1724
|
+
// {
|
|
1725
|
+
// type: 'string',
|
|
1726
|
+
// },
|
|
1727
|
+
// {
|
|
1728
|
+
// type: 'number',
|
|
1729
|
+
// },
|
|
1730
|
+
// ];
|
|
1731
|
+
//
|
|
1732
|
+
// rawDataContract.documents.indexedArray.properties.mentions.minItems = 2;
|
|
1733
|
+
//
|
|
1734
|
+
// const result = await validateDataContract(rawDataContract);
|
|
1735
|
+
// expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1736
|
+
//
|
|
1737
|
+
// const error = result.getFirstError();
|
|
1738
|
+
//
|
|
1739
|
+
// expect(error.getCode()).to.equal(1013);
|
|
1740
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
1741
|
+
// expect(error.getPropertyType()).to.equal('array');
|
|
1742
|
+
// expect(error.getDocumentType()).to.deep.equal('indexedArray');
|
|
1743
|
+
// expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1744
|
+
// });
|
|
1745
|
+
//
|
|
1746
|
+
// it('should return invalid result if index property contained prefixItems array of arrays',
|
|
1747
|
+
// async () => {
|
|
1748
|
+
// const indexedDocumentDefinition = rawDataContract.documents.indexedArray;
|
|
1749
|
+
//
|
|
1750
|
+
// const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1751
|
+
//
|
|
1752
|
+
// rawDataContract.documents.indexedArray.properties.mentions.prefixItems = [
|
|
1753
|
+
// {
|
|
1754
|
+
// type: 'array',
|
|
1755
|
+
// items: {
|
|
1756
|
+
// type: 'string',
|
|
1757
|
+
// },
|
|
1758
|
+
// },
|
|
1759
|
+
// ];
|
|
1760
|
+
//
|
|
1761
|
+
// const result = await validateDataContract(rawDataContract);
|
|
1762
|
+
// expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1763
|
+
//
|
|
1764
|
+
// const error = result.getFirstError();
|
|
1765
|
+
//
|
|
1766
|
+
// expect(error.getCode()).to.equal(1013);
|
|
1767
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
1768
|
+
// expect(error.getPropertyType()).to.equal('array');
|
|
1769
|
+
// expect(error.getDocumentType()).to.deep.equal('indexedArray');
|
|
1770
|
+
// expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1771
|
+
// });
|
|
1772
|
+
|
|
1773
|
+
// it('should return invalid result if index property contained prefixItems array of objects',
|
|
1774
|
+
// async () => {
|
|
1775
|
+
// const indexedDocumentDefinition = rawDataContract.documents.indexedArray;
|
|
1776
|
+
//
|
|
1777
|
+
// const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1778
|
+
//
|
|
1779
|
+
// rawDataContract.documents.indexedArray.properties.mentions.prefixItems = [
|
|
1780
|
+
// {
|
|
1781
|
+
// type: 'object',
|
|
1782
|
+
// properties: {
|
|
1783
|
+
// something: {
|
|
1784
|
+
// type: 'string',
|
|
1785
|
+
// },
|
|
1786
|
+
// },
|
|
1787
|
+
// additionalProperties: false,
|
|
1788
|
+
// },
|
|
1789
|
+
// ];
|
|
1790
|
+
//
|
|
1791
|
+
// const result = await validateDataContract(rawDataContract);
|
|
1792
|
+
// expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1793
|
+
//
|
|
1794
|
+
// const error = result.getFirstError();
|
|
1795
|
+
//
|
|
1796
|
+
// expect(error.getCode()).to.equal(1013);
|
|
1797
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
1798
|
+
// expect(error.getPropertyType()).to.equal('array');
|
|
1799
|
+
// expect(error.getDocumentType()).to.deep.equal('indexedArray');
|
|
1800
|
+
// expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1801
|
+
// });
|
|
1802
|
+
//
|
|
1803
|
+
// it('should return invalid result if index property is array of arrays', async () => {
|
|
1804
|
+
// const indexedDocumentDefinition = rawDataContract.documents.indexedDocument;
|
|
1805
|
+
//
|
|
1806
|
+
// indexedDocumentDefinition.properties.arrayProperty = {
|
|
1807
|
+
// type: 'array',
|
|
1808
|
+
// items: {
|
|
1809
|
+
// type: 'array',
|
|
1810
|
+
// items: {
|
|
1811
|
+
// type: 'string',
|
|
1812
|
+
// },
|
|
1813
|
+
// },
|
|
1814
|
+
// };
|
|
1815
|
+
//
|
|
1816
|
+
// indexedDocumentDefinition.required.push('arrayProperty');
|
|
1817
|
+
//
|
|
1818
|
+
// const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1819
|
+
//
|
|
1820
|
+
// indexDefinition.properties.push({
|
|
1821
|
+
// arrayProperty: 'asc',
|
|
1822
|
+
// });
|
|
1823
|
+
//
|
|
1824
|
+
// const result = await validateDataContract(rawDataContract);
|
|
1825
|
+
//
|
|
1826
|
+
// expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1827
|
+
//
|
|
1828
|
+
// const [error] = result.getErrors();
|
|
1829
|
+
//
|
|
1830
|
+
// expect(error.getCode()).to.equal(1013);
|
|
1831
|
+
// expect(error.getPropertyName()).to.equal('arrayProperty');
|
|
1832
|
+
// expect(error.getPropertyType()).to.equal('array');
|
|
1833
|
+
// expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1834
|
+
// expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1835
|
+
// });
|
|
1836
|
+
|
|
1837
|
+
it('should return invalid result if index property is array with different item definitions', async () => {
|
|
1838
|
+
const indexedDocumentDefinition = rawDataContract.documents.indexedDocument;
|
|
1839
|
+
|
|
1840
|
+
indexedDocumentDefinition.properties.arrayProperty = {
|
|
1841
|
+
type: 'array',
|
|
1842
|
+
prefixItems: [
|
|
1843
|
+
{
|
|
1844
|
+
type: 'string',
|
|
1845
|
+
},
|
|
1846
|
+
{
|
|
1847
|
+
type: 'number',
|
|
1848
|
+
},
|
|
1849
|
+
],
|
|
1850
|
+
minItems: 2,
|
|
1851
|
+
items: false,
|
|
1852
|
+
};
|
|
1853
|
+
|
|
1854
|
+
indexedDocumentDefinition.required.push('arrayProperty');
|
|
1855
|
+
|
|
1856
|
+
const indexDefinition = indexedDocumentDefinition.indices[0];
|
|
1857
|
+
|
|
1858
|
+
indexDefinition.properties.push({
|
|
1859
|
+
arrayProperty: 'asc',
|
|
1860
|
+
});
|
|
1861
|
+
|
|
1862
|
+
const result = await validateDataContract(rawDataContract);
|
|
1863
|
+
|
|
1864
|
+
expectValidationError(result, InvalidIndexPropertyTypeError);
|
|
1865
|
+
|
|
1866
|
+
const [error] = result.getErrors();
|
|
1867
|
+
|
|
1868
|
+
expect(error.getCode()).to.equal(1013);
|
|
1869
|
+
expect(error.getPropertyName()).to.equal('arrayProperty');
|
|
1870
|
+
expect(error.getPropertyType()).to.equal('array');
|
|
1871
|
+
expect(error.getDocumentType()).to.deep.equal('indexedDocument');
|
|
1872
|
+
expect(error.getIndexDefinition()).to.deep.equal(indexDefinition);
|
|
1873
|
+
});
|
|
1874
|
+
|
|
1875
|
+
it('should return invalid result if unique compound index contains both required and optional properties', async () => {
|
|
1876
|
+
rawDataContract.documents.optionalUniqueIndexedDocument.required.splice(-1);
|
|
1877
|
+
|
|
1878
|
+
const result = await validateDataContract(rawDataContract);
|
|
1879
|
+
|
|
1880
|
+
expectValidationError(result, InvalidCompoundIndexError);
|
|
1881
|
+
|
|
1882
|
+
const [error] = result.getErrors();
|
|
1883
|
+
|
|
1884
|
+
expect(error.getCode()).to.equal(1010);
|
|
1885
|
+
expect(error.getIndexDefinition()).to.deep.equal(
|
|
1886
|
+
rawDataContract.documents.optionalUniqueIndexedDocument.indices[1],
|
|
1887
|
+
);
|
|
1888
|
+
expect(error.getDocumentType()).to.equal('optionalUniqueIndexedDocument');
|
|
1889
|
+
});
|
|
1890
|
+
});
|
|
1891
|
+
});
|
|
1892
|
+
|
|
1893
|
+
describe('signatureSecurityLevelRequirement', () => {
|
|
1894
|
+
it('should be a number', async () => {
|
|
1895
|
+
rawDataContract.documents.indexedDocument.signatureSecurityLevelRequirement = 'definitely not a number';
|
|
1896
|
+
|
|
1897
|
+
const result = await validateDataContract(rawDataContract);
|
|
1898
|
+
|
|
1899
|
+
expectJsonSchemaError(result);
|
|
1900
|
+
|
|
1901
|
+
const [error] = result.getErrors();
|
|
1902
|
+
|
|
1903
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/signatureSecurityLevelRequirement');
|
|
1904
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1905
|
+
});
|
|
1906
|
+
|
|
1907
|
+
it('should be one of the available values', async () => {
|
|
1908
|
+
rawDataContract.documents.indexedDocument.signatureSecurityLevelRequirement = 199;
|
|
1909
|
+
|
|
1910
|
+
const result = await validateDataContract(rawDataContract);
|
|
1911
|
+
|
|
1912
|
+
expectJsonSchemaError(result);
|
|
1913
|
+
|
|
1914
|
+
const [error] = result.getErrors();
|
|
1915
|
+
|
|
1916
|
+
expect(error.instancePath).to.equal('/documents/indexedDocument/signatureSecurityLevelRequirement');
|
|
1917
|
+
expect(error.getKeyword()).to.equal('enum');
|
|
1918
|
+
});
|
|
1919
|
+
});
|
|
1920
|
+
|
|
1921
|
+
describe('dependentSchemas', () => {
|
|
1922
|
+
it('should be an object', async () => {
|
|
1923
|
+
rawDataContract.documents.niceDocument = {
|
|
1924
|
+
type: 'object',
|
|
1925
|
+
properties: {
|
|
1926
|
+
abc: {
|
|
1927
|
+
type: 'string',
|
|
1928
|
+
},
|
|
1929
|
+
},
|
|
1930
|
+
additionalProperties: false,
|
|
1931
|
+
dependentSchemas: 'string',
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
const result = await validateDataContract(rawDataContract);
|
|
1935
|
+
|
|
1936
|
+
expectJsonSchemaError(result);
|
|
1937
|
+
|
|
1938
|
+
const [error] = result.getErrors();
|
|
1939
|
+
|
|
1940
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1941
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/dependentSchemas');
|
|
1942
|
+
expect(error.message).to.equal('must be object');
|
|
1943
|
+
});
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
describe('dependentRequired', () => {
|
|
1947
|
+
it('should be an object', async () => {
|
|
1948
|
+
rawDataContract.documents.niceDocument = {
|
|
1949
|
+
type: 'object',
|
|
1950
|
+
properties: {
|
|
1951
|
+
abc: {
|
|
1952
|
+
type: 'string',
|
|
1953
|
+
},
|
|
1954
|
+
},
|
|
1955
|
+
additionalProperties: false,
|
|
1956
|
+
dependentRequired: 'string',
|
|
1957
|
+
};
|
|
1958
|
+
|
|
1959
|
+
const result = await validateDataContract(rawDataContract);
|
|
1960
|
+
|
|
1961
|
+
expectJsonSchemaError(result);
|
|
1962
|
+
|
|
1963
|
+
const [error] = result.getErrors();
|
|
1964
|
+
|
|
1965
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1966
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/dependentRequired');
|
|
1967
|
+
expect(error.message).to.equal('must be object');
|
|
1968
|
+
});
|
|
1969
|
+
|
|
1970
|
+
it('should have an array value', async () => {
|
|
1971
|
+
rawDataContract.documents.niceDocument = {
|
|
1972
|
+
type: 'object',
|
|
1973
|
+
properties: {
|
|
1974
|
+
abc: {
|
|
1975
|
+
type: 'string',
|
|
1976
|
+
},
|
|
1977
|
+
},
|
|
1978
|
+
additionalProperties: false,
|
|
1979
|
+
dependentRequired: {
|
|
1980
|
+
zxy: {
|
|
1981
|
+
type: 'number',
|
|
1982
|
+
},
|
|
1983
|
+
},
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
const result = await validateDataContract(rawDataContract);
|
|
1987
|
+
|
|
1988
|
+
expectJsonSchemaError(result);
|
|
1989
|
+
|
|
1990
|
+
const [error] = result.getErrors();
|
|
1991
|
+
|
|
1992
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1993
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/dependentRequired/zxy');
|
|
1994
|
+
expect(error.message).to.equal('must be array');
|
|
1995
|
+
});
|
|
1996
|
+
|
|
1997
|
+
it('should have an array of strings', async () => {
|
|
1998
|
+
rawDataContract.documents.niceDocument = {
|
|
1999
|
+
type: 'object',
|
|
2000
|
+
properties: {
|
|
2001
|
+
abc: {
|
|
2002
|
+
type: 'string',
|
|
2003
|
+
},
|
|
2004
|
+
},
|
|
2005
|
+
additionalProperties: false,
|
|
2006
|
+
dependentRequired: {
|
|
2007
|
+
zxy: [1, '2'],
|
|
2008
|
+
},
|
|
2009
|
+
};
|
|
2010
|
+
|
|
2011
|
+
const result = await validateDataContract(rawDataContract);
|
|
2012
|
+
|
|
2013
|
+
expectJsonSchemaError(result);
|
|
2014
|
+
|
|
2015
|
+
const [error] = result.getErrors();
|
|
2016
|
+
|
|
2017
|
+
expect(error.getKeyword()).to.equal('type');
|
|
2018
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/dependentRequired/zxy/0');
|
|
2019
|
+
expect(error.message).to.equal('must be string');
|
|
2020
|
+
});
|
|
2021
|
+
|
|
2022
|
+
it('should have an array of unique strings', async () => {
|
|
2023
|
+
rawDataContract.documents.niceDocument = {
|
|
2024
|
+
type: 'object',
|
|
2025
|
+
properties: {
|
|
2026
|
+
abc: {
|
|
2027
|
+
type: 'string',
|
|
2028
|
+
},
|
|
2029
|
+
},
|
|
2030
|
+
additionalProperties: false,
|
|
2031
|
+
dependentRequired: {
|
|
2032
|
+
zxy: ['1', '2', '2'],
|
|
2033
|
+
},
|
|
2034
|
+
};
|
|
2035
|
+
|
|
2036
|
+
const result = await validateDataContract(rawDataContract);
|
|
2037
|
+
|
|
2038
|
+
expectJsonSchemaError(result);
|
|
2039
|
+
|
|
2040
|
+
const [error] = result.getErrors();
|
|
2041
|
+
|
|
2042
|
+
expect(error.getKeyword()).to.equal('uniqueItems');
|
|
2043
|
+
expect(error.instancePath).to.equal('/documents/niceDocument/dependentRequired/zxy');
|
|
2044
|
+
expect(error.message).to.equal('must NOT have duplicate items (items ## 2 and 1 are identical)');
|
|
2045
|
+
});
|
|
2046
|
+
});
|
|
2047
|
+
|
|
2048
|
+
it.skip('should return invalid result with circular $ref pointer', async () => {
|
|
2049
|
+
rawDataContract.$defs.object = { $ref: '#/$defs/object' };
|
|
2050
|
+
|
|
2051
|
+
const result = await validateDataContract(rawDataContract);
|
|
2052
|
+
|
|
2053
|
+
expectValidationError(result, InvalidJsonSchemaRefError);
|
|
2054
|
+
|
|
2055
|
+
const [error] = result.getErrors();
|
|
2056
|
+
|
|
2057
|
+
expect(error.getCode()).to.equal(1014);
|
|
2058
|
+
|
|
2059
|
+
expect(error.message).to.startsWith('Invalid JSON Schema $ref: Circular $ref pointer found');
|
|
2060
|
+
});
|
|
2061
|
+
|
|
2062
|
+
it('should return invalid result if indexed string property missing maxLength constraint', async () => {
|
|
2063
|
+
delete rawDataContract.documents.indexedDocument.properties.firstName.maxLength;
|
|
2064
|
+
|
|
2065
|
+
const result = await validateDataContract(rawDataContract);
|
|
2066
|
+
|
|
2067
|
+
expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2068
|
+
|
|
2069
|
+
const [error] = result.getErrors();
|
|
2070
|
+
|
|
2071
|
+
expect(error.getCode()).to.equal(1012);
|
|
2072
|
+
expect(error.getPropertyName()).to.equal('firstName');
|
|
2073
|
+
expect(error.getConstraintName()).to.equal('maxLength');
|
|
2074
|
+
expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2075
|
+
});
|
|
2076
|
+
|
|
2077
|
+
it('should return invalid result if indexed string property have to big maxLength', async () => {
|
|
2078
|
+
rawDataContract.documents.indexedDocument.properties.firstName.maxLength = 2048;
|
|
2079
|
+
|
|
2080
|
+
const result = await validateDataContract(rawDataContract);
|
|
2081
|
+
|
|
2082
|
+
expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2083
|
+
|
|
2084
|
+
const [error] = result.getErrors();
|
|
2085
|
+
|
|
2086
|
+
expect(error.getCode()).to.equal(1012);
|
|
2087
|
+
expect(error.getPropertyName()).to.equal('firstName');
|
|
2088
|
+
expect(error.getConstraintName()).to.equal('maxLength');
|
|
2089
|
+
expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2090
|
+
});
|
|
2091
|
+
|
|
2092
|
+
// it('should return invalid result if indexed array property missing maxItems constraint',
|
|
2093
|
+
// async () => {
|
|
2094
|
+
// delete rawDataContract.documents.indexedArray.properties.mentions.maxItems;
|
|
2095
|
+
//
|
|
2096
|
+
// const result = await validateDataContract(rawDataContract);
|
|
2097
|
+
//
|
|
2098
|
+
// expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2099
|
+
//
|
|
2100
|
+
// const [error] = result.getErrors();
|
|
2101
|
+
//
|
|
2102
|
+
// expect(error.getCode()).to.equal(1012);
|
|
2103
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
2104
|
+
// expect(error.getConstraintName()).to.equal('maxItems');
|
|
2105
|
+
// expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2106
|
+
// });
|
|
2107
|
+
//
|
|
2108
|
+
// it('should return invalid result if indexed array property have to big maxItems', async () => {
|
|
2109
|
+
// rawDataContract.documents.indexedArray.properties.mentions.maxItems = 2048;
|
|
2110
|
+
//
|
|
2111
|
+
// const result = await validateDataContract(rawDataContract);
|
|
2112
|
+
//
|
|
2113
|
+
// expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2114
|
+
//
|
|
2115
|
+
// const [error] = result.getErrors();
|
|
2116
|
+
//
|
|
2117
|
+
// expect(error.getCode()).to.equal(1012);
|
|
2118
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
2119
|
+
// expect(error.getConstraintName()).to.equal('maxItems');
|
|
2120
|
+
// expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2121
|
+
// });
|
|
2122
|
+
//
|
|
2123
|
+
// it('should return invalid result if indexed array property
|
|
2124
|
+
// have string item without maxItems constraint', async () => {
|
|
2125
|
+
// delete rawDataContract.documents.indexedArray.properties.mentions.maxItems;
|
|
2126
|
+
//
|
|
2127
|
+
// const result = await validateDataContract(rawDataContract);
|
|
2128
|
+
//
|
|
2129
|
+
// expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2130
|
+
//
|
|
2131
|
+
// const [error] = result.getErrors();
|
|
2132
|
+
//
|
|
2133
|
+
// expect(error.getCode()).to.equal(1012);
|
|
2134
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
2135
|
+
// expect(error.getConstraintName()).to.equal('maxItems');
|
|
2136
|
+
// expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2137
|
+
// });
|
|
2138
|
+
//
|
|
2139
|
+
// it('should return invalid result if indexed array property have
|
|
2140
|
+
// string item with maxItems bigger than 1024', async () => {
|
|
2141
|
+
// rawDataContract.documents.indexedArray.properties.mentions.maxItems = 2048;
|
|
2142
|
+
//
|
|
2143
|
+
// const result = await validateDataContract(rawDataContract);
|
|
2144
|
+
//
|
|
2145
|
+
// expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2146
|
+
//
|
|
2147
|
+
// const [error] = result.getErrors();
|
|
2148
|
+
//
|
|
2149
|
+
// expect(error.getCode()).to.equal(1012);
|
|
2150
|
+
// expect(error.getPropertyName()).to.equal('mentions');
|
|
2151
|
+
// expect(error.getConstraintName()).to.equal('maxItems');
|
|
2152
|
+
// expect(error.getReason()).to.equal('should be less or equal 63');
|
|
2153
|
+
// });
|
|
2154
|
+
|
|
2155
|
+
it('should return invalid result if indexed byte array property missing maxItems constraint', async () => {
|
|
2156
|
+
delete rawDataContract.documents.withByteArrays.properties.byteArrayField.maxItems;
|
|
2157
|
+
|
|
2158
|
+
const result = await validateDataContract(rawDataContract);
|
|
2159
|
+
|
|
2160
|
+
expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2161
|
+
|
|
2162
|
+
const [error] = result.getErrors();
|
|
2163
|
+
|
|
2164
|
+
expect(error.getCode()).to.equal(1012);
|
|
2165
|
+
expect(error.getPropertyName()).to.equal('byteArrayField');
|
|
2166
|
+
expect(error.getConstraintName()).to.equal('maxItems');
|
|
2167
|
+
expect(error.getReason()).to.equal('should be less or equal 255');
|
|
2168
|
+
});
|
|
2169
|
+
|
|
2170
|
+
it('should return invalid result if indexed byte array property have to big maxItems', async () => {
|
|
2171
|
+
rawDataContract.documents.withByteArrays.properties.byteArrayField.maxItems = 8192;
|
|
2172
|
+
|
|
2173
|
+
const result = await validateDataContract(rawDataContract);
|
|
2174
|
+
|
|
2175
|
+
expectValidationError(result, InvalidIndexedPropertyConstraintError);
|
|
2176
|
+
|
|
2177
|
+
const [error] = result.getErrors();
|
|
2178
|
+
|
|
2179
|
+
expect(error.getCode()).to.equal(1012);
|
|
2180
|
+
expect(error.getPropertyName()).to.equal('byteArrayField');
|
|
2181
|
+
expect(error.getConstraintName()).to.equal('maxItems');
|
|
2182
|
+
expect(error.getReason()).to.equal('should be less or equal 255');
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
it('should return valid result if Data Contract is valid', async () => {
|
|
2186
|
+
const result = await validateDataContract(rawDataContract);
|
|
2187
|
+
|
|
2188
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
2189
|
+
expect(result.isValid()).to.be.true();
|
|
2190
|
+
});
|
|
2191
|
+
});
|