@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,1146 @@
|
|
|
1
|
+
const { getRE2Class } = require('@dashevo/wasm-re2');
|
|
2
|
+
|
|
3
|
+
const createAjv = require('../../../../../../../lib/ajv/createAjv');
|
|
4
|
+
|
|
5
|
+
const protocolVersion = require('../../../../../../../lib/version/protocolVersion');
|
|
6
|
+
|
|
7
|
+
const JsonSchemaValidator = require('../../../../../../../lib/validation/JsonSchemaValidator');
|
|
8
|
+
|
|
9
|
+
const generateRandomIdentifier = require('../../../../../../../lib/test/utils/generateRandomIdentifier');
|
|
10
|
+
|
|
11
|
+
const enrichDataContractWithBaseSchema = require('../../../../../../../lib/dataContract/enrichDataContractWithBaseSchema');
|
|
12
|
+
|
|
13
|
+
const DocumentsBatchTransition = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/DocumentsBatchTransition');
|
|
14
|
+
|
|
15
|
+
const getDocumentTransitionsFixture = require('../../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
|
|
16
|
+
const getDocumentsFixture = require('../../../../../../../lib/test/fixtures/getDocumentsFixture');
|
|
17
|
+
const getDataContractFixture = require('../../../../../../../lib/test/fixtures/getDataContractFixture');
|
|
18
|
+
|
|
19
|
+
const ValidationResult = require('../../../../../../../lib/validation/ValidationResult');
|
|
20
|
+
|
|
21
|
+
const validateDocumentsBatchTransitionBasicFactory = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory');
|
|
22
|
+
|
|
23
|
+
const { expectValidationError, expectJsonSchemaError } = require('../../../../../../../lib/test/expect/expectError');
|
|
24
|
+
|
|
25
|
+
const createStateRepositoryMock = require('../../../../../../../lib/test/mocks/createStateRepositoryMock');
|
|
26
|
+
|
|
27
|
+
const InvalidDocumentTransitionIdError = require('../../../../../../../lib/errors/consensus/basic/document/InvalidDocumentTransitionIdError');
|
|
28
|
+
const DataContractNotPresentError = require('../../../../../../../lib/errors/consensus/basic/document/DataContractNotPresentError');
|
|
29
|
+
const MissingDataContractIdError = require('../../../../../../../lib/errors/consensus/basic/document/MissingDataContractIdError');
|
|
30
|
+
const MissingDocumentTransitionTypeError = require('../../../../../../../lib/errors/consensus/basic/document/MissingDocumentTransitionTypeError');
|
|
31
|
+
const InvalidDocumentTypeError = require('../../../../../../../lib/errors/consensus/basic/document/InvalidDocumentTypeError');
|
|
32
|
+
const MissingDocumentTransitionActionError = require('../../../../../../../lib/errors/consensus/basic/document/MissingDocumentTransitionActionError');
|
|
33
|
+
const InvalidDocumentTransitionActionError = require('../../../../../../../lib/errors/consensus/basic/document/InvalidDocumentTransitionActionError');
|
|
34
|
+
const InvalidIdentifierError = require('../../../../../../../lib/errors/consensus/basic/InvalidIdentifierError');
|
|
35
|
+
const DuplicateDocumentTransitionsWithIndicesError = require('../../../../../../../lib/errors/consensus/basic/document/DuplicateDocumentTransitionsWithIndicesError');
|
|
36
|
+
const DuplicateDocumentTransitionsWithIdsError = require('../../../../../../../lib/errors/consensus/basic/document/DuplicateDocumentTransitionsWithIdsError');
|
|
37
|
+
const SomeConsensusError = require('../../../../../../../lib/test/mocks/SomeConsensusError');
|
|
38
|
+
const StateTransitionExecutionContext = require('../../../../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
39
|
+
|
|
40
|
+
describe('validateDocumentsBatchTransitionBasicFactory', () => {
|
|
41
|
+
let dataContract;
|
|
42
|
+
let documents;
|
|
43
|
+
let rawStateTransition;
|
|
44
|
+
let findDuplicatesByIdMock;
|
|
45
|
+
let findDuplicatesByIndicesMock;
|
|
46
|
+
let validateDocumentsBatchTransitionBasic;
|
|
47
|
+
let stateTransition;
|
|
48
|
+
let ownerId;
|
|
49
|
+
let stateRepositoryMock;
|
|
50
|
+
let validator;
|
|
51
|
+
let enrichSpy;
|
|
52
|
+
let documentTransitions;
|
|
53
|
+
let validatePartialCompoundIndicesMock;
|
|
54
|
+
let validateProtocolVersionMock;
|
|
55
|
+
let executionContext;
|
|
56
|
+
|
|
57
|
+
beforeEach(async function beforeEach() {
|
|
58
|
+
dataContract = getDataContractFixture();
|
|
59
|
+
documents = getDocumentsFixture(dataContract);
|
|
60
|
+
|
|
61
|
+
ownerId = getDocumentsFixture.ownerId;
|
|
62
|
+
|
|
63
|
+
documentTransitions = getDocumentTransitionsFixture({
|
|
64
|
+
create: documents,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
executionContext = new StateTransitionExecutionContext();
|
|
68
|
+
|
|
69
|
+
stateTransition = new DocumentsBatchTransition({
|
|
70
|
+
protocolVersion: protocolVersion.latestVersion,
|
|
71
|
+
ownerId,
|
|
72
|
+
contractId: dataContract.getId(),
|
|
73
|
+
transitions: documentTransitions.map((t) => t.toObject()),
|
|
74
|
+
signature: Buffer.alloc(65),
|
|
75
|
+
signaturePublicKeyId: 0,
|
|
76
|
+
}, [dataContract]);
|
|
77
|
+
|
|
78
|
+
rawStateTransition = stateTransition.toObject();
|
|
79
|
+
|
|
80
|
+
findDuplicatesByIdMock = this.sinonSandbox.stub().returns([]);
|
|
81
|
+
findDuplicatesByIndicesMock = this.sinonSandbox.stub().returns([]);
|
|
82
|
+
|
|
83
|
+
const dataContractValidationResult = new ValidationResult();
|
|
84
|
+
dataContractValidationResult.setData(dataContract);
|
|
85
|
+
|
|
86
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
87
|
+
stateRepositoryMock.fetchDataContract.resolves(dataContract);
|
|
88
|
+
|
|
89
|
+
const RE2 = await getRE2Class();
|
|
90
|
+
const ajv = createAjv(RE2);
|
|
91
|
+
|
|
92
|
+
validator = new JsonSchemaValidator(ajv);
|
|
93
|
+
|
|
94
|
+
enrichSpy = this.sinonSandbox.spy(enrichDataContractWithBaseSchema);
|
|
95
|
+
|
|
96
|
+
validatePartialCompoundIndicesMock = this.sinonSandbox.stub().returns(
|
|
97
|
+
new ValidationResult(),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
validateProtocolVersionMock = this.sinonSandbox.stub().returns(new ValidationResult());
|
|
101
|
+
|
|
102
|
+
validateDocumentsBatchTransitionBasic = validateDocumentsBatchTransitionBasicFactory(
|
|
103
|
+
findDuplicatesByIdMock,
|
|
104
|
+
findDuplicatesByIndicesMock,
|
|
105
|
+
stateRepositoryMock,
|
|
106
|
+
validator,
|
|
107
|
+
enrichSpy,
|
|
108
|
+
validatePartialCompoundIndicesMock,
|
|
109
|
+
validateProtocolVersionMock,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('protocolVersion', () => {
|
|
114
|
+
it('should be present', async () => {
|
|
115
|
+
delete rawStateTransition.protocolVersion;
|
|
116
|
+
|
|
117
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
118
|
+
rawStateTransition,
|
|
119
|
+
executionContext,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
expectJsonSchemaError(result);
|
|
123
|
+
|
|
124
|
+
const [error] = result.getErrors();
|
|
125
|
+
|
|
126
|
+
expect(error.getInstancePath()).to.equal('');
|
|
127
|
+
expect(error.getKeyword()).to.equal('required');
|
|
128
|
+
expect(error.getParams().missingProperty).to.equal('protocolVersion');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should be an integer', async () => {
|
|
132
|
+
rawStateTransition.protocolVersion = '1';
|
|
133
|
+
|
|
134
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
135
|
+
rawStateTransition,
|
|
136
|
+
executionContext,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
expectJsonSchemaError(result);
|
|
140
|
+
|
|
141
|
+
const [error] = result.getErrors();
|
|
142
|
+
|
|
143
|
+
expect(error.getInstancePath()).to.equal('/protocolVersion');
|
|
144
|
+
expect(error.getKeyword()).to.equal('type');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should be valid', async () => {
|
|
148
|
+
rawStateTransition.protocolVersion = -1;
|
|
149
|
+
|
|
150
|
+
const protocolVersionError = new SomeConsensusError('test');
|
|
151
|
+
const protocolVersionResult = new ValidationResult([
|
|
152
|
+
protocolVersionError,
|
|
153
|
+
]);
|
|
154
|
+
|
|
155
|
+
validateProtocolVersionMock.returns(protocolVersionResult);
|
|
156
|
+
|
|
157
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
158
|
+
rawStateTransition,
|
|
159
|
+
executionContext,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
expectValidationError(result, SomeConsensusError);
|
|
163
|
+
|
|
164
|
+
const [error] = result.getErrors();
|
|
165
|
+
|
|
166
|
+
expect(error).to.equal(protocolVersionError);
|
|
167
|
+
|
|
168
|
+
expect(validateProtocolVersionMock).to.be.calledOnceWith(
|
|
169
|
+
rawStateTransition.protocolVersion,
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('type', () => {
|
|
175
|
+
it('should be present', async () => {
|
|
176
|
+
delete rawStateTransition.type;
|
|
177
|
+
|
|
178
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
179
|
+
rawStateTransition,
|
|
180
|
+
executionContext,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
expectJsonSchemaError(result);
|
|
184
|
+
|
|
185
|
+
const [error] = result.getErrors();
|
|
186
|
+
|
|
187
|
+
expect(error.getInstancePath()).to.equal('');
|
|
188
|
+
expect(error.getKeyword()).to.equal('required');
|
|
189
|
+
expect(error.getParams().missingProperty).to.equal('type');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should be equal 1', async () => {
|
|
193
|
+
rawStateTransition.type = 666;
|
|
194
|
+
|
|
195
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
196
|
+
rawStateTransition,
|
|
197
|
+
executionContext,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
expectJsonSchemaError(result);
|
|
201
|
+
|
|
202
|
+
const [error] = result.getErrors();
|
|
203
|
+
|
|
204
|
+
expect(error.getInstancePath()).to.equal('/type');
|
|
205
|
+
expect(error.getKeyword()).to.equal('const');
|
|
206
|
+
expect(error.getParams().allowedValue).to.equal(1);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('ownerId', () => {
|
|
211
|
+
it('should be present', async () => {
|
|
212
|
+
delete rawStateTransition.ownerId;
|
|
213
|
+
|
|
214
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
215
|
+
rawStateTransition,
|
|
216
|
+
executionContext,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
expectJsonSchemaError(result);
|
|
220
|
+
|
|
221
|
+
const [error] = result.getErrors();
|
|
222
|
+
|
|
223
|
+
expect(error.getInstancePath()).to.equal('');
|
|
224
|
+
expect(error.getKeyword()).to.equal('required');
|
|
225
|
+
expect(error.getParams().missingProperty).to.equal('ownerId');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should be a byte array', async () => {
|
|
229
|
+
rawStateTransition.ownerId = new Array(32).fill('string');
|
|
230
|
+
|
|
231
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
232
|
+
rawStateTransition,
|
|
233
|
+
executionContext,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expectJsonSchemaError(result, 2);
|
|
237
|
+
|
|
238
|
+
const [error, byteArrayError] = result.getErrors();
|
|
239
|
+
|
|
240
|
+
expect(error.getInstancePath()).to.equal('/ownerId/0');
|
|
241
|
+
expect(error.getKeyword()).to.equal('type');
|
|
242
|
+
|
|
243
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should be no less than 32 bytes', async () => {
|
|
247
|
+
rawStateTransition.ownerId = Buffer.alloc(31);
|
|
248
|
+
|
|
249
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
250
|
+
rawStateTransition,
|
|
251
|
+
executionContext,
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
expectJsonSchemaError(result);
|
|
255
|
+
|
|
256
|
+
const [error] = result.getErrors();
|
|
257
|
+
|
|
258
|
+
expect(error.instancePath).to.equal('/ownerId');
|
|
259
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should be no longer than 32 bytes', async () => {
|
|
263
|
+
rawStateTransition.ownerId = Buffer.alloc(33);
|
|
264
|
+
|
|
265
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
266
|
+
rawStateTransition,
|
|
267
|
+
executionContext,
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
expectJsonSchemaError(result);
|
|
271
|
+
|
|
272
|
+
const [error] = result.getErrors();
|
|
273
|
+
|
|
274
|
+
expect(error.instancePath).to.equal('/ownerId');
|
|
275
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe('document transitions', () => {
|
|
280
|
+
it('should be present', async () => {
|
|
281
|
+
delete rawStateTransition.transitions;
|
|
282
|
+
|
|
283
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
284
|
+
rawStateTransition,
|
|
285
|
+
executionContext,
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
expectJsonSchemaError(result);
|
|
289
|
+
|
|
290
|
+
const [error] = result.getErrors();
|
|
291
|
+
|
|
292
|
+
expect(error.instancePath).to.equal('');
|
|
293
|
+
expect(error.getKeyword()).to.equal('required');
|
|
294
|
+
expect(error.getParams().missingProperty).to.equal('transitions');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should be an array', async () => {
|
|
298
|
+
rawStateTransition.transitions = {};
|
|
299
|
+
|
|
300
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
301
|
+
rawStateTransition,
|
|
302
|
+
executionContext,
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
expectJsonSchemaError(result);
|
|
306
|
+
|
|
307
|
+
const [error] = result.getErrors();
|
|
308
|
+
|
|
309
|
+
expect(error.instancePath).to.equal('/transitions');
|
|
310
|
+
expect(error.getKeyword()).to.equal('type');
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should have at least one element', async () => {
|
|
314
|
+
rawStateTransition.transitions = [];
|
|
315
|
+
|
|
316
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
317
|
+
rawStateTransition,
|
|
318
|
+
executionContext,
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
expectJsonSchemaError(result);
|
|
322
|
+
|
|
323
|
+
const [error] = result.getErrors();
|
|
324
|
+
|
|
325
|
+
expect(error.instancePath).to.equal('/transitions');
|
|
326
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
327
|
+
expect(error.getParams().limit).to.equal(1);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('should have no more than 10 elements', async () => {
|
|
331
|
+
rawStateTransition.transitions = Array(11).fill({});
|
|
332
|
+
|
|
333
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
334
|
+
rawStateTransition,
|
|
335
|
+
executionContext,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
expectJsonSchemaError(result);
|
|
339
|
+
|
|
340
|
+
const [error] = result.getErrors();
|
|
341
|
+
|
|
342
|
+
expect(error.instancePath).to.equal('/transitions');
|
|
343
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
344
|
+
expect(error.getParams().limit).to.equal(10);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should have objects as elements', async () => {
|
|
348
|
+
rawStateTransition.transitions = [1];
|
|
349
|
+
|
|
350
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
351
|
+
rawStateTransition,
|
|
352
|
+
executionContext,
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
expectJsonSchemaError(result);
|
|
356
|
+
|
|
357
|
+
const [error] = result.getErrors();
|
|
358
|
+
|
|
359
|
+
expect(error.instancePath).to.equal('/transitions/0');
|
|
360
|
+
expect(error.getKeyword()).to.equal('type');
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe('document transition', () => {
|
|
364
|
+
describe('$id', () => {
|
|
365
|
+
it('should be present', async () => {
|
|
366
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
367
|
+
|
|
368
|
+
delete documentTransition.$id;
|
|
369
|
+
|
|
370
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
371
|
+
rawStateTransition,
|
|
372
|
+
executionContext,
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
expectJsonSchemaError(result);
|
|
376
|
+
|
|
377
|
+
const [error] = result.getErrors();
|
|
378
|
+
|
|
379
|
+
expect(error.instancePath).to.equal('');
|
|
380
|
+
expect(error.getKeyword()).to.equal('required');
|
|
381
|
+
expect(error.getParams().missingProperty).to.equal('$id');
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('should be a byte array', async () => {
|
|
385
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
386
|
+
|
|
387
|
+
documentTransition.$id = new Array(32).fill('string');
|
|
388
|
+
|
|
389
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
390
|
+
rawStateTransition,
|
|
391
|
+
executionContext,
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
expectJsonSchemaError(result, 2);
|
|
395
|
+
|
|
396
|
+
const [error, byteArrayError] = result.getErrors();
|
|
397
|
+
|
|
398
|
+
expect(error.instancePath).to.equal('/$id/0');
|
|
399
|
+
expect(error.getKeyword()).to.equal('type');
|
|
400
|
+
|
|
401
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it('should be no less than 32 bytes', async () => {
|
|
405
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
406
|
+
|
|
407
|
+
documentTransition.$id = Buffer.alloc(31);
|
|
408
|
+
|
|
409
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
410
|
+
rawStateTransition,
|
|
411
|
+
executionContext,
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
expectJsonSchemaError(result);
|
|
415
|
+
|
|
416
|
+
const [error] = result.getErrors();
|
|
417
|
+
|
|
418
|
+
expect(error.instancePath).to.equal('/$id');
|
|
419
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
420
|
+
expect(error.getParams().limit).to.equal(32);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it('should be no longer than 32 bytes', async () => {
|
|
424
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
425
|
+
|
|
426
|
+
documentTransition.$id = Buffer.alloc(33);
|
|
427
|
+
|
|
428
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
429
|
+
rawStateTransition,
|
|
430
|
+
executionContext,
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
expectJsonSchemaError(result);
|
|
434
|
+
|
|
435
|
+
const [error] = result.getErrors();
|
|
436
|
+
|
|
437
|
+
expect(error.instancePath).to.equal('/$id');
|
|
438
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
439
|
+
expect(error.getParams().limit).to.equal(32);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it('should no have duplicate IDs in the state transition', async () => {
|
|
443
|
+
const duplicates = [documentTransitions[0].toObject()];
|
|
444
|
+
|
|
445
|
+
findDuplicatesByIdMock.returns(duplicates);
|
|
446
|
+
|
|
447
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
448
|
+
rawStateTransition,
|
|
449
|
+
executionContext,
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
expectValidationError(result, DuplicateDocumentTransitionsWithIdsError);
|
|
453
|
+
|
|
454
|
+
const [error] = result.getErrors();
|
|
455
|
+
|
|
456
|
+
expect(error.getCode()).to.equal(1019);
|
|
457
|
+
expect(error.getDocumentTransitionReferences()).to.deep.equal(
|
|
458
|
+
duplicates.map((d) => [d.$type, d.$id]),
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
462
|
+
dataContract.getId(),
|
|
463
|
+
executionContext,
|
|
464
|
+
);
|
|
465
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
466
|
+
expect(findDuplicatesByIdMock).to.have.been.calledOnceWithExactly(
|
|
467
|
+
rawStateTransition.transitions,
|
|
468
|
+
);
|
|
469
|
+
expect(findDuplicatesByIndicesMock).to.have.been.calledOnceWithExactly(
|
|
470
|
+
rawStateTransition.transitions, dataContract,
|
|
471
|
+
);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe('$dataContractId', () => {
|
|
476
|
+
it('should be present', async () => {
|
|
477
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
478
|
+
|
|
479
|
+
delete firstDocumentTransition.$dataContractId;
|
|
480
|
+
|
|
481
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
482
|
+
rawStateTransition,
|
|
483
|
+
executionContext,
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
expectValidationError(result, MissingDataContractIdError);
|
|
487
|
+
|
|
488
|
+
const [error] = result.getErrors();
|
|
489
|
+
|
|
490
|
+
expect(error.getCode()).to.equal(1025);
|
|
491
|
+
|
|
492
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
493
|
+
dataContract.getId(),
|
|
494
|
+
executionContext,
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
498
|
+
|
|
499
|
+
expect(findDuplicatesByIdMock).to.have.been.calledOnceWithExactly(
|
|
500
|
+
rawStateTransition.transitions.slice(1),
|
|
501
|
+
);
|
|
502
|
+
expect(findDuplicatesByIndicesMock).to.have.been.calledOnceWithExactly(
|
|
503
|
+
rawStateTransition.transitions.slice(1), dataContract,
|
|
504
|
+
);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should be a byte array', async () => {
|
|
508
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
509
|
+
|
|
510
|
+
firstDocumentTransition.$dataContractId = 'something';
|
|
511
|
+
|
|
512
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
513
|
+
rawStateTransition,
|
|
514
|
+
executionContext,
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
expectValidationError(result, InvalidIdentifierError);
|
|
518
|
+
|
|
519
|
+
const [error] = result.getErrors();
|
|
520
|
+
|
|
521
|
+
expect(error.getCode()).to.equal(1006);
|
|
522
|
+
|
|
523
|
+
expect(error.getIdentifierName()).to.equal('$dataContractId');
|
|
524
|
+
|
|
525
|
+
expect(error.getIdentifierError()).to.be.instanceOf(Error);
|
|
526
|
+
expect(error.getIdentifierError().message).to.equal('Identifier expects Buffer');
|
|
527
|
+
|
|
528
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
529
|
+
dataContract.getId(),
|
|
530
|
+
executionContext,
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
534
|
+
|
|
535
|
+
expect(findDuplicatesByIdMock).to.have.been.calledOnceWithExactly(
|
|
536
|
+
rawStateTransition.transitions.slice(1),
|
|
537
|
+
);
|
|
538
|
+
expect(findDuplicatesByIndicesMock).to.have.been.calledOnceWithExactly(
|
|
539
|
+
rawStateTransition.transitions.slice(1), dataContract,
|
|
540
|
+
);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it('should exists in the state', async () => {
|
|
544
|
+
stateRepositoryMock.fetchDataContract.resolves(undefined);
|
|
545
|
+
|
|
546
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
547
|
+
rawStateTransition,
|
|
548
|
+
executionContext,
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
expectValidationError(result, DataContractNotPresentError);
|
|
552
|
+
|
|
553
|
+
const [error] = result.getErrors();
|
|
554
|
+
|
|
555
|
+
expect(error.getCode()).to.equal(1018);
|
|
556
|
+
expect(error.getDataContractId()).to.deep.equal(dataContract.getId());
|
|
557
|
+
|
|
558
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
559
|
+
dataContract.getId(),
|
|
560
|
+
executionContext,
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
expect(enrichSpy).to.have.not.been.called();
|
|
564
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
565
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
describe('$type', () => {
|
|
570
|
+
it('should be present', async () => {
|
|
571
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
572
|
+
|
|
573
|
+
delete firstDocumentTransition.$type;
|
|
574
|
+
|
|
575
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
576
|
+
rawStateTransition,
|
|
577
|
+
executionContext,
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
expectValidationError(result, MissingDocumentTransitionTypeError);
|
|
581
|
+
|
|
582
|
+
const [error] = result.getErrors();
|
|
583
|
+
|
|
584
|
+
expect(error.getCode()).to.equal(1027);
|
|
585
|
+
|
|
586
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
587
|
+
dataContract.getId(),
|
|
588
|
+
executionContext,
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
592
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
593
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('should be defined in Data Contract', async () => {
|
|
597
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
598
|
+
|
|
599
|
+
firstDocumentTransition.$type = 'wrong';
|
|
600
|
+
|
|
601
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
602
|
+
rawStateTransition,
|
|
603
|
+
executionContext,
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
expectValidationError(result, InvalidDocumentTypeError);
|
|
607
|
+
|
|
608
|
+
const [error] = result.getErrors();
|
|
609
|
+
|
|
610
|
+
expect(error.getCode()).to.equal(1024);
|
|
611
|
+
expect(error.getType()).to.equal(firstDocumentTransition.$type);
|
|
612
|
+
|
|
613
|
+
expect(Buffer.isBuffer(error.getDataContractId())).to.be.true();
|
|
614
|
+
expect(error.getDataContractId()).to.deep.equal(dataContract.getId().toBuffer());
|
|
615
|
+
|
|
616
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
617
|
+
dataContract.getId(),
|
|
618
|
+
executionContext,
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
622
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
623
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
describe('$action', () => {
|
|
628
|
+
it('should be present', async () => {
|
|
629
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
630
|
+
|
|
631
|
+
delete firstDocumentTransition.$action;
|
|
632
|
+
|
|
633
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
634
|
+
rawStateTransition,
|
|
635
|
+
executionContext,
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
expectValidationError(result, MissingDocumentTransitionActionError);
|
|
639
|
+
|
|
640
|
+
const [error] = result.getErrors();
|
|
641
|
+
|
|
642
|
+
expect(error.getCode()).to.equal(1026);
|
|
643
|
+
|
|
644
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
645
|
+
dataContract.getId(),
|
|
646
|
+
executionContext,
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
650
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
651
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
it('should throw InvalidDocumentTransitionActionError if action is not valid', async () => {
|
|
655
|
+
const [firstDocumentTransition] = rawStateTransition.transitions;
|
|
656
|
+
|
|
657
|
+
firstDocumentTransition.$action = 4;
|
|
658
|
+
|
|
659
|
+
try {
|
|
660
|
+
await validateDocumentsBatchTransitionBasic(
|
|
661
|
+
rawStateTransition,
|
|
662
|
+
executionContext,
|
|
663
|
+
);
|
|
664
|
+
} catch (e) {
|
|
665
|
+
expect(e).to.be.instanceOf(InvalidDocumentTransitionActionError);
|
|
666
|
+
expect(e.getAction()).to.equal(firstDocumentTransition.$action);
|
|
667
|
+
expect(e.getRawDocumentTransition()).to.deep.equal(firstDocumentTransition);
|
|
668
|
+
|
|
669
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
670
|
+
dataContract.getId(),
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
674
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
675
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
describe('create', () => {
|
|
681
|
+
describe('$id', () => {
|
|
682
|
+
it('should be valid generated ID', async () => {
|
|
683
|
+
const [firstTransition] = rawStateTransition.transitions;
|
|
684
|
+
|
|
685
|
+
const expectedId = firstTransition.$id;
|
|
686
|
+
firstTransition.$id = generateRandomIdentifier();
|
|
687
|
+
|
|
688
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
689
|
+
rawStateTransition,
|
|
690
|
+
executionContext,
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
expectValidationError(result, InvalidDocumentTransitionIdError);
|
|
694
|
+
|
|
695
|
+
const [error] = result.getErrors();
|
|
696
|
+
|
|
697
|
+
expect(error.getCode()).to.equal(1023);
|
|
698
|
+
|
|
699
|
+
expect(Buffer.isBuffer(error.getExpectedId())).to.be.true();
|
|
700
|
+
expect(error.getExpectedId()).to.deep.equal(expectedId);
|
|
701
|
+
|
|
702
|
+
expect(Buffer.isBuffer(error.getInvalidId())).to.be.true();
|
|
703
|
+
expect(error.getInvalidId()).to.deep.equal(firstTransition.$id);
|
|
704
|
+
|
|
705
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
706
|
+
dataContract.getId(),
|
|
707
|
+
executionContext,
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
711
|
+
|
|
712
|
+
expect(findDuplicatesByIdMock).to.have.not.been.called();
|
|
713
|
+
expect(findDuplicatesByIndicesMock).to.have.not.been.called();
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
describe('$entropy', () => {
|
|
718
|
+
it('should be present', async () => {
|
|
719
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
720
|
+
|
|
721
|
+
delete documentTransition.$entropy;
|
|
722
|
+
|
|
723
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
724
|
+
rawStateTransition,
|
|
725
|
+
executionContext,
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
expectJsonSchemaError(result);
|
|
729
|
+
|
|
730
|
+
const [error] = result.getErrors();
|
|
731
|
+
|
|
732
|
+
expect(error.instancePath).to.equal('');
|
|
733
|
+
expect(error.getKeyword()).to.equal('required');
|
|
734
|
+
expect(error.getParams().missingProperty).to.equal('$entropy');
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('should be a byte array', async () => {
|
|
738
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
739
|
+
|
|
740
|
+
documentTransition.$entropy = new Array(32).fill('string');
|
|
741
|
+
|
|
742
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
743
|
+
rawStateTransition,
|
|
744
|
+
executionContext,
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
expectJsonSchemaError(result, 2);
|
|
748
|
+
|
|
749
|
+
const [error, byteArrayError] = result.getErrors();
|
|
750
|
+
|
|
751
|
+
expect(error.instancePath).to.equal('/$entropy/0');
|
|
752
|
+
expect(error.getKeyword()).to.equal('type');
|
|
753
|
+
|
|
754
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
it('should be no less than 32 bytes', async () => {
|
|
758
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
759
|
+
|
|
760
|
+
documentTransition.$entropy = Buffer.alloc(31);
|
|
761
|
+
|
|
762
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
763
|
+
rawStateTransition,
|
|
764
|
+
executionContext,
|
|
765
|
+
);
|
|
766
|
+
|
|
767
|
+
expectJsonSchemaError(result);
|
|
768
|
+
|
|
769
|
+
const [error] = result.getErrors();
|
|
770
|
+
|
|
771
|
+
expect(error.instancePath).to.equal('/$entropy');
|
|
772
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
773
|
+
expect(error.getParams().limit).to.equal(32);
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
it('should be no longer than 32 bytes', async () => {
|
|
777
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
778
|
+
|
|
779
|
+
documentTransition.$entropy = Buffer.alloc(33);
|
|
780
|
+
|
|
781
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
782
|
+
rawStateTransition,
|
|
783
|
+
executionContext,
|
|
784
|
+
);
|
|
785
|
+
|
|
786
|
+
expectJsonSchemaError(result);
|
|
787
|
+
|
|
788
|
+
const [error] = result.getErrors();
|
|
789
|
+
|
|
790
|
+
expect(error.instancePath).to.equal('/$entropy');
|
|
791
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
792
|
+
expect(error.getParams().limit).to.equal(32);
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
describe('replace', () => {
|
|
798
|
+
beforeEach(() => {
|
|
799
|
+
documentTransitions = getDocumentTransitionsFixture({
|
|
800
|
+
create: [],
|
|
801
|
+
replace: documents,
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
stateTransition = new DocumentsBatchTransition({
|
|
805
|
+
protocolVersion: protocolVersion.latestVersion,
|
|
806
|
+
ownerId,
|
|
807
|
+
contractId: dataContract.getId(),
|
|
808
|
+
transitions: documentTransitions.map((t) => t.toObject()),
|
|
809
|
+
signature: Buffer.alloc(65),
|
|
810
|
+
signaturePublicKeyId: 0,
|
|
811
|
+
}, [dataContract]);
|
|
812
|
+
|
|
813
|
+
rawStateTransition = stateTransition.toObject();
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
describe('$revision', () => {
|
|
817
|
+
it('should be present', async () => {
|
|
818
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
819
|
+
|
|
820
|
+
delete documentTransition.$revision;
|
|
821
|
+
|
|
822
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
823
|
+
rawStateTransition,
|
|
824
|
+
executionContext,
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
expectJsonSchemaError(result);
|
|
828
|
+
|
|
829
|
+
const [error] = result.getErrors();
|
|
830
|
+
|
|
831
|
+
expect(error.getParams().missingProperty).to.equal('$revision');
|
|
832
|
+
expect(error.getKeyword()).to.equal('required');
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it('should be a number', async () => {
|
|
836
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
837
|
+
|
|
838
|
+
documentTransition.$revision = '1';
|
|
839
|
+
|
|
840
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
841
|
+
rawStateTransition,
|
|
842
|
+
executionContext,
|
|
843
|
+
);
|
|
844
|
+
|
|
845
|
+
expectJsonSchemaError(result);
|
|
846
|
+
|
|
847
|
+
const [error] = result.getErrors();
|
|
848
|
+
|
|
849
|
+
expect(error.instancePath).to.equal('/$revision');
|
|
850
|
+
expect(error.getKeyword()).to.equal('type');
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
it('should be multiple of 1.0', async () => {
|
|
854
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
855
|
+
|
|
856
|
+
documentTransition.$revision = 1.2;
|
|
857
|
+
|
|
858
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
859
|
+
rawStateTransition,
|
|
860
|
+
executionContext,
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
expectJsonSchemaError(result);
|
|
864
|
+
|
|
865
|
+
const [error] = result.getErrors();
|
|
866
|
+
|
|
867
|
+
expect(error.instancePath).to.equal('/$revision');
|
|
868
|
+
expect(error.getKeyword()).to.equal('type');
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it('should have a minimum value of 1', async () => {
|
|
872
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
873
|
+
|
|
874
|
+
documentTransition.$revision = 0;
|
|
875
|
+
|
|
876
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
877
|
+
rawStateTransition,
|
|
878
|
+
executionContext,
|
|
879
|
+
);
|
|
880
|
+
|
|
881
|
+
expectJsonSchemaError(result);
|
|
882
|
+
|
|
883
|
+
const [error] = result.getErrors();
|
|
884
|
+
|
|
885
|
+
expect(error.instancePath).to.equal('/$revision');
|
|
886
|
+
expect(error.getKeyword()).to.equal('minimum');
|
|
887
|
+
});
|
|
888
|
+
});
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
describe('delete', () => {
|
|
892
|
+
beforeEach(() => {
|
|
893
|
+
documentTransitions = getDocumentTransitionsFixture({
|
|
894
|
+
create: [],
|
|
895
|
+
replace: [],
|
|
896
|
+
delete: documents,
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
stateTransition = new DocumentsBatchTransition({
|
|
900
|
+
protocolVersion: protocolVersion.latestVersion,
|
|
901
|
+
ownerId,
|
|
902
|
+
contractId: dataContract.getId(),
|
|
903
|
+
transitions: documentTransitions.map((t) => t.toObject()),
|
|
904
|
+
signature: Buffer.alloc(65),
|
|
905
|
+
signaturePublicKeyId: 0,
|
|
906
|
+
}, [dataContract]);
|
|
907
|
+
|
|
908
|
+
rawStateTransition = stateTransition.toObject();
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
it('should return invalid result if delete transaction is not valid', async () => {
|
|
912
|
+
const [documentTransition] = rawStateTransition.transitions;
|
|
913
|
+
|
|
914
|
+
delete documentTransition.$id;
|
|
915
|
+
|
|
916
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
917
|
+
rawStateTransition,
|
|
918
|
+
executionContext,
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
expectJsonSchemaError(result);
|
|
922
|
+
|
|
923
|
+
const [error] = result.getErrors();
|
|
924
|
+
|
|
925
|
+
expect(error.getParams().missingProperty).to.equal('$id');
|
|
926
|
+
expect(error.getKeyword()).to.equal('required');
|
|
927
|
+
});
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
it('should return invalid result if there are duplicate unique index values', async () => {
|
|
931
|
+
const duplicates = [documentTransitions[1].toObject()];
|
|
932
|
+
|
|
933
|
+
findDuplicatesByIndicesMock.returns(duplicates);
|
|
934
|
+
|
|
935
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
936
|
+
rawStateTransition,
|
|
937
|
+
executionContext,
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
expectValidationError(result, DuplicateDocumentTransitionsWithIndicesError);
|
|
941
|
+
|
|
942
|
+
const [error] = result.getErrors();
|
|
943
|
+
|
|
944
|
+
expect(error.getCode()).to.equal(1020);
|
|
945
|
+
|
|
946
|
+
expect(error.getDocumentTransitionReferences()).to.deep.equal(
|
|
947
|
+
duplicates.map((d) => [d.$type, d.$id]),
|
|
948
|
+
);
|
|
949
|
+
|
|
950
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
951
|
+
dataContract.getId(),
|
|
952
|
+
executionContext,
|
|
953
|
+
);
|
|
954
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
955
|
+
expect(findDuplicatesByIdMock).to.have.been.calledOnceWithExactly(
|
|
956
|
+
rawStateTransition.transitions,
|
|
957
|
+
);
|
|
958
|
+
expect(findDuplicatesByIndicesMock).to.have.been.calledOnceWithExactly(
|
|
959
|
+
rawStateTransition.transitions, dataContract,
|
|
960
|
+
);
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
it('should return invalid result if compound index doesn\'t contain all fields', async () => {
|
|
964
|
+
const consensusError = new SomeConsensusError('error');
|
|
965
|
+
|
|
966
|
+
validatePartialCompoundIndicesMock.returns(
|
|
967
|
+
new ValidationResult([consensusError]),
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
971
|
+
rawStateTransition,
|
|
972
|
+
executionContext,
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
expectValidationError(result);
|
|
976
|
+
|
|
977
|
+
const [error] = result.getErrors();
|
|
978
|
+
|
|
979
|
+
expect(error).to.equal(consensusError);
|
|
980
|
+
|
|
981
|
+
expect(validatePartialCompoundIndicesMock).to.be.calledOnceWithExactly(
|
|
982
|
+
ownerId.toBuffer(),
|
|
983
|
+
rawStateTransition.transitions,
|
|
984
|
+
dataContract,
|
|
985
|
+
);
|
|
986
|
+
|
|
987
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
988
|
+
dataContract.getId(),
|
|
989
|
+
executionContext,
|
|
990
|
+
);
|
|
991
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
describe('signature', () => {
|
|
997
|
+
it('should be present', async () => {
|
|
998
|
+
delete rawStateTransition.signature;
|
|
999
|
+
|
|
1000
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1001
|
+
rawStateTransition,
|
|
1002
|
+
executionContext,
|
|
1003
|
+
);
|
|
1004
|
+
|
|
1005
|
+
expectJsonSchemaError(result);
|
|
1006
|
+
|
|
1007
|
+
const [error] = result.getErrors();
|
|
1008
|
+
|
|
1009
|
+
expect(error.instancePath).to.equal('');
|
|
1010
|
+
expect(error.getKeyword()).to.equal('required');
|
|
1011
|
+
expect(error.getParams().missingProperty).to.equal('signature');
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
it('should be a byte array', async () => {
|
|
1015
|
+
rawStateTransition.signature = new Array(65).fill('string');
|
|
1016
|
+
|
|
1017
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1018
|
+
rawStateTransition,
|
|
1019
|
+
executionContext,
|
|
1020
|
+
);
|
|
1021
|
+
|
|
1022
|
+
expectJsonSchemaError(result, 2);
|
|
1023
|
+
|
|
1024
|
+
const [error, byteArrayError] = result.getErrors();
|
|
1025
|
+
|
|
1026
|
+
expect(error.instancePath).to.equal('/signature/0');
|
|
1027
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1028
|
+
|
|
1029
|
+
expect(byteArrayError.getKeyword()).to.equal('byteArray');
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
it('should be not less than 65 bytes', async () => {
|
|
1033
|
+
rawStateTransition.signature = Buffer.alloc(64);
|
|
1034
|
+
|
|
1035
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1036
|
+
rawStateTransition,
|
|
1037
|
+
executionContext,
|
|
1038
|
+
);
|
|
1039
|
+
|
|
1040
|
+
expectJsonSchemaError(result);
|
|
1041
|
+
|
|
1042
|
+
const [error] = result.getErrors();
|
|
1043
|
+
|
|
1044
|
+
expect(error.instancePath).to.equal('/signature');
|
|
1045
|
+
expect(error.getKeyword()).to.equal('minItems');
|
|
1046
|
+
expect(error.getParams().limit).to.equal(65);
|
|
1047
|
+
});
|
|
1048
|
+
|
|
1049
|
+
it('should be not longer than 96 bytes', async () => {
|
|
1050
|
+
rawStateTransition.signature = Buffer.alloc(97);
|
|
1051
|
+
|
|
1052
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1053
|
+
rawStateTransition,
|
|
1054
|
+
executionContext,
|
|
1055
|
+
);
|
|
1056
|
+
|
|
1057
|
+
expectJsonSchemaError(result);
|
|
1058
|
+
|
|
1059
|
+
const [error] = result.getErrors();
|
|
1060
|
+
|
|
1061
|
+
expect(error.instancePath).to.equal('/signature');
|
|
1062
|
+
expect(error.getKeyword()).to.equal('maxItems');
|
|
1063
|
+
expect(error.getParams().limit).to.equal(96);
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
describe('signaturePublicKeyId', () => {
|
|
1068
|
+
it('should be an integer', async () => {
|
|
1069
|
+
rawStateTransition.signaturePublicKeyId = 1.4;
|
|
1070
|
+
|
|
1071
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1072
|
+
rawStateTransition,
|
|
1073
|
+
executionContext,
|
|
1074
|
+
);
|
|
1075
|
+
|
|
1076
|
+
expectJsonSchemaError(result, 1);
|
|
1077
|
+
|
|
1078
|
+
const [error] = result.getErrors();
|
|
1079
|
+
|
|
1080
|
+
expect(error.instancePath).to.equal('/signaturePublicKeyId');
|
|
1081
|
+
expect(error.getKeyword()).to.equal('type');
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
it('should not be < 0', async () => {
|
|
1085
|
+
rawStateTransition.signaturePublicKeyId = -1;
|
|
1086
|
+
|
|
1087
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1088
|
+
rawStateTransition,
|
|
1089
|
+
executionContext,
|
|
1090
|
+
);
|
|
1091
|
+
|
|
1092
|
+
expectJsonSchemaError(result, 1);
|
|
1093
|
+
|
|
1094
|
+
const [error] = result.getErrors();
|
|
1095
|
+
|
|
1096
|
+
expect(error.instancePath).to.equal('/signaturePublicKeyId');
|
|
1097
|
+
expect(error.getKeyword()).to.equal('minimum');
|
|
1098
|
+
});
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
it('should return valid result', async () => {
|
|
1102
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1103
|
+
rawStateTransition,
|
|
1104
|
+
executionContext,
|
|
1105
|
+
);
|
|
1106
|
+
|
|
1107
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
1108
|
+
expect(result.isValid()).to.be.true();
|
|
1109
|
+
|
|
1110
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
1111
|
+
dataContract.getId(),
|
|
1112
|
+
executionContext,
|
|
1113
|
+
);
|
|
1114
|
+
|
|
1115
|
+
expect(enrichSpy).to.have.been.calledThrice();
|
|
1116
|
+
|
|
1117
|
+
expect(findDuplicatesByIdMock).to.have.been.calledOnceWithExactly(
|
|
1118
|
+
rawStateTransition.transitions,
|
|
1119
|
+
);
|
|
1120
|
+
|
|
1121
|
+
expect(findDuplicatesByIndicesMock).to.have.been.calledOnceWithExactly(
|
|
1122
|
+
rawStateTransition.transitions, dataContract,
|
|
1123
|
+
);
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1126
|
+
it('should not validate Document transitions on dry run', async () => {
|
|
1127
|
+
stateRepositoryMock.fetchDataContract.resolves(null);
|
|
1128
|
+
|
|
1129
|
+
executionContext.enableDryRun();
|
|
1130
|
+
|
|
1131
|
+
const result = await validateDocumentsBatchTransitionBasic(
|
|
1132
|
+
rawStateTransition,
|
|
1133
|
+
executionContext,
|
|
1134
|
+
);
|
|
1135
|
+
|
|
1136
|
+
executionContext.disableDryRun();
|
|
1137
|
+
|
|
1138
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
1139
|
+
expect(result.isValid()).to.be.true();
|
|
1140
|
+
|
|
1141
|
+
expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnceWithExactly(
|
|
1142
|
+
dataContract.getId(),
|
|
1143
|
+
executionContext,
|
|
1144
|
+
);
|
|
1145
|
+
});
|
|
1146
|
+
});
|