@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.
Files changed (110) hide show
  1. package/.babelrc +5 -0
  2. package/.editorconfig +13 -0
  3. package/.eslintignore +1 -0
  4. package/.eslintrc +15 -0
  5. package/.mocharc.yml +4 -0
  6. package/CHANGELOG.md +397 -0
  7. package/LICENSE +20 -0
  8. package/README.md +37 -0
  9. package/karma.conf.js +53 -0
  10. package/package.json +107 -0
  11. package/test/.eslintrc +12 -0
  12. package/test/integration/DashPlatformProtocol.spec.js +53 -0
  13. package/test/integration/ajv/keywords/byteArray/addByteArrayKeyword.spec.js +148 -0
  14. package/test/integration/dataContract/DataContractFacade.spec.js +84 -0
  15. package/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +357 -0
  16. package/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +444 -0
  17. package/test/integration/dataContract/validation/validateDataContractFactory.spec.js +2191 -0
  18. package/test/integration/document/Document.spec.js +90 -0
  19. package/test/integration/document/DocumentFacade.spec.js +155 -0
  20. package/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js +83 -0
  21. package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +1146 -0
  22. package/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +294 -0
  23. package/test/integration/document/validation/validateDocumentFactory.spec.js +447 -0
  24. package/test/integration/error/consensus/createConsensusError.spec.js +21 -0
  25. package/test/integration/identity/IdentityFacade.spec.js +187 -0
  26. package/test/integration/identity/stateTransition/IdentityCreateTransition/validation/basic/validateIdentityCreateTransitionBasicFactory.spec.js +422 -0
  27. package/test/integration/identity/stateTransition/IdentityTopUpTransition/validation/basic/validateIdentityTopUpTransitionBasicFactory.spec.js +361 -0
  28. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js +595 -0
  29. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +299 -0
  30. package/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validatePublicKeysState.spec.js +66 -0
  31. package/test/integration/identity/stateTransition/assetLockProof/chain/validateChainAssetLockProofStructureFactory.spec.js +415 -0
  32. package/test/integration/identity/stateTransition/assetLockProof/fetchAssetLockTransactionOutputFactory.spec.js +134 -0
  33. package/test/integration/identity/stateTransition/assetLockProof/instant/validateInstantAssetLockProofStructureFactory.spec.js +401 -0
  34. package/test/integration/identity/stateTransition/assetLockProof/validateAssetLockTransactionFactory.spec.js +205 -0
  35. package/test/integration/identity/stateTransition/validatePublicKeySignaturesFactory.spec.js +127 -0
  36. package/test/integration/identity/validation/validateIdentityFactory.spec.js +370 -0
  37. package/test/integration/identity/validation/validatePublicKeysFactory.spec.js +497 -0
  38. package/test/integration/stateTransition/AbstractStateTransitionIdentitySigned.spec.js +507 -0
  39. package/test/integration/stateTransition/StateTransitionFacade.spec.js +418 -0
  40. package/test/integration/stateTransition/calculateStateTransitionFee.spec.js +35 -0
  41. package/test/integration/util/generateEntropy.spec.js +17 -0
  42. package/test/integration/util/serializer.spec.js +24 -0
  43. package/test/unit/DashPlatformProtocol.spec.js +79 -0
  44. package/test/unit/Identifier.spec.js +123 -0
  45. package/test/unit/Metadata.spec.js +37 -0
  46. package/test/unit/dataContract/DataContract.spec.js +407 -0
  47. package/test/unit/dataContract/DataContractFactory.spec.js +178 -0
  48. package/test/unit/dataContract/createDataContract.spec.js +57 -0
  49. package/test/unit/dataContract/errors/InvalidDataContractError.spec.js +46 -0
  50. package/test/unit/dataContract/generateDataContractId.spec.js +19 -0
  51. package/test/unit/dataContract/getBinaryPropertiesFromSchema.spec.js +103 -0
  52. package/test/unit/dataContract/getPropertyDefinitionByPath.spec.js +84 -0
  53. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition.spec.js +160 -0
  54. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/applyDataContractCreateTransitionFactory.spec.js +48 -0
  55. package/test/unit/dataContract/stateTransition/DataContractCreateTransition/validation/state/validateDataContractCreateTransitionStateFactory.spec.js +85 -0
  56. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/DataContractUpdateTransition.spec.js +158 -0
  57. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/applyDataContractUpdateTransitionFactory.spec.js +47 -0
  58. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateIndicesAreBackwardCompatible.spec.js +121 -0
  59. package/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +111 -0
  60. package/test/unit/dataContract/validation/validateDataContractMaxDepthFactory.spec.js +93 -0
  61. package/test/unit/dataContract/validation/validateDataContractPatternsFactory.spec.js +64 -0
  62. package/test/unit/dataTrigger/DataTrigger.spec.js +132 -0
  63. package/test/unit/dataTrigger/DataTriggerExecutionContext.spec.js +29 -0
  64. package/test/unit/dataTrigger/dashpayDataTriggers/createContactRequestDataTrigger.spec.js +109 -0
  65. package/test/unit/dataTrigger/dpnsTriggers/createDomainDataTrigger.spec.js +382 -0
  66. package/test/unit/dataTrigger/featureFlagDataTriggers/createFeatureFlagDataTrigger.spec.js +101 -0
  67. package/test/unit/dataTrigger/getDataTriggersFactory.spec.js +113 -0
  68. package/test/unit/dataTrigger/rejectDataTrigger.spec.js +51 -0
  69. package/test/unit/dataTrigger/rewardShareDataTriggers/createMasternodeRewardSharesDataTrigger.spec.js +200 -0
  70. package/test/unit/decodeProtocolEntityFactory.spec.js +75 -0
  71. package/test/unit/document/Document.spec.js +444 -0
  72. package/test/unit/document/DocumentFactory.spec.js +376 -0
  73. package/test/unit/document/errors/InvalidDocumentError.spec.js +46 -0
  74. package/test/unit/document/fetchAndValidateDataContractFactory.spec.js +66 -0
  75. package/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +168 -0
  76. package/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +171 -0
  77. package/test/unit/document/stateTransition/DocumetsBatchTransition/documentTransition/DocumentCreateTransition.spec.js +25 -0
  78. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js +31 -0
  79. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +122 -0
  80. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/validatePartialCompoundIndices.spec.js +75 -0
  81. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +128 -0
  82. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +811 -0
  83. package/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +279 -0
  84. package/test/unit/errors/consensus/codes.spec.js +102 -0
  85. package/test/unit/identity/Identity.spec.js +243 -0
  86. package/test/unit/identity/IdentityFactory.spec.js +274 -0
  87. package/test/unit/identity/IdentityPublicKey.spec.js +273 -0
  88. package/test/unit/identity/creditsConverter.spec.js +34 -0
  89. package/test/unit/identity/errors/InvalidIdentityError.spec.js +46 -0
  90. package/test/unit/identity/stateTransition/IdentityCreateTransition/IdentityCreateTransition.spec.js +184 -0
  91. package/test/unit/identity/stateTransition/IdentityCreateTransition/applyIdentityCreateTransitionFactory.spec.js +90 -0
  92. package/test/unit/identity/stateTransition/IdentityCreateTransition/validation/state/validateIdentityCreateTransitionStateFactory.spec.js +71 -0
  93. package/test/unit/identity/stateTransition/IdentityTopUpTransition/IdentityTopUpTransition.spec.js +137 -0
  94. package/test/unit/identity/stateTransition/IdentityTopUpTransition/applyIdentityTopUpTransitionFactory.spec.js +108 -0
  95. package/test/unit/identity/stateTransition/IdentityTopUpTransition/validation/state/validateIdentityTopUpTransitionStateFactory.spec.js +22 -0
  96. package/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js +219 -0
  97. package/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +149 -0
  98. package/test/unit/identity/stateTransition/assetLockProof/createAssetLockProofInstance.spec.js +21 -0
  99. package/test/unit/identity/stateTransition/assetLockProof/fetchAssetLockPublicKeyHashFactory.spec.js +36 -0
  100. package/test/unit/identity/validation/validateRequiredPurposeAndSecurityLevelFactory.spec.js +47 -0
  101. package/test/unit/stateTransition/StateTransitionFactory.spec.js +160 -0
  102. package/test/unit/stateTransition/createStateTransitionFactory.spec.js +72 -0
  103. package/test/unit/stateTransition/errors/InvalidStateTransitionError.spec.js +51 -0
  104. package/test/unit/stateTransition/validation/validateStateTransitionBasicFactory.spec.js +138 -0
  105. package/test/unit/stateTransition/validation/validateStateTransitionFeeFactory.spec.js +372 -0
  106. package/test/unit/stateTransition/validation/validateStateTransitionIdentitySignatureFactory.spec.js +339 -0
  107. package/test/unit/stateTransition/validation/validateStateTransitionKeySignatureFactory.spec.js +86 -0
  108. package/test/unit/stateTransition/validation/validateStateTransitionStateFactory.spec.js +89 -0
  109. package/test/unit/version/validateProtocolVersionFactory.spec.js +80 -0
  110. package/webpack.config.js +49 -0
@@ -0,0 +1,376 @@
1
+ const bs58 = require('bs58');
2
+
3
+ const Document = require('../../../lib/document/Document');
4
+
5
+ const DocumentCreateTransition = require('../../../lib/document/stateTransition/DocumentsBatchTransition/documentTransition/DocumentCreateTransition');
6
+
7
+ const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture');
8
+ const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture');
9
+ const getDocumentTransitionsFixture = require('../../../lib/test/fixtures/getDocumentTransitionsFixture');
10
+
11
+ const ValidationResult = require('../../../lib/validation/ValidationResult');
12
+
13
+ const Identifier = require('../../../lib/identifier/Identifier');
14
+
15
+ const InvalidDocumentTypeError = require('../../../lib/errors/InvalidDocumentTypeError');
16
+ const InvalidDocumentError = require('../../../lib/document/errors/InvalidDocumentError');
17
+ const InvalidActionNameError = require('../../../lib/document/errors/InvalidActionNameError');
18
+ const NoDocumentsSuppliedError = require('../../../lib/document/errors/NoDocumentsSuppliedError');
19
+ const MismatchOwnerIdsError = require('../../../lib/document/errors/MismatchOwnerIdsError');
20
+ const InvalidInitialRevisionError = require('../../../lib/document/errors/InvalidInitialRevisionError');
21
+ const SerializedObjectParsingError = require('../../../lib/errors/consensus/basic/decode/SerializedObjectParsingError');
22
+
23
+ const generateRandomIdentifier = require('../../../lib/test/utils/generateRandomIdentifier');
24
+ const createDPPMock = require('../../../lib/test/mocks/createDPPMock');
25
+ const SomeConsensusError = require('../../../lib/test/mocks/SomeConsensusError');
26
+ const entropyGenerator = require('../../../lib/util/entropyGenerator');
27
+ const DocumentFactory = require('../../../lib/document/DocumentFactory');
28
+
29
+ describe('DocumentFactory', () => {
30
+ let decodeProtocolEntityMock;
31
+ let generateEntropyMock;
32
+ let validateDocumentMock;
33
+ let fetchAndValidateDataContractMock;
34
+ let ownerId;
35
+ let dataContract;
36
+ let document;
37
+ let documents;
38
+ let rawDocument;
39
+ let factory;
40
+ let fakeTime;
41
+ let fakeTimeDate;
42
+ let entropy;
43
+ let dppMock;
44
+
45
+ beforeEach(function beforeEach() {
46
+ ({ ownerId } = getDocumentsFixture);
47
+ dataContract = getDataContractFixture();
48
+
49
+ documents = getDocumentsFixture(dataContract);
50
+ ([,,, document] = documents);
51
+ rawDocument = document.toObject();
52
+
53
+ decodeProtocolEntityMock = this.sinonSandbox.stub();
54
+ generateEntropyMock = this.sinonSandbox.stub(entropyGenerator, 'generate');
55
+ validateDocumentMock = this.sinonSandbox.stub();
56
+
57
+ validateDocumentMock.returns(new ValidationResult());
58
+
59
+ entropy = bs58.decode('789');
60
+
61
+ generateEntropyMock.returns(entropy);
62
+
63
+ const fetchContractResult = new ValidationResult();
64
+ fetchContractResult.setData(dataContract);
65
+
66
+ fetchAndValidateDataContractMock = this.sinonSandbox.stub().returns(fetchContractResult);
67
+
68
+ dppMock = createDPPMock();
69
+
70
+ factory = new DocumentFactory(
71
+ dppMock,
72
+ validateDocumentMock,
73
+ fetchAndValidateDataContractMock,
74
+ decodeProtocolEntityMock,
75
+ );
76
+
77
+ fakeTimeDate = new Date();
78
+ fakeTime = this.sinonSandbox.useFakeTimers(fakeTimeDate);
79
+ });
80
+
81
+ afterEach(() => {
82
+ fakeTime.reset();
83
+ generateEntropyMock.restore();
84
+ });
85
+
86
+ describe('create', () => {
87
+ it('should return new Document with specified type and data', () => {
88
+ const contractId = bs58.decode('FQco85WbwNgb5ix8QQAH6wurMcgEC5ENSCv5ixG9cj12');
89
+ const name = 'Cutie';
90
+
91
+ ownerId = bs58.decode('5zcXZpTLWFwZjKjq3ME5KVavtZa9YUaZESVzrndehBhq');
92
+ dataContract.id = Identifier.from(contractId);
93
+
94
+ const newDocument = factory.create(
95
+ dataContract,
96
+ ownerId,
97
+ rawDocument.$type,
98
+ { name },
99
+ );
100
+
101
+ expect(newDocument).to.be.an.instanceOf(Document);
102
+
103
+ expect(newDocument.getType()).to.equal(rawDocument.$type);
104
+
105
+ expect(newDocument.get('name')).to.equal(name);
106
+
107
+ expect(newDocument.getDataContractId().toBuffer()).to.deep.equal(contractId);
108
+ expect(newDocument.getOwnerId().toBuffer()).to.deep.equal(ownerId);
109
+
110
+ expect(generateEntropyMock).to.have.been.calledOnce();
111
+ expect(newDocument.getEntropy()).to.deep.equal(entropy);
112
+
113
+ expect(newDocument.getRevision()).to.equal(DocumentCreateTransition.INITIAL_REVISION);
114
+
115
+ expect(newDocument.getId()).to.deep.equal(bs58.decode('B99gjrjq6R1FXwGUQnoP7VrmCDDT1PbKprUNzjVbxXfz'));
116
+
117
+ expect(newDocument.getCreatedAt().getTime()).to.be.equal(fakeTimeDate.getTime());
118
+ expect(newDocument.getCreatedAt().getTime()).to.equal(newDocument.getUpdatedAt().getTime());
119
+ });
120
+
121
+ it('should throw an error if type is not defined', () => {
122
+ const type = 'wrong';
123
+
124
+ try {
125
+ factory.create(dataContract, ownerId, type);
126
+
127
+ expect.fail('InvalidDocumentTypeError should be thrown');
128
+ } catch (e) {
129
+ expect(e).to.be.an.instanceOf(InvalidDocumentTypeError);
130
+ expect(e.getType()).to.equal(type);
131
+ expect(e.getDataContract()).to.equal(dataContract);
132
+ }
133
+ });
134
+
135
+ it('should throw an error if validation faled', () => {
136
+ const error = new Error('validation failed');
137
+ const validationResult = new ValidationResult();
138
+ validationResult.addError(error);
139
+
140
+ validateDocumentMock.returns(validationResult);
141
+
142
+ try {
143
+ factory.create(dataContract, ownerId, rawDocument.$type);
144
+
145
+ expect.fail('InvalidDocumentError should be thrown');
146
+ } catch (e) {
147
+ expect(e).to.be.an.instanceOf(InvalidDocumentError);
148
+ }
149
+ });
150
+ });
151
+
152
+ describe('createFromObject', () => {
153
+ it('should return new Data Contract with data from passed object', async () => {
154
+ validateDocumentMock.returns(new ValidationResult());
155
+
156
+ const result = await factory.createFromObject(rawDocument);
157
+
158
+ expect(result).to.be.an.instanceOf(Document);
159
+ expect(result.toObject()).to.deep.equal(document.toObject());
160
+
161
+ expect(fetchAndValidateDataContractMock).to.have.been.calledOnceWithExactly(rawDocument);
162
+
163
+ expect(validateDocumentMock).to.have.been.calledOnceWithExactly(
164
+ rawDocument, dataContract,
165
+ );
166
+ });
167
+
168
+ it('should return new Document without validation if "skipValidation" option is passed', async function it() {
169
+ const resultMock = {
170
+ isValid: () => true,
171
+ merge: this.sinonSandbox.stub(),
172
+ getData: () => getDataContractFixture(),
173
+ };
174
+
175
+ fetchAndValidateDataContractMock.resolves(resultMock);
176
+
177
+ const result = await factory.createFromObject(rawDocument, { skipValidation: true });
178
+
179
+ expect(result).to.be.an.instanceOf(Document);
180
+ expect(result.toObject()).to.deep.equal(document.toObject());
181
+
182
+ expect(fetchAndValidateDataContractMock).to.have.been.calledOnceWithExactly(rawDocument);
183
+ expect(validateDocumentMock).to.have.not.been.called();
184
+ expect(resultMock.merge).to.have.not.been.called();
185
+ });
186
+
187
+ it('should throw InvalidDocumentError if passed object is not valid', async () => {
188
+ const validationError = new SomeConsensusError('test');
189
+
190
+ validateDocumentMock.returns(
191
+ new ValidationResult([validationError]),
192
+ );
193
+
194
+ try {
195
+ await factory.createFromObject(rawDocument);
196
+
197
+ expect.fail('InvalidDocumentError should be thrown');
198
+ } catch (e) {
199
+ expect(e).to.be.an.instanceOf(InvalidDocumentError);
200
+
201
+ expect(e.getErrors()).to.have.length(1);
202
+ expect(e.getRawDocument()).to.equal(rawDocument);
203
+
204
+ const [consensusError] = e.getErrors();
205
+ expect(consensusError).to.equal(validationError);
206
+
207
+ expect(fetchAndValidateDataContractMock).to.have.been.calledOnceWithExactly(rawDocument);
208
+ expect(validateDocumentMock).to.have.been.calledOnceWithExactly(rawDocument, dataContract);
209
+ }
210
+ });
211
+
212
+ it('should throw InvalidDocumentError if Data Contract is not valid', async () => {
213
+ const fetchContractError = new SomeConsensusError('error');
214
+
215
+ fetchAndValidateDataContractMock.returns(
216
+ new ValidationResult([fetchContractError]),
217
+ );
218
+
219
+ try {
220
+ await factory.createFromObject(rawDocument);
221
+
222
+ expect.fail('InvalidDocumentError should be thrown');
223
+ } catch (e) {
224
+ expect(e).to.be.an.instanceOf(InvalidDocumentError);
225
+
226
+ expect(e.getErrors()).to.have.length(1);
227
+ expect(e.getRawDocument()).to.equal(rawDocument);
228
+
229
+ const [consensusError] = e.getErrors();
230
+
231
+ expect(consensusError).to.equal(fetchContractError);
232
+
233
+ expect(fetchAndValidateDataContractMock).to.have.been.calledOnceWith(rawDocument);
234
+ expect(validateDocumentMock).to.have.not.been.called();
235
+ }
236
+ });
237
+ });
238
+
239
+ describe('createFromBuffer', () => {
240
+ let serializedDocument;
241
+
242
+ beforeEach(function beforeEach() {
243
+ this.sinonSandbox.stub(factory, 'createFromObject');
244
+ // eslint-disable-next-line prefer-destructuring
245
+ document = documents[8]; // document with binary fields
246
+
247
+ serializedDocument = document.toBuffer();
248
+ rawDocument = document.toObject();
249
+ });
250
+
251
+ afterEach(() => {
252
+ factory.createFromObject.restore();
253
+ });
254
+
255
+ it('should return new Document from serialized one', async () => {
256
+ decodeProtocolEntityMock.returns([rawDocument.$protocolVersion, rawDocument]);
257
+
258
+ factory.createFromObject.returns(document);
259
+
260
+ const result = await factory.createFromBuffer(serializedDocument);
261
+
262
+ expect(result).to.equal(document);
263
+
264
+ expect(factory.createFromObject).to.have.been.calledOnceWith(rawDocument);
265
+
266
+ expect(decodeProtocolEntityMock).to.have.been.calledOnceWith(
267
+ serializedDocument,
268
+ );
269
+ });
270
+
271
+ it('should throw InvalidDocumentError if the decoding fails with consensus error', async () => {
272
+ const parsingError = new SerializedObjectParsingError(
273
+ serializedDocument,
274
+ new Error(),
275
+ );
276
+
277
+ decodeProtocolEntityMock.throws(parsingError);
278
+
279
+ try {
280
+ await factory.createFromBuffer(serializedDocument);
281
+
282
+ expect.fail('should throw InvalidDocumentError');
283
+ } catch (e) {
284
+ expect(e).to.be.an.instanceOf(InvalidDocumentError);
285
+
286
+ const [innerError] = e.getErrors();
287
+ expect(innerError).to.equal(parsingError);
288
+ }
289
+ });
290
+
291
+ it('should throw an error if decoding fails with any other error', async () => {
292
+ const parsingError = new Error('Something failed during parsing');
293
+
294
+ decodeProtocolEntityMock.throws(parsingError);
295
+
296
+ try {
297
+ await factory.createFromBuffer(serializedDocument);
298
+
299
+ expect.fail('should throw an error');
300
+ } catch (e) {
301
+ expect(e).to.equal(parsingError);
302
+ }
303
+ });
304
+ });
305
+
306
+ describe('createStateTransition', () => {
307
+ it('should throw and error if documents have unknown action', () => {
308
+ try {
309
+ factory.createStateTransition({
310
+ unknown: documents,
311
+ });
312
+ expect.fail('Error was not thrown');
313
+ } catch (e) {
314
+ expect(e).to.be.an.instanceOf(InvalidActionNameError);
315
+ expect(e.getActions()).to.have.deep.members(['unknown']);
316
+ }
317
+ });
318
+
319
+ it('should throw and error if no documents were supplied', () => {
320
+ try {
321
+ factory.createStateTransition({});
322
+ expect.fail('Error was not thrown');
323
+ } catch (e) {
324
+ expect(e).to.be.an.instanceOf(NoDocumentsSuppliedError);
325
+ }
326
+ });
327
+
328
+ it('should throw and error if documents have mixed owner ids', () => {
329
+ documents[0].ownerId = generateRandomIdentifier().toBuffer();
330
+ try {
331
+ factory.createStateTransition({
332
+ create: documents,
333
+ });
334
+ expect.fail('Error was not thrown');
335
+ } catch (e) {
336
+ expect(e).to.be.an.instanceOf(MismatchOwnerIdsError);
337
+ expect(e.getDocuments()).to.have.deep.members(documents);
338
+ }
339
+ });
340
+
341
+ it('should throw and error if create documents have invalid initial version', () => {
342
+ documents[0].setRevision(3);
343
+ try {
344
+ factory.createStateTransition({
345
+ create: documents,
346
+ });
347
+ expect.fail('Error was not thrown');
348
+ } catch (e) {
349
+ expect(e).to.be.an.instanceOf(InvalidInitialRevisionError);
350
+ expect(e.getDocument()).to.deep.equal(documents[0]);
351
+ }
352
+ });
353
+
354
+ it('should create DocumentsBatchTransition with passed documents', () => {
355
+ const [newDocument] = getDocumentsFixture(dataContract);
356
+
357
+ fakeTime.tick(1000);
358
+
359
+ const stateTransition = factory.createStateTransition({
360
+ create: documents,
361
+ replace: [newDocument],
362
+ });
363
+
364
+ const expectedTransitions = getDocumentTransitionsFixture({
365
+ create: documents,
366
+ replace: [newDocument],
367
+ });
368
+
369
+ expectedTransitions.slice(-1).updatedAt = new Date();
370
+
371
+ expect(stateTransition.getTransitions()).to.deep.equal(
372
+ expectedTransitions,
373
+ );
374
+ });
375
+ });
376
+ });
@@ -0,0 +1,46 @@
1
+ const InvalidDocumentError = require('../../../../lib/document/errors/InvalidDocumentError');
2
+ const getDocumentsFixture = require('../../../../lib/test/fixtures/getDocumentsFixture');
3
+
4
+ describe('InvalidDocumentError', () => {
5
+ let rawDocument;
6
+ let error;
7
+
8
+ beforeEach(() => {
9
+ error = new Error('Some error');
10
+
11
+ const [document] = getDocumentsFixture();
12
+ rawDocument = document.toObject();
13
+ });
14
+
15
+ it('should return errors', () => {
16
+ const errors = [error];
17
+
18
+ const invalidDocumentError = new InvalidDocumentError(errors, rawDocument);
19
+
20
+ expect(invalidDocumentError.getErrors()).to.deep.equal(errors);
21
+ });
22
+
23
+ it('should return Document', async () => {
24
+ const errors = [error];
25
+
26
+ const invalidDocumentError = new InvalidDocumentError(errors, rawDocument);
27
+
28
+ expect(invalidDocumentError.getRawDocument()).to.deep.equal(rawDocument);
29
+ });
30
+
31
+ it('should contain message for 1 error', async () => {
32
+ const errors = [error];
33
+
34
+ const invalidDocumentError = new InvalidDocumentError(errors, rawDocument);
35
+
36
+ expect(invalidDocumentError.message).to.equal(`Invalid Document: "${error.message}"`);
37
+ });
38
+
39
+ it('should contain message for multiple errors', async () => {
40
+ const errors = [error, error];
41
+
42
+ const invalidDocumentError = new InvalidDocumentError(errors, rawDocument);
43
+
44
+ expect(invalidDocumentError.message).to.equal(`Invalid Document: "${error.message}" and 1 more`);
45
+ });
46
+ });
@@ -0,0 +1,66 @@
1
+ const fetchAndValidateDataContractFactory = require('../../../lib/document/fetchAndValidateDataContractFactory');
2
+
3
+ const createStateRepositoryMock = require('../../../lib/test/mocks/createStateRepositoryMock');
4
+
5
+ const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture');
6
+ const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture');
7
+
8
+ const ValidationResult = require('../../../lib/validation/ValidationResult');
9
+
10
+ const MissingDataContractIdError = require('../../../lib/errors/consensus/basic/document/MissingDataContractIdError');
11
+ const DataContractNotPresentError = require('../../../lib/errors/consensus/basic/document/DataContractNotPresentError');
12
+
13
+ const { expectValidationError } = require('../../../lib/test/expect/expectError');
14
+
15
+ describe('fetchAndValidateDataContractFactory', () => {
16
+ let stateRepositoryMock;
17
+ let fetchAndValidateDataContract;
18
+ let rawDocument;
19
+
20
+ beforeEach(function beforeEach() {
21
+ const dataContract = getDataContractFixture();
22
+
23
+ const [document] = getDocumentsFixture(dataContract);
24
+ rawDocument = document.toObject();
25
+
26
+ stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
27
+
28
+ stateRepositoryMock.fetchDataContract.resolves(dataContract);
29
+
30
+ fetchAndValidateDataContract = fetchAndValidateDataContractFactory(
31
+ stateRepositoryMock,
32
+ );
33
+ });
34
+
35
+ it('should return with invalid result if $dataContractId is not present', async () => {
36
+ delete rawDocument.$dataContractId;
37
+
38
+ const result = await fetchAndValidateDataContract(rawDocument);
39
+
40
+ expectValidationError(result, MissingDataContractIdError);
41
+
42
+ const [error] = result.getErrors();
43
+
44
+ expect(error.getCode()).to.equal(1025);
45
+ });
46
+
47
+ it('should return with invalid result if Data Contract is not present', async () => {
48
+ stateRepositoryMock.fetchDataContract.resolves(null);
49
+
50
+ const result = await fetchAndValidateDataContract(rawDocument);
51
+
52
+ expectValidationError(result, DataContractNotPresentError);
53
+
54
+ const [error] = result.getErrors();
55
+
56
+ expect(error.getCode()).to.equal(1018);
57
+ expect(error.getDataContractId()).to.deep.equal(rawDocument.$dataContractId);
58
+ });
59
+
60
+ it('should return valid result', async () => {
61
+ const result = await fetchAndValidateDataContract(rawDocument);
62
+
63
+ expect(result).to.be.an.instanceOf(ValidationResult);
64
+ expect(result.isValid()).to.be.true();
65
+ });
66
+ });
@@ -0,0 +1,168 @@
1
+ const getDataContractFixture = require('../../../../../lib/test/fixtures/getDataContractFixture');
2
+ const getDocumentsFixture = require('../../../../../lib/test/fixtures/getDocumentsFixture');
3
+ const stateTransitionTypes = require('../../../../../lib/stateTransition/stateTransitionTypes');
4
+ const createDPPMock = require('../../../../../lib/test/mocks/createDPPMock');
5
+ const protocolVersion = require('../../../../../lib/version/protocolVersion');
6
+ const DocumentFactory = require('../../../../../lib/document/DocumentFactory');
7
+ const serializer = require('../../../../../lib/util/serializer');
8
+ const hash = require('../../../../../lib/util/hash');
9
+
10
+ describe('DocumentsBatchTransition', () => {
11
+ let stateTransition;
12
+ let documents;
13
+ let hashMock;
14
+ let encodeMock;
15
+ let dataContract;
16
+
17
+ beforeEach(function beforeEach() {
18
+ dataContract = getDataContractFixture();
19
+ documents = getDocumentsFixture(dataContract);
20
+
21
+ encodeMock = this.sinonSandbox.stub(serializer, 'encode');
22
+ hashMock = this.sinonSandbox.stub(hash, 'hash');
23
+
24
+ const factory = new DocumentFactory(createDPPMock(), undefined, undefined);
25
+ stateTransition = factory.createStateTransition({
26
+ create: documents,
27
+ });
28
+ });
29
+
30
+ afterEach(() => {
31
+ encodeMock.restore();
32
+ hashMock.restore();
33
+ });
34
+
35
+ describe('#getProtocolVersion', () => {
36
+ it('should return the current protocol version', () => {
37
+ const result = stateTransition.getProtocolVersion();
38
+
39
+ expect(result).to.equal(protocolVersion.latestVersion);
40
+ });
41
+ });
42
+
43
+ describe('#getType', () => {
44
+ it('should return State Transition type', () => {
45
+ const result = stateTransition.getType();
46
+
47
+ expect(result).to.equal(stateTransitionTypes.DOCUMENTS_BATCH);
48
+ });
49
+ });
50
+
51
+ describe('#getTransitions', () => {
52
+ it('should return document transitions', () => {
53
+ const result = stateTransition.getTransitions();
54
+
55
+ expect(result).to.equal(stateTransition.transitions);
56
+ });
57
+ });
58
+
59
+ describe('#toJSON', () => {
60
+ it('should return State Transition as JSON', () => {
61
+ expect(stateTransition.toJSON()).to.deep.equal({
62
+ protocolVersion: protocolVersion.latestVersion,
63
+ type: stateTransitionTypes.DOCUMENTS_BATCH,
64
+ ownerId: documents[0].getOwnerId().toString(),
65
+ transitions: stateTransition.getTransitions().map((d) => d.toJSON()),
66
+ signaturePublicKeyId: undefined,
67
+ signature: undefined,
68
+ });
69
+ });
70
+ });
71
+
72
+ describe('#toObject', () => {
73
+ it('should return State Transition as plain object', () => {
74
+ expect(stateTransition.toObject()).to.deep.equal({
75
+ protocolVersion: protocolVersion.latestVersion,
76
+ type: stateTransitionTypes.DOCUMENTS_BATCH,
77
+ ownerId: documents[0].getOwnerId(),
78
+ transitions: stateTransition.getTransitions().map((d) => d.toObject()),
79
+ signaturePublicKeyId: undefined,
80
+ signature: undefined,
81
+ });
82
+ });
83
+ });
84
+
85
+ describe('#toBuffer', () => {
86
+ it('should return serialized Documents State Transition', () => {
87
+ const serializedStateTransition = Buffer.from('123');
88
+
89
+ encodeMock.returns(serializedStateTransition);
90
+
91
+ const result = stateTransition.toBuffer();
92
+
93
+ const protocolVersionUInt32 = Buffer.alloc(4);
94
+ protocolVersionUInt32.writeUInt32LE(stateTransition.protocolVersion, 0);
95
+
96
+ expect(result).to.deep.equal(
97
+ Buffer.concat([protocolVersionUInt32, serializedStateTransition]),
98
+ );
99
+
100
+ const dataToEncode = stateTransition.toObject();
101
+ delete dataToEncode.protocolVersion;
102
+
103
+ expect(encodeMock).to.have.been.calledOnceWith(dataToEncode);
104
+ });
105
+ });
106
+
107
+ describe('#hash', () => {
108
+ it('should return Documents State Transition hash as hex', () => {
109
+ const serializedDocument = Buffer.from('123');
110
+ const hashedDocument = '456';
111
+
112
+ encodeMock.returns(serializedDocument);
113
+ hashMock.returns(hashedDocument);
114
+
115
+ const result = stateTransition.hash();
116
+
117
+ expect(result).to.equal(hashedDocument);
118
+
119
+ const dataToEncode = stateTransition.toObject();
120
+ delete dataToEncode.protocolVersion;
121
+
122
+ expect(encodeMock).to.have.been.calledOnceWith(dataToEncode);
123
+
124
+ const protocolVersionUInt32 = Buffer.alloc(4);
125
+ protocolVersionUInt32.writeUInt32LE(stateTransition.protocolVersion, 0);
126
+
127
+ expect(hashMock).to.have.been.calledOnceWith(
128
+ Buffer.concat([protocolVersionUInt32, serializedDocument]),
129
+ );
130
+ });
131
+ });
132
+
133
+ describe('#getOwnerId', () => {
134
+ it('should return owner id', async () => {
135
+ const result = stateTransition.getOwnerId();
136
+
137
+ expect(result).to.deep.equal(getDocumentsFixture.ownerId);
138
+ });
139
+ });
140
+
141
+ describe('#getModifiedDataIds', () => {
142
+ it('should return ids of affected documents', () => {
143
+ const expectedIds = documents.map((doc) => doc.getId());
144
+ const result = stateTransition.getModifiedDataIds();
145
+
146
+ expect(result.length).to.be.equal(10);
147
+ expect(result).to.be.deep.equal(expectedIds);
148
+ });
149
+ });
150
+
151
+ describe('#isDataContractStateTransition', () => {
152
+ it('should return false', () => {
153
+ expect(stateTransition.isDataContractStateTransition()).to.be.false();
154
+ });
155
+ });
156
+
157
+ describe('#isDocumentStateTransition', () => {
158
+ it('should return true', () => {
159
+ expect(stateTransition.isDocumentStateTransition()).to.be.true();
160
+ });
161
+ });
162
+
163
+ describe('#isIdentityStateTransition', () => {
164
+ it('should return false', () => {
165
+ expect(stateTransition.isIdentityStateTransition()).to.be.false();
166
+ });
167
+ });
168
+ });