@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,37 @@
|
|
|
1
|
+
const Metadata = require('../../lib/Metadata');
|
|
2
|
+
|
|
3
|
+
describe('Metadata', () => {
|
|
4
|
+
describe('#constructor', () => {
|
|
5
|
+
it('should set height and core chain-locked height', () => {
|
|
6
|
+
const result = new Metadata({
|
|
7
|
+
blockHeight: 42,
|
|
8
|
+
coreChainLockedHeight: 1,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
expect(result.blockHeight).to.equal(42);
|
|
12
|
+
expect(result.coreChainLockedHeight).to.equal(1);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('#getBlockHeight', () => {
|
|
17
|
+
it('should get block height', () => {
|
|
18
|
+
const result = new Metadata({
|
|
19
|
+
blockHeight: 42,
|
|
20
|
+
coreChainLockedHeight: 1,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(result.getBlockHeight()).to.equal(42);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('#getCoreChainLockedHeight', () => {
|
|
28
|
+
it('should get core chain-locked height', () => {
|
|
29
|
+
const result = new Metadata({
|
|
30
|
+
blockHeight: 1,
|
|
31
|
+
coreChainLockedHeight: 42,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(result.getCoreChainLockedHeight()).to.equal(42);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
const bs58 = require('bs58');
|
|
2
|
+
|
|
3
|
+
const Identifier = require('../../../lib/identifier/Identifier');
|
|
4
|
+
|
|
5
|
+
const InvalidDocumentTypeError = require('../../../lib/errors/InvalidDocumentTypeError');
|
|
6
|
+
|
|
7
|
+
const generateRandomIdentifier = require('../../../lib/test/utils/generateRandomIdentifier');
|
|
8
|
+
const Metadata = require('../../../lib/Metadata');
|
|
9
|
+
const DataContract = require('../../../lib/dataContract/DataContract');
|
|
10
|
+
|
|
11
|
+
const hash = require('../../../lib/util/hash');
|
|
12
|
+
const serializer = require('../../../lib/util/serializer');
|
|
13
|
+
const getBinaryPropertiesFromSchema = require('../../../lib/dataContract/getBinaryPropertiesFromSchema');
|
|
14
|
+
|
|
15
|
+
describe('DataContract', () => {
|
|
16
|
+
let hashMock;
|
|
17
|
+
let encodeMock;
|
|
18
|
+
let documentType;
|
|
19
|
+
let documentSchema;
|
|
20
|
+
let documents;
|
|
21
|
+
let dataContract;
|
|
22
|
+
let ownerId;
|
|
23
|
+
let entropy;
|
|
24
|
+
let contractId;
|
|
25
|
+
let getBinaryPropertiesFromSchemaMock;
|
|
26
|
+
let metadataFixture;
|
|
27
|
+
|
|
28
|
+
beforeEach(function beforeEach() {
|
|
29
|
+
encodeMock = this.sinonSandbox.stub(serializer, 'encode');
|
|
30
|
+
hashMock = this.sinonSandbox.stub(hash, 'hash');
|
|
31
|
+
getBinaryPropertiesFromSchemaMock = this.sinonSandbox.stub(getBinaryPropertiesFromSchema, 'getBinaryPropertiesFromSchema');
|
|
32
|
+
|
|
33
|
+
documentType = 'niceDocument';
|
|
34
|
+
|
|
35
|
+
documentSchema = {
|
|
36
|
+
properties: {
|
|
37
|
+
nice: {
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
documents = {
|
|
44
|
+
[documentType]: documentSchema,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
getBinaryPropertiesFromSchemaMock.withArgs(documentSchema)
|
|
48
|
+
.returns({
|
|
49
|
+
'firstLevel.secondLevel': {
|
|
50
|
+
type: 'array',
|
|
51
|
+
byteArray: true,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
ownerId = generateRandomIdentifier();
|
|
56
|
+
entropy = Buffer.alloc(32);
|
|
57
|
+
contractId = generateRandomIdentifier();
|
|
58
|
+
|
|
59
|
+
dataContract = new DataContract({
|
|
60
|
+
$schema: DataContract.DEFAULTS.SCHEMA,
|
|
61
|
+
$id: contractId,
|
|
62
|
+
version: 1,
|
|
63
|
+
ownerId,
|
|
64
|
+
documents,
|
|
65
|
+
$defs: {},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
metadataFixture = new Metadata(42, 0);
|
|
69
|
+
|
|
70
|
+
dataContract.setMetadata(metadataFixture);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
encodeMock.restore();
|
|
75
|
+
hashMock.restore();
|
|
76
|
+
getBinaryPropertiesFromSchemaMock.restore();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('constructor', () => {
|
|
80
|
+
it('should create new DataContract', () => {
|
|
81
|
+
const id = generateRandomIdentifier();
|
|
82
|
+
|
|
83
|
+
dataContract = new DataContract({
|
|
84
|
+
$schema: DataContract.DEFAULTS.SCHEMA,
|
|
85
|
+
$id: id,
|
|
86
|
+
ownerId,
|
|
87
|
+
documents,
|
|
88
|
+
$defs: {},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(dataContract.id).to.deep.equal(id);
|
|
92
|
+
expect(dataContract.ownerId).to.deep.equal(ownerId);
|
|
93
|
+
expect(dataContract.schema).to.equal(DataContract.DEFAULTS.SCHEMA);
|
|
94
|
+
expect(dataContract.documents).to.equal(documents);
|
|
95
|
+
expect(dataContract.$defs).to.deep.equal({});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('#getId', () => {
|
|
100
|
+
it('should return DataContract Identifier', () => {
|
|
101
|
+
const result = dataContract.getId();
|
|
102
|
+
|
|
103
|
+
expect(result).to.deep.equal(contractId);
|
|
104
|
+
expect(result).to.be.instanceof(Identifier);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('#getJsonSchemaId', () => {
|
|
109
|
+
it('should return JSON Schema ID', () => {
|
|
110
|
+
const result = dataContract.getJsonSchemaId();
|
|
111
|
+
|
|
112
|
+
expect(result).to.equal(dataContract.getId().toString());
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('#setJsonMetaSchema', () => {
|
|
117
|
+
it('should set meta schema', () => {
|
|
118
|
+
const metaSchema = 'http://test.com/schema';
|
|
119
|
+
|
|
120
|
+
const result = dataContract.setJsonMetaSchema(metaSchema);
|
|
121
|
+
|
|
122
|
+
expect(result).to.equal(dataContract);
|
|
123
|
+
expect(dataContract.schema).to.equal(metaSchema);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('#getJsonMetaSchema', () => {
|
|
128
|
+
it('should return meta schema', () => {
|
|
129
|
+
const result = dataContract.getJsonMetaSchema();
|
|
130
|
+
|
|
131
|
+
expect(result).to.equal(dataContract.schema);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('#setDocuments', () => {
|
|
136
|
+
it('should set Documents definition', () => {
|
|
137
|
+
const anotherDocuments = {
|
|
138
|
+
anotherDocument: {
|
|
139
|
+
properties: {
|
|
140
|
+
name: { type: 'string' },
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const result = dataContract.setDocuments(anotherDocuments);
|
|
146
|
+
|
|
147
|
+
expect(result).to.equal(dataContract);
|
|
148
|
+
expect(dataContract.documents).to.equal(anotherDocuments);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('#getDocuments', () => {
|
|
153
|
+
it('should return Documents definition', () => {
|
|
154
|
+
const result = dataContract.getDocuments();
|
|
155
|
+
|
|
156
|
+
expect(result).to.equal(dataContract.documents);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('#isDocumentDefined', () => {
|
|
161
|
+
it('should return true if Document schema is defined', () => {
|
|
162
|
+
const result = dataContract.isDocumentDefined('niceDocument');
|
|
163
|
+
|
|
164
|
+
expect(result).to.equal(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should return false if Document schema is not defined', () => {
|
|
168
|
+
const result = dataContract.isDocumentDefined('undefinedDocument');
|
|
169
|
+
|
|
170
|
+
expect(result).to.equal(false);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('#setDocumentSchema', () => {
|
|
175
|
+
it('should set Document schema', () => {
|
|
176
|
+
const anotherType = 'prettyDocument';
|
|
177
|
+
const anotherDefinition = {
|
|
178
|
+
properties: {
|
|
179
|
+
name: { type: 'string' },
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const result = dataContract.setDocumentSchema(anotherType, anotherDefinition);
|
|
184
|
+
|
|
185
|
+
expect(result).to.equal(dataContract);
|
|
186
|
+
|
|
187
|
+
expect(dataContract.documents).to.have.property(anotherType);
|
|
188
|
+
expect(dataContract.documents[anotherType]).to.equal(anotherDefinition);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('#getDocumentSchema', () => {
|
|
193
|
+
it('should throw error if Document is not defined', () => {
|
|
194
|
+
let error;
|
|
195
|
+
try {
|
|
196
|
+
dataContract.getDocumentSchema('undefinedObject');
|
|
197
|
+
} catch (e) {
|
|
198
|
+
error = e;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
expect(error).to.be.an.instanceOf(InvalidDocumentTypeError);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should return Document Schema', () => {
|
|
205
|
+
const result = dataContract.getDocumentSchema(documentType);
|
|
206
|
+
|
|
207
|
+
expect(result).to.equal(documentSchema);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe('#getDocumentSchemaRef', () => {
|
|
212
|
+
it('should throw error if Document is not defined', () => {
|
|
213
|
+
let error;
|
|
214
|
+
try {
|
|
215
|
+
dataContract.getDocumentSchemaRef('undefinedObject');
|
|
216
|
+
} catch (e) {
|
|
217
|
+
error = e;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
expect(error).to.be.an.instanceOf(InvalidDocumentTypeError);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should return schema with $ref to Document schema', () => {
|
|
224
|
+
const hashed = Buffer.from(ownerId + entropy);
|
|
225
|
+
hashMock.returns(hashed);
|
|
226
|
+
|
|
227
|
+
const result = dataContract.getDocumentSchemaRef(documentType);
|
|
228
|
+
|
|
229
|
+
expect(result).to.deep.equal({
|
|
230
|
+
$ref: `${dataContract.getJsonSchemaId()}#/documents/niceDocument`,
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('#setDefinitions', () => {
|
|
236
|
+
it('should set $defs', () => {
|
|
237
|
+
const $defs = {};
|
|
238
|
+
|
|
239
|
+
const result = dataContract.setDefinitions($defs);
|
|
240
|
+
|
|
241
|
+
expect(result).to.equal(dataContract);
|
|
242
|
+
expect(dataContract.$defs).to.equal($defs);
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('#getDefinitions', () => {
|
|
247
|
+
it('should return $defs', () => {
|
|
248
|
+
const result = dataContract.getDefinitions();
|
|
249
|
+
|
|
250
|
+
expect(result).to.equal(dataContract.$defs);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
describe('#toJSON', () => {
|
|
255
|
+
it('should return DataContract as plain object', () => {
|
|
256
|
+
const result = dataContract.toJSON();
|
|
257
|
+
|
|
258
|
+
expect(result).to.deep.equal({
|
|
259
|
+
protocolVersion: dataContract.getProtocolVersion(),
|
|
260
|
+
$id: bs58.encode(contractId),
|
|
261
|
+
$schema: DataContract.DEFAULTS.SCHEMA,
|
|
262
|
+
version: 1,
|
|
263
|
+
ownerId: bs58.encode(ownerId),
|
|
264
|
+
documents,
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should return plain object with "$defs" if present', () => {
|
|
269
|
+
const $defs = {
|
|
270
|
+
subSchema: { type: 'object' },
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
dataContract.setDefinitions($defs);
|
|
274
|
+
|
|
275
|
+
const result = dataContract.toJSON();
|
|
276
|
+
|
|
277
|
+
expect(result).to.deep.equal({
|
|
278
|
+
protocolVersion: dataContract.getProtocolVersion(),
|
|
279
|
+
$schema: DataContract.DEFAULTS.SCHEMA,
|
|
280
|
+
$id: bs58.encode(contractId),
|
|
281
|
+
version: 1,
|
|
282
|
+
ownerId: bs58.encode(ownerId),
|
|
283
|
+
documents,
|
|
284
|
+
$defs,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
describe('#toBuffer', () => {
|
|
290
|
+
it('should return DataContract as a Buffer', () => {
|
|
291
|
+
const serializedDataContract = Buffer.from('123');
|
|
292
|
+
|
|
293
|
+
encodeMock.returns(serializedDataContract);
|
|
294
|
+
|
|
295
|
+
const result = dataContract.toBuffer();
|
|
296
|
+
|
|
297
|
+
const dataContractToEncode = dataContract.toObject();
|
|
298
|
+
delete dataContractToEncode.protocolVersion;
|
|
299
|
+
|
|
300
|
+
const protocolVersionUInt32 = Buffer.alloc(4);
|
|
301
|
+
protocolVersionUInt32.writeUInt32LE(dataContract.getProtocolVersion(), 0);
|
|
302
|
+
|
|
303
|
+
expect(encodeMock).to.have.been.calledOnceWith(dataContractToEncode);
|
|
304
|
+
expect(result).to.deep.equal(Buffer.concat([protocolVersionUInt32, serializedDataContract]));
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe('#hash', () => {
|
|
309
|
+
let toBufferMock;
|
|
310
|
+
|
|
311
|
+
beforeEach(function beforeEach() {
|
|
312
|
+
toBufferMock = this.sinonSandbox.stub(DataContract.prototype, 'toBuffer');
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
afterEach(() => {
|
|
316
|
+
toBufferMock.restore();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('should return DataContract hash', () => {
|
|
320
|
+
const serializedDataContract = '123';
|
|
321
|
+
const hashedDocument = '456';
|
|
322
|
+
|
|
323
|
+
toBufferMock.returns(serializedDataContract);
|
|
324
|
+
|
|
325
|
+
hashMock.returns(hashedDocument);
|
|
326
|
+
|
|
327
|
+
const result = dataContract.hash();
|
|
328
|
+
|
|
329
|
+
expect(result).to.equal(hashedDocument);
|
|
330
|
+
|
|
331
|
+
expect(toBufferMock).to.have.been.calledOnce();
|
|
332
|
+
|
|
333
|
+
expect(hashMock).to.have.been.calledOnceWith(serializedDataContract);
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe('#setEntropy', () => {
|
|
338
|
+
it('should set entropy', () => {
|
|
339
|
+
const result = dataContract.setEntropy(entropy);
|
|
340
|
+
|
|
341
|
+
expect(result).to.equal(dataContract);
|
|
342
|
+
expect(dataContract.entropy).to.deep.equal(entropy);
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
describe('#getEntropy', () => {
|
|
347
|
+
it('should return entropy', () => {
|
|
348
|
+
dataContract.entropy = entropy;
|
|
349
|
+
|
|
350
|
+
const result = dataContract.getEntropy();
|
|
351
|
+
|
|
352
|
+
expect(result).to.equal(dataContract.entropy);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
describe('#getBinaryProperties', () => {
|
|
357
|
+
it('should return flat map of properties with `contentEncoding` keywords', () => {
|
|
358
|
+
const result = dataContract.getBinaryProperties(documentType);
|
|
359
|
+
expect(result).to.deep.equal({
|
|
360
|
+
'firstLevel.secondLevel': {
|
|
361
|
+
type: 'array',
|
|
362
|
+
byteArray: true,
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should return cached flat map of properties with `contentEncoding` keywords', () => {
|
|
368
|
+
dataContract.getBinaryProperties(documentType);
|
|
369
|
+
|
|
370
|
+
const result = dataContract.getBinaryProperties(documentType);
|
|
371
|
+
|
|
372
|
+
expect(result).to.deep.equal({
|
|
373
|
+
'firstLevel.secondLevel': {
|
|
374
|
+
type: 'array',
|
|
375
|
+
byteArray: true,
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
expect(getBinaryPropertiesFromSchemaMock).to.have.been.calledOnceWith(documentSchema);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('should throw an error if document type is not found', () => {
|
|
383
|
+
try {
|
|
384
|
+
dataContract.getBinaryProperties('unknown');
|
|
385
|
+
expect.fail('Error was not thrown');
|
|
386
|
+
} catch (e) {
|
|
387
|
+
expect(e).to.be.an.instanceOf(InvalidDocumentTypeError);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
describe('#setMetadata', () => {
|
|
393
|
+
it('should set metadata', () => {
|
|
394
|
+
const otherMetadata = new Metadata(43, 1);
|
|
395
|
+
|
|
396
|
+
dataContract.setMetadata(otherMetadata);
|
|
397
|
+
|
|
398
|
+
expect(dataContract.metadata).to.deep.equal(otherMetadata);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
describe('#getMetadata', () => {
|
|
403
|
+
it('should get metadata', () => {
|
|
404
|
+
expect(dataContract.getMetadata()).to.deep.equal(metadataFixture);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture');
|
|
2
|
+
|
|
3
|
+
const protocolVersion = require('../../../lib/version/protocolVersion');
|
|
4
|
+
|
|
5
|
+
const DataContractCreateTransition = require('../../../lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition');
|
|
6
|
+
|
|
7
|
+
const ValidationResult = require('../../../lib/validation/ValidationResult');
|
|
8
|
+
|
|
9
|
+
const InvalidDataContractError = require('../../../lib/dataContract/errors/InvalidDataContractError');
|
|
10
|
+
const SerializedObjectParsingError = require('../../../lib/errors/consensus/basic/decode/SerializedObjectParsingError');
|
|
11
|
+
const createDPPMock = require('../../../lib/test/mocks/createDPPMock');
|
|
12
|
+
const SomeConsensusError = require('../../../lib/test/mocks/SomeConsensusError');
|
|
13
|
+
|
|
14
|
+
const DataContractFactory = require('../../../lib/dataContract/DataContractFactory');
|
|
15
|
+
const entropyGenerator = require('../../../lib/util/entropyGenerator');
|
|
16
|
+
|
|
17
|
+
describe('DataContractFactory', () => {
|
|
18
|
+
let decodeProtocolEntityMock;
|
|
19
|
+
let validateDataContractMock;
|
|
20
|
+
let factory;
|
|
21
|
+
let dataContract;
|
|
22
|
+
let rawDataContract;
|
|
23
|
+
let generateEntropyMock;
|
|
24
|
+
let dppMock;
|
|
25
|
+
|
|
26
|
+
beforeEach(function beforeEach() {
|
|
27
|
+
dataContract = getDataContractFixture();
|
|
28
|
+
dppMock = createDPPMock();
|
|
29
|
+
|
|
30
|
+
rawDataContract = dataContract.toObject();
|
|
31
|
+
|
|
32
|
+
decodeProtocolEntityMock = this.sinonSandbox.stub();
|
|
33
|
+
validateDataContractMock = this.sinonSandbox.stub();
|
|
34
|
+
generateEntropyMock = this.sinonSandbox.stub(entropyGenerator, 'generate');
|
|
35
|
+
|
|
36
|
+
factory = new DataContractFactory(
|
|
37
|
+
dppMock,
|
|
38
|
+
validateDataContractMock,
|
|
39
|
+
decodeProtocolEntityMock,
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
generateEntropyMock.restore();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('create', () => {
|
|
48
|
+
it('should return new Data Contract with specified name and documents definition', () => {
|
|
49
|
+
generateEntropyMock.returns(dataContract.getEntropy());
|
|
50
|
+
const result = factory.create(
|
|
51
|
+
dataContract.ownerId.toBuffer(),
|
|
52
|
+
rawDataContract.documents,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
expect(result).excluding('$defs').to.deep.equal(dataContract);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('createFromObject', () => {
|
|
60
|
+
it('should return new Data Contract with data from passed object', async () => {
|
|
61
|
+
validateDataContractMock.returns(new ValidationResult());
|
|
62
|
+
|
|
63
|
+
const result = await factory.createFromObject(rawDataContract);
|
|
64
|
+
|
|
65
|
+
expect(result.toObject()).excluding('entropy').to.deep.equal(rawDataContract);
|
|
66
|
+
|
|
67
|
+
expect(validateDataContractMock).to.have.been.calledOnceWith(rawDataContract);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should return new Data Contract without validation if "skipValidation" option is passed', async () => {
|
|
71
|
+
const result = await factory.createFromObject(rawDataContract, { skipValidation: true });
|
|
72
|
+
|
|
73
|
+
expect(result.toObject()).excluding('entropy').to.deep.equal(rawDataContract);
|
|
74
|
+
|
|
75
|
+
expect(validateDataContractMock).to.have.not.been.called();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should throw an error if passed object is not valid', async () => {
|
|
79
|
+
const validationError = new SomeConsensusError('test');
|
|
80
|
+
|
|
81
|
+
validateDataContractMock.returns(new ValidationResult([validationError]));
|
|
82
|
+
|
|
83
|
+
let error;
|
|
84
|
+
try {
|
|
85
|
+
await factory.createFromObject(rawDataContract);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
error = e;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
expect(error).to.be.an.instanceOf(InvalidDataContractError);
|
|
91
|
+
expect(error.getRawDataContract()).to.equal(rawDataContract);
|
|
92
|
+
|
|
93
|
+
expect(error.getErrors()).to.have.length(1);
|
|
94
|
+
|
|
95
|
+
const [consensusError] = error.getErrors();
|
|
96
|
+
|
|
97
|
+
expect(consensusError).to.equal(validationError);
|
|
98
|
+
|
|
99
|
+
expect(validateDataContractMock).to.have.been.calledOnceWith(rawDataContract);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('createFromBuffer', () => {
|
|
104
|
+
let serializedDataContract;
|
|
105
|
+
|
|
106
|
+
beforeEach(function beforeEach() {
|
|
107
|
+
this.sinonSandbox.stub(factory, 'createFromObject');
|
|
108
|
+
|
|
109
|
+
serializedDataContract = dataContract.toBuffer();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
afterEach(() => {
|
|
113
|
+
factory.createFromObject.restore();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should return new Data Contract from serialized contract', async () => {
|
|
117
|
+
decodeProtocolEntityMock.returns([rawDataContract.protocolVersion, rawDataContract]);
|
|
118
|
+
|
|
119
|
+
factory.createFromObject.returns(dataContract);
|
|
120
|
+
|
|
121
|
+
const result = await factory.createFromBuffer(serializedDataContract);
|
|
122
|
+
|
|
123
|
+
expect(result).to.equal(dataContract);
|
|
124
|
+
|
|
125
|
+
expect(factory.createFromObject).to.have.been.calledOnceWith(rawDataContract);
|
|
126
|
+
|
|
127
|
+
expect(decodeProtocolEntityMock).to.have.been.calledOnceWithExactly(
|
|
128
|
+
serializedDataContract,
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should throw InvalidDataContractError if the decoding fails with consensus error', async () => {
|
|
133
|
+
const parsingError = new SerializedObjectParsingError(
|
|
134
|
+
serializedDataContract,
|
|
135
|
+
new Error(),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
decodeProtocolEntityMock.throws(parsingError);
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await factory.createFromBuffer(serializedDataContract);
|
|
142
|
+
|
|
143
|
+
expect.fail('should throw InvalidDataContractError');
|
|
144
|
+
} catch (e) {
|
|
145
|
+
expect(e).to.be.an.instanceOf(InvalidDataContractError);
|
|
146
|
+
|
|
147
|
+
const [innerError] = e.getErrors();
|
|
148
|
+
expect(innerError).to.equal(parsingError);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should throw an error if decoding fails with any other error', async () => {
|
|
153
|
+
const parsingError = new Error('Something failed during parsing');
|
|
154
|
+
|
|
155
|
+
decodeProtocolEntityMock.throws(parsingError);
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
await factory.createFromBuffer(serializedDataContract);
|
|
159
|
+
|
|
160
|
+
expect.fail('should throw an error');
|
|
161
|
+
} catch (e) {
|
|
162
|
+
expect(e).to.equal(parsingError);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('createDataContractCreateTransition', () => {
|
|
168
|
+
it('should return new DataContractCreateTransition with passed DataContract', () => {
|
|
169
|
+
const result = factory.createDataContractCreateTransition(dataContract);
|
|
170
|
+
|
|
171
|
+
expect(result).to.be.an.instanceOf(DataContractCreateTransition);
|
|
172
|
+
|
|
173
|
+
expect(result.getProtocolVersion()).to.equal(protocolVersion.latestVersion);
|
|
174
|
+
expect(result.getEntropy()).to.deep.equal(dataContract.getEntropy());
|
|
175
|
+
expect(result.getDataContract().toObject()).to.deep.equal(dataContract.toObject());
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const DataContract = require('../../../lib/dataContract/DataContract');
|
|
2
|
+
|
|
3
|
+
const generateRandomIdentifier = require('../../../lib/test/utils/generateRandomIdentifier');
|
|
4
|
+
|
|
5
|
+
describe('createDataContract', () => {
|
|
6
|
+
let rawDataContract;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
rawDataContract = {
|
|
10
|
+
$id: generateRandomIdentifier().toBuffer(),
|
|
11
|
+
ownerId: generateRandomIdentifier().toBuffer(),
|
|
12
|
+
contractId: generateRandomIdentifier().toBuffer(),
|
|
13
|
+
documents: {
|
|
14
|
+
niceDocument: {
|
|
15
|
+
name: { type: 'string' },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return new DataContract with "dataContractId" and documents', () => {
|
|
22
|
+
const dataContract = new DataContract(rawDataContract);
|
|
23
|
+
|
|
24
|
+
expect(dataContract).to.be.an.instanceOf(DataContract);
|
|
25
|
+
|
|
26
|
+
expect(dataContract.getOwnerId()).to.deep.equal(rawDataContract.ownerId);
|
|
27
|
+
expect(dataContract.getDocuments()).to.equal(rawDataContract.documents);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return new DataContract with "$schema" if present', () => {
|
|
31
|
+
rawDataContract.$schema = 'http://test.com/schema';
|
|
32
|
+
|
|
33
|
+
const dataContract = new DataContract(rawDataContract);
|
|
34
|
+
|
|
35
|
+
expect(dataContract).to.be.an.instanceOf(DataContract);
|
|
36
|
+
|
|
37
|
+
expect(dataContract.getJsonMetaSchema()).to.equal(rawDataContract.$schema);
|
|
38
|
+
|
|
39
|
+
expect(dataContract.getOwnerId()).to.deep.equal(rawDataContract.ownerId);
|
|
40
|
+
expect(dataContract.getDocuments()).to.equal(rawDataContract.documents);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return new DataContract with "$defs" if present', () => {
|
|
44
|
+
rawDataContract.$defs = {
|
|
45
|
+
subSchema: { type: 'object' },
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const dataContract = new DataContract(rawDataContract);
|
|
49
|
+
|
|
50
|
+
expect(dataContract).to.be.an.instanceOf(DataContract);
|
|
51
|
+
|
|
52
|
+
expect(dataContract.getDefinitions()).to.equal(rawDataContract.$defs);
|
|
53
|
+
|
|
54
|
+
expect(dataContract.getOwnerId()).to.deep.equal(rawDataContract.ownerId);
|
|
55
|
+
expect(dataContract.getDocuments()).to.equal(rawDataContract.documents);
|
|
56
|
+
});
|
|
57
|
+
});
|