@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,158 @@
|
|
|
1
|
+
const getDataContractFixture = require('../../../../../lib/test/fixtures/getDataContractFixture');
|
|
2
|
+
const stateTransitionTypes = require('../../../../../lib/stateTransition/stateTransitionTypes');
|
|
3
|
+
|
|
4
|
+
const Identifier = require('../../../../../lib/identifier/Identifier');
|
|
5
|
+
const protocolVersion = require('../../../../../lib/version/protocolVersion');
|
|
6
|
+
const DataContractUpdateTransition = require('../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition');
|
|
7
|
+
const hash = require('../../../../../lib/util/hash');
|
|
8
|
+
const serializer = require('../../../../../lib/util/serializer');
|
|
9
|
+
|
|
10
|
+
describe('DataContractUpdateTransition', () => {
|
|
11
|
+
let stateTransition;
|
|
12
|
+
let dataContract;
|
|
13
|
+
let hashMock;
|
|
14
|
+
let encodeMock;
|
|
15
|
+
|
|
16
|
+
beforeEach(function beforeEach() {
|
|
17
|
+
dataContract = getDataContractFixture();
|
|
18
|
+
|
|
19
|
+
encodeMock = this.sinonSandbox.stub(serializer, 'encode');
|
|
20
|
+
hashMock = this.sinonSandbox.stub(hash, 'hash');
|
|
21
|
+
|
|
22
|
+
stateTransition = new DataContractUpdateTransition({
|
|
23
|
+
protocolVersion: protocolVersion.latestVersion,
|
|
24
|
+
dataContract: dataContract.toObject(),
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
encodeMock.restore();
|
|
30
|
+
hashMock.restore();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('#getProtocolVersion', () => {
|
|
34
|
+
it('should return the current protocol version', () => {
|
|
35
|
+
const result = stateTransition.getProtocolVersion();
|
|
36
|
+
|
|
37
|
+
expect(result).to.equal(protocolVersion.latestVersion);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('#getType', () => {
|
|
42
|
+
it('should return State Transition type', () => {
|
|
43
|
+
const result = stateTransition.getType();
|
|
44
|
+
|
|
45
|
+
expect(result).to.equal(stateTransitionTypes.DATA_CONTRACT_UPDATE);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('#getDataContract', () => {
|
|
50
|
+
it('should return Data Contract', () => {
|
|
51
|
+
const result = stateTransition.getDataContract();
|
|
52
|
+
|
|
53
|
+
expect(result.toObject()).to.deep.equal(dataContract.toObject());
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('#toJSON', () => {
|
|
58
|
+
it('should return State Transition as plain JS object', () => {
|
|
59
|
+
expect(stateTransition.toJSON()).to.deep.equal({
|
|
60
|
+
protocolVersion: protocolVersion.latestVersion,
|
|
61
|
+
type: stateTransitionTypes.DATA_CONTRACT_UPDATE,
|
|
62
|
+
dataContract: dataContract.toJSON(),
|
|
63
|
+
signaturePublicKeyId: undefined,
|
|
64
|
+
signature: undefined,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('#toBuffer', () => {
|
|
70
|
+
it('should return serialized State Transition', () => {
|
|
71
|
+
const serializedStateTransition = Buffer.from('123');
|
|
72
|
+
|
|
73
|
+
encodeMock.returns(serializedStateTransition);
|
|
74
|
+
|
|
75
|
+
const protocolVersionUInt32 = Buffer.alloc(4);
|
|
76
|
+
protocolVersionUInt32.writeUInt32LE(stateTransition.protocolVersion, 0);
|
|
77
|
+
|
|
78
|
+
const result = stateTransition.toBuffer();
|
|
79
|
+
|
|
80
|
+
expect(result).to.deep.equal(
|
|
81
|
+
Buffer.concat([protocolVersionUInt32, serializedStateTransition]),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const dataToEncode = stateTransition.toObject();
|
|
85
|
+
delete dataToEncode.protocolVersion;
|
|
86
|
+
|
|
87
|
+
expect(encodeMock.getCall(0).args).to.have.deep.members([
|
|
88
|
+
dataToEncode,
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('#hash', () => {
|
|
94
|
+
it('should return State Transition hash as hex', () => {
|
|
95
|
+
const serializedDocument = Buffer.from('123');
|
|
96
|
+
const hashedDocument = '456';
|
|
97
|
+
|
|
98
|
+
encodeMock.returns(serializedDocument);
|
|
99
|
+
hashMock.returns(hashedDocument);
|
|
100
|
+
|
|
101
|
+
const result = stateTransition.hash();
|
|
102
|
+
|
|
103
|
+
expect(result).to.equal(hashedDocument);
|
|
104
|
+
|
|
105
|
+
const dataToEncode = stateTransition.toObject();
|
|
106
|
+
delete dataToEncode.protocolVersion;
|
|
107
|
+
|
|
108
|
+
expect(encodeMock.getCall(0).args).to.have.deep.members([
|
|
109
|
+
dataToEncode,
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
const protocolVersionUInt32 = Buffer.alloc(4);
|
|
113
|
+
protocolVersionUInt32.writeUInt32LE(stateTransition.protocolVersion, 0);
|
|
114
|
+
|
|
115
|
+
expect(hashMock).to.have.been.calledOnceWith(
|
|
116
|
+
Buffer.concat([protocolVersionUInt32, serializedDocument]),
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('#getOwnerId', () => {
|
|
122
|
+
it('should return owner id', async () => {
|
|
123
|
+
const result = stateTransition.getOwnerId();
|
|
124
|
+
|
|
125
|
+
expect(result).to.equal(stateTransition.getDataContract().getOwnerId());
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('#getModifiedDataIds', () => {
|
|
130
|
+
it('should return ids of affected data contracts', () => {
|
|
131
|
+
const result = stateTransition.getModifiedDataIds();
|
|
132
|
+
|
|
133
|
+
expect(result.length).to.be.equal(1);
|
|
134
|
+
const contractId = result[0];
|
|
135
|
+
|
|
136
|
+
expect(contractId).to.be.an.instanceOf(Identifier);
|
|
137
|
+
expect(contractId).to.be.deep.equal(dataContract.getId());
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('#isDataContractStateTransition', () => {
|
|
142
|
+
it('should return true', () => {
|
|
143
|
+
expect(stateTransition.isDataContractStateTransition()).to.be.true();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('#isDocumentStateTransition', () => {
|
|
148
|
+
it('should return false', () => {
|
|
149
|
+
expect(stateTransition.isDocumentStateTransition()).to.be.false();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe('#isIdentityStateTransition', () => {
|
|
154
|
+
it('should return false', () => {
|
|
155
|
+
expect(stateTransition.isIdentityStateTransition()).to.be.false();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const DataContractUpdateTransition = require(
|
|
2
|
+
'../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition',
|
|
3
|
+
);
|
|
4
|
+
|
|
5
|
+
const getDataContractFixture = require('../../../../../lib/test/fixtures/getDataContractFixture');
|
|
6
|
+
|
|
7
|
+
const applyDataContractUpdateTransitionFactory = require(
|
|
8
|
+
'../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory',
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const createStateRepositoryMock = require('../../../../../lib/test/mocks/createStateRepositoryMock');
|
|
12
|
+
const StateTransitionExecutionContext = require('../../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
13
|
+
|
|
14
|
+
describe('applyDataContractUpdateTransitionFactory', () => {
|
|
15
|
+
let stateTransition;
|
|
16
|
+
let dataContract;
|
|
17
|
+
let stateRepositoryMock;
|
|
18
|
+
let applyDataContractUpdateTransition;
|
|
19
|
+
let executionContext;
|
|
20
|
+
|
|
21
|
+
beforeEach(function beforeEach() {
|
|
22
|
+
dataContract = getDataContractFixture();
|
|
23
|
+
|
|
24
|
+
stateTransition = new DataContractUpdateTransition({
|
|
25
|
+
dataContract: dataContract.toObject(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
executionContext = new StateTransitionExecutionContext();
|
|
29
|
+
|
|
30
|
+
stateTransition.setExecutionContext(executionContext);
|
|
31
|
+
|
|
32
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
33
|
+
|
|
34
|
+
applyDataContractUpdateTransition = applyDataContractUpdateTransitionFactory(
|
|
35
|
+
stateRepositoryMock,
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should store a data contract from state transition in the repository', async () => {
|
|
40
|
+
await applyDataContractUpdateTransition(stateTransition);
|
|
41
|
+
|
|
42
|
+
expect(stateRepositoryMock.storeDataContract).to.have.been.calledOnceWithExactly(
|
|
43
|
+
stateTransition.getDataContract(),
|
|
44
|
+
executionContext,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const validateIndicesAreBackwardCompatible = require('../../../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible');
|
|
2
|
+
const DataContractHaveNewIndexWithOldPropertiesError = require('../../../../../../../lib/errors/consensus/basic/dataContract/DataContractInvalidIndexDefinitionUpdateError');
|
|
3
|
+
const DataContractHaveNewUniqueIndexError = require('../../../../../../../lib/errors/consensus/basic/dataContract/DataContractHaveNewUniqueIndexError');
|
|
4
|
+
const DataContractIndicesChangedError = require('../../../../../../../lib/errors/consensus/basic/dataContract/DataContractUniqueIndicesChangedError');
|
|
5
|
+
const getDataContractFixture = require('../../../../../../../lib/test/fixtures/getDataContractFixture');
|
|
6
|
+
const DataContractInvalidIndexDefinitionUpdateError = require('../../../../../../../lib/errors/consensus/basic/dataContract/DataContractInvalidIndexDefinitionUpdateError');
|
|
7
|
+
|
|
8
|
+
describe('validateIndicesAreBackwardCompatible', () => {
|
|
9
|
+
let oldDocumentsSchema;
|
|
10
|
+
let newDocumentsSchema;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
const oldDataContract = getDataContractFixture();
|
|
14
|
+
const newDataContract = getDataContractFixture();
|
|
15
|
+
|
|
16
|
+
newDataContract.getDocumentSchema('indexedDocument').properties.otherName = {
|
|
17
|
+
type: 'string',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
newDataContract.getDocumentSchema('indexedDocument').indices.push({
|
|
21
|
+
name: 'index42',
|
|
22
|
+
unique: false,
|
|
23
|
+
properties: [
|
|
24
|
+
{ otherName: 'asc' },
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
newDataContract.getDocumentSchema('indexedDocument').indices.push({
|
|
29
|
+
name: 'index42',
|
|
30
|
+
properties: [
|
|
31
|
+
{ otherName: 'asc' },
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
oldDocumentsSchema = oldDataContract.getDocuments();
|
|
36
|
+
newDocumentsSchema = newDataContract.getDocuments();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should return invalid result if some of unique indices have changed', async () => {
|
|
40
|
+
newDocumentsSchema.indexedDocument.indices[0].properties[0].lastName = 'asc';
|
|
41
|
+
|
|
42
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
43
|
+
|
|
44
|
+
expect(result.isValid()).to.be.false();
|
|
45
|
+
|
|
46
|
+
const error = result.getErrors()[0];
|
|
47
|
+
|
|
48
|
+
expect(error).to.be.an.instanceOf(DataContractIndicesChangedError);
|
|
49
|
+
expect(error.getIndexName()).to.equal(newDocumentsSchema.indexedDocument.indices[0].name);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return invalid result if non-unique index update failed due to changed old properties', async () => {
|
|
53
|
+
newDocumentsSchema.indexedDocument.indices[2].properties[0].$id = 'asc';
|
|
54
|
+
|
|
55
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
56
|
+
|
|
57
|
+
expect(result.isValid()).to.be.false();
|
|
58
|
+
|
|
59
|
+
const error = result.getErrors()[0];
|
|
60
|
+
|
|
61
|
+
expect(error).to.be.an.instanceOf(DataContractInvalidIndexDefinitionUpdateError);
|
|
62
|
+
expect(error.getIndexName()).to.equal(newDocumentsSchema.indexedDocument.indices[2].name);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should return invalid result if non-unique index update failed due old properties used', async () => {
|
|
66
|
+
newDocumentsSchema.indexedDocument.indices[2].properties.push({ firstName: 'asc' });
|
|
67
|
+
|
|
68
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
69
|
+
|
|
70
|
+
expect(result.isValid()).to.be.false();
|
|
71
|
+
|
|
72
|
+
const error = result.getErrors()[0];
|
|
73
|
+
|
|
74
|
+
expect(error).to.be.an.instanceOf(DataContractInvalidIndexDefinitionUpdateError);
|
|
75
|
+
expect(error.getIndexName()).to.equal(newDocumentsSchema.indexedDocument.indices[2].name);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should return invalid result if one of new indices contains old properties in the wrong order', async () => {
|
|
79
|
+
newDocumentsSchema.indexedDocument.indices.push({
|
|
80
|
+
name: 'index_other',
|
|
81
|
+
properties: [
|
|
82
|
+
{ firstName: 'asc' },
|
|
83
|
+
{ $ownerId: 'asc' },
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
88
|
+
|
|
89
|
+
expect(result.isValid()).to.be.false();
|
|
90
|
+
|
|
91
|
+
const error = result.getErrors()[0];
|
|
92
|
+
|
|
93
|
+
expect(error).to.be.an.instanceOf(DataContractHaveNewIndexWithOldPropertiesError);
|
|
94
|
+
expect(error.getIndexName()).to.equal('index_other');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should return invalid result if one of new indices is unique', async () => {
|
|
98
|
+
newDocumentsSchema.indexedDocument.indices.push({
|
|
99
|
+
name: 'index_other',
|
|
100
|
+
properties: [
|
|
101
|
+
{ otherName: 'asc' },
|
|
102
|
+
],
|
|
103
|
+
unique: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
107
|
+
|
|
108
|
+
expect(result.isValid()).to.be.false();
|
|
109
|
+
|
|
110
|
+
const error = result.getErrors()[0];
|
|
111
|
+
|
|
112
|
+
expect(error).to.be.an.instanceOf(DataContractHaveNewUniqueIndexError);
|
|
113
|
+
expect(error.getIndexName()).to.equal('index_other');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should return valid result if indices are not changed', async () => {
|
|
117
|
+
const result = validateIndicesAreBackwardCompatible(oldDocumentsSchema, newDocumentsSchema);
|
|
118
|
+
|
|
119
|
+
expect(result.isValid()).to.be.true();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const validateDataContractUpdateTransitionStateFactory = require('../../../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory');
|
|
2
|
+
const DataContractUpdateTransition = require('../../../../../../../lib/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition');
|
|
3
|
+
|
|
4
|
+
const createStateRepositoryMock = require('../../../../../../../lib/test/mocks/createStateRepositoryMock');
|
|
5
|
+
const getDataContractFixture = require('../../../../../../../lib/test/fixtures/getDataContractFixture');
|
|
6
|
+
|
|
7
|
+
const { expectValidationError } = require('../../../../../../../lib/test/expect/expectError');
|
|
8
|
+
|
|
9
|
+
const ValidationResult = require('../../../../../../../lib/validation/ValidationResult');
|
|
10
|
+
|
|
11
|
+
const DataContractNotPresentError = require('../../../../../../../lib/errors/consensus/basic/document/DataContractNotPresentError');
|
|
12
|
+
const InvalidDataContractVersionError = require('../../../../../../../lib/errors/consensus/basic/dataContract/InvalidDataContractVersionError');
|
|
13
|
+
const StateTransitionExecutionContext = require('../../../../../../../lib/stateTransition/StateTransitionExecutionContext');
|
|
14
|
+
|
|
15
|
+
describe('validateDataContractUpdateTransitionStateFactory', () => {
|
|
16
|
+
let validateDataContractUpdateTransitionState;
|
|
17
|
+
let dataContract;
|
|
18
|
+
let stateTransition;
|
|
19
|
+
let stateRepositoryMock;
|
|
20
|
+
let executionContext;
|
|
21
|
+
|
|
22
|
+
beforeEach(function beforeEach() {
|
|
23
|
+
stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
|
|
24
|
+
|
|
25
|
+
dataContract = getDataContractFixture();
|
|
26
|
+
|
|
27
|
+
const updatedRawDataContract = dataContract.toObject();
|
|
28
|
+
|
|
29
|
+
updatedRawDataContract.version += 1;
|
|
30
|
+
|
|
31
|
+
stateTransition = new DataContractUpdateTransition({
|
|
32
|
+
dataContract: updatedRawDataContract,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
executionContext = new StateTransitionExecutionContext();
|
|
36
|
+
|
|
37
|
+
stateTransition.setExecutionContext(executionContext);
|
|
38
|
+
|
|
39
|
+
stateRepositoryMock.fetchDataContract.resolves(dataContract);
|
|
40
|
+
|
|
41
|
+
validateDataContractUpdateTransitionState = validateDataContractUpdateTransitionStateFactory(
|
|
42
|
+
stateRepositoryMock,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return invalid result if Data Contract with specified contractId was not found', async () => {
|
|
47
|
+
stateRepositoryMock.fetchDataContract.resolves(undefined);
|
|
48
|
+
|
|
49
|
+
const result = await validateDataContractUpdateTransitionState(stateTransition);
|
|
50
|
+
|
|
51
|
+
expectValidationError(result, DataContractNotPresentError);
|
|
52
|
+
|
|
53
|
+
const [error] = result.getErrors();
|
|
54
|
+
|
|
55
|
+
expect(error.getCode()).to.equal(1018);
|
|
56
|
+
expect(Buffer.isBuffer(error.getDataContractId())).to.be.true();
|
|
57
|
+
expect(error.getDataContractId()).to.deep.equal(dataContract.getId().toBuffer());
|
|
58
|
+
|
|
59
|
+
expect(stateRepositoryMock.fetchDataContract).to.be.calledOnceWithExactly(
|
|
60
|
+
dataContract.getId(),
|
|
61
|
+
executionContext,
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should return invalid result if Data Contract version is not larger by 1', async () => {
|
|
66
|
+
dataContract.version -= 1;
|
|
67
|
+
|
|
68
|
+
const result = await validateDataContractUpdateTransitionState(stateTransition);
|
|
69
|
+
|
|
70
|
+
expectValidationError(result, InvalidDataContractVersionError);
|
|
71
|
+
|
|
72
|
+
const [error] = result.getErrors();
|
|
73
|
+
|
|
74
|
+
expect(error.getCode()).to.equal(1050);
|
|
75
|
+
|
|
76
|
+
expect(stateRepositoryMock.fetchDataContract).to.be.calledOnceWithExactly(
|
|
77
|
+
dataContract.getId(),
|
|
78
|
+
executionContext,
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should return valid result', async () => {
|
|
83
|
+
const result = await validateDataContractUpdateTransitionState(stateTransition);
|
|
84
|
+
|
|
85
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
86
|
+
expect(result.isValid()).to.be.true();
|
|
87
|
+
|
|
88
|
+
expect(stateRepositoryMock.fetchDataContract).to.be.calledOnceWithExactly(
|
|
89
|
+
dataContract.getId(),
|
|
90
|
+
executionContext,
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should return valid result on dry run', async () => {
|
|
95
|
+
stateRepositoryMock.fetchDataContract.resolves(undefined);
|
|
96
|
+
|
|
97
|
+
executionContext.enableDryRun();
|
|
98
|
+
|
|
99
|
+
const result = await validateDataContractUpdateTransitionState(stateTransition);
|
|
100
|
+
|
|
101
|
+
executionContext.disableDryRun();
|
|
102
|
+
|
|
103
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
104
|
+
expect(result.isValid()).to.be.true();
|
|
105
|
+
|
|
106
|
+
expect(stateRepositoryMock.fetchDataContract).to.be.calledOnceWithExactly(
|
|
107
|
+
dataContract.getId(),
|
|
108
|
+
executionContext,
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const validateDataContractMaxDepthFactory = require('../../../../lib/dataContract/validation/validateDataContractMaxDepthFactory');
|
|
2
|
+
const ValidationResult = require('../../../../lib/validation/ValidationResult');
|
|
3
|
+
const { expectValidationError } = require('../../../../lib/test/expect/expectError');
|
|
4
|
+
const DataContractMaxDepthExceedError = require('../../../../lib/errors/consensus/basic/dataContract/DataContractMaxDepthExceedError');
|
|
5
|
+
const generateDeepJson = require('../../../../lib/test/utils/generateDeepJson');
|
|
6
|
+
const InvalidJsonSchemaRefError = require('../../../../lib/errors/consensus/basic/dataContract/InvalidJsonSchemaRefError');
|
|
7
|
+
|
|
8
|
+
describe('validateDataContractMaxDepthFactory', () => {
|
|
9
|
+
let refParserMock;
|
|
10
|
+
let validateDataContractMaxDepth;
|
|
11
|
+
let dataContractFixture;
|
|
12
|
+
|
|
13
|
+
beforeEach(function beforeEach() {
|
|
14
|
+
dataContractFixture = {};
|
|
15
|
+
|
|
16
|
+
refParserMock = {
|
|
17
|
+
dereference: this.sinonSandbox.stub(),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
validateDataContractMaxDepth = validateDataContractMaxDepthFactory(refParserMock);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should throw error if depth > MAX_DEPTH', async () => {
|
|
24
|
+
dataContractFixture = generateDeepJson(DataContractMaxDepthExceedError.MAX_DEPTH + 1);
|
|
25
|
+
|
|
26
|
+
refParserMock.dereference.resolves(dataContractFixture);
|
|
27
|
+
|
|
28
|
+
const result = await validateDataContractMaxDepth(dataContractFixture);
|
|
29
|
+
|
|
30
|
+
expectValidationError(result);
|
|
31
|
+
|
|
32
|
+
const [error] = result.getErrors();
|
|
33
|
+
|
|
34
|
+
expect(error).to.be.an.instanceOf(DataContractMaxDepthExceedError);
|
|
35
|
+
expect(error.getCode()).to.equal(1007);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return valid result if depth = MAX_DEPTH', async () => {
|
|
39
|
+
dataContractFixture = generateDeepJson(DataContractMaxDepthExceedError.MAX_DEPTH);
|
|
40
|
+
|
|
41
|
+
refParserMock.dereference.resolves(dataContractFixture);
|
|
42
|
+
|
|
43
|
+
const result = await validateDataContractMaxDepth(dataContractFixture);
|
|
44
|
+
|
|
45
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
46
|
+
expect(result.isValid()).to.be.true();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should throw error if contract contains array with depth > MAX_DEPTH', async () => {
|
|
50
|
+
const deepJson = generateDeepJson(DataContractMaxDepthExceedError.MAX_DEPTH + 1);
|
|
51
|
+
|
|
52
|
+
dataContractFixture = {
|
|
53
|
+
array: [
|
|
54
|
+
0, deepJson,
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
refParserMock.dereference.resolves(dataContractFixture);
|
|
59
|
+
|
|
60
|
+
const result = await validateDataContractMaxDepth(dataContractFixture);
|
|
61
|
+
|
|
62
|
+
expectValidationError(result);
|
|
63
|
+
|
|
64
|
+
const [error] = result.getErrors();
|
|
65
|
+
|
|
66
|
+
expect(error).to.be.an.instanceOf(DataContractMaxDepthExceedError);
|
|
67
|
+
expect(error.getCode()).to.equal(1007);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should return error if refParser throws an error', async () => {
|
|
71
|
+
const refParserError = new Error('refParser error');
|
|
72
|
+
|
|
73
|
+
refParserMock.dereference.throws(refParserError);
|
|
74
|
+
|
|
75
|
+
const result = await validateDataContractMaxDepth(dataContractFixture);
|
|
76
|
+
|
|
77
|
+
expectValidationError(result);
|
|
78
|
+
|
|
79
|
+
const [error] = result.getErrors();
|
|
80
|
+
|
|
81
|
+
expect(error).to.be.an.instanceOf(InvalidJsonSchemaRefError);
|
|
82
|
+
expect(error.message).to.equal(`Invalid JSON Schema $ref: ${refParserError.message}`);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should return valid result', async () => {
|
|
86
|
+
refParserMock.dereference.resolves(dataContractFixture);
|
|
87
|
+
|
|
88
|
+
const result = await validateDataContractMaxDepth(dataContractFixture);
|
|
89
|
+
|
|
90
|
+
expect(result).to.be.an.instanceOf(ValidationResult);
|
|
91
|
+
expect(result.isValid()).to.be.true();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const { getRE2Class } = require('@dashevo/wasm-re2');
|
|
2
|
+
|
|
3
|
+
const validateDataContractPatternsFactory = require('../../../../lib/dataContract/validation/validateDataContractPatternsFactory');
|
|
4
|
+
const { expectValidationError } = require(
|
|
5
|
+
'../../../../lib/test/expect/expectError',
|
|
6
|
+
);
|
|
7
|
+
const IncompatibleRe2PatternError = require('../../../../lib/errors/consensus/basic/dataContract/IncompatibleRe2PatternError');
|
|
8
|
+
|
|
9
|
+
describe('validateDataContractPatternsFactory', () => {
|
|
10
|
+
let validateDataContractPatterns;
|
|
11
|
+
let RE2;
|
|
12
|
+
|
|
13
|
+
before(async () => {
|
|
14
|
+
RE2 = await getRE2Class();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
validateDataContractPatterns = validateDataContractPatternsFactory(RE2);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return valid result', () => {
|
|
22
|
+
const schema = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
foo: { type: 'integer' },
|
|
26
|
+
bar: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
pattern: '([a-z]+)+$',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ['foo'],
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const result = validateDataContractPatterns(schema);
|
|
36
|
+
|
|
37
|
+
expect(result.isValid()).to.be.true();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should return invalid result on incompatible pattern', () => {
|
|
41
|
+
const schema = {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
foo: { type: 'integer' },
|
|
45
|
+
bar: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
pattern: '^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ['foo'],
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const result = validateDataContractPatterns(schema);
|
|
55
|
+
|
|
56
|
+
expectValidationError(result, IncompatibleRe2PatternError);
|
|
57
|
+
const [error] = result.getErrors();
|
|
58
|
+
|
|
59
|
+
expect(error.getCode()).to.equal(1009);
|
|
60
|
+
expect(error.getPattern()).to.equal('^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$');
|
|
61
|
+
expect(error.getPath()).to.equal('/properties/bar');
|
|
62
|
+
expect(error.getPatternError()).to.be.instanceOf(Error);
|
|
63
|
+
});
|
|
64
|
+
});
|