@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,171 @@
1
+ const Document = require('../../../../../lib/document/Document');
2
+ const DocumentsBatchTransition = require(
3
+ '../../../../../lib/document/stateTransition/DocumentsBatchTransition/DocumentsBatchTransition',
4
+ );
5
+
6
+ const applyDocumentsBatchTransitionFactory = require(
7
+ '../../../../../lib/document/stateTransition/DocumentsBatchTransition/applyDocumentsBatchTransitionFactory',
8
+ );
9
+
10
+ const getDataContractFixture = require('../../../../../lib/test/fixtures/getDataContractFixture');
11
+ const getDocumentsFixture = require('../../../../../lib/test/fixtures/getDocumentsFixture');
12
+ const getDocumentTransitionsFixture = require(
13
+ '../../../../../lib/test/fixtures/getDocumentTransitionsFixture',
14
+ );
15
+
16
+ const createStateRepositoryMock = require('../../../../../lib/test/mocks/createStateRepositoryMock');
17
+
18
+ const protocolVersion = require('../../../../../lib/version/protocolVersion');
19
+ const StateTransitionExecutionContext = require('../../../../../lib/stateTransition/StateTransitionExecutionContext');
20
+ const DocumentNotProvidedError = require('../../../../../lib/document/errors/DocumentNotProvidedError');
21
+
22
+ describe('applyDocumentsBatchTransitionFactory', () => {
23
+ let documents;
24
+ let dataContract;
25
+ let documentTransitions;
26
+ let ownerId;
27
+ let replaceDocument;
28
+ let stateTransition;
29
+ let documentsFixture;
30
+ let applyDocumentsBatchTransition;
31
+ let stateRepositoryMock;
32
+ let fetchDocumentsMock;
33
+ let executionContext;
34
+
35
+ beforeEach(function beforeEach() {
36
+ dataContract = getDataContractFixture();
37
+ documentsFixture = getDocumentsFixture(dataContract);
38
+
39
+ ownerId = getDocumentsFixture.ownerId;
40
+
41
+ replaceDocument = new Document({
42
+ ...documentsFixture[1].toObject(),
43
+ lastName: 'NotSoShiny',
44
+ }, dataContract);
45
+
46
+ documents = [replaceDocument, documentsFixture[2]];
47
+
48
+ documentTransitions = getDocumentTransitionsFixture({
49
+ create: [documentsFixture[0]],
50
+ replace: [documents[0]],
51
+ delete: [documents[1]],
52
+ });
53
+
54
+ stateTransition = new DocumentsBatchTransition({
55
+ protocolVersion: protocolVersion.latestVersion,
56
+ ownerId,
57
+ transitions: documentTransitions.map((t) => t.toObject()),
58
+ }, [dataContract]);
59
+
60
+ executionContext = new StateTransitionExecutionContext();
61
+
62
+ stateTransition.setExecutionContext(executionContext);
63
+
64
+ stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
65
+ stateRepositoryMock.fetchDataContract.resolves(dataContract);
66
+ stateRepositoryMock.fetchLatestPlatformBlockHeader.resolves({
67
+ time: {
68
+ seconds: 86400,
69
+ },
70
+ });
71
+
72
+ fetchDocumentsMock = this.sinonSandbox.stub();
73
+ fetchDocumentsMock.resolves([
74
+ replaceDocument,
75
+ ]);
76
+
77
+ applyDocumentsBatchTransition = applyDocumentsBatchTransitionFactory(
78
+ stateRepositoryMock,
79
+ fetchDocumentsMock,
80
+ );
81
+ });
82
+
83
+ it('should call `store`, `replace` and `remove` functions for specific type of transitions', async () => {
84
+ await applyDocumentsBatchTransition(stateTransition);
85
+
86
+ const replaceDocumentTransition = documentTransitions[1];
87
+
88
+ expect(fetchDocumentsMock).to.have.been.calledOnceWithExactly(
89
+ [replaceDocumentTransition],
90
+ executionContext,
91
+ );
92
+
93
+ expect(stateRepositoryMock.createDocument).to.have.been.calledOnce();
94
+ expect(stateRepositoryMock.updateDocument).to.have.been.calledOnce();
95
+
96
+ const callsArgs = [
97
+ ...stateRepositoryMock.createDocument.getCall(0).args,
98
+ ...stateRepositoryMock.updateDocument.getCall(0).args,
99
+ ];
100
+
101
+ expect(callsArgs).to.have.deep.members([
102
+ documentsFixture[0],
103
+ documents[0],
104
+ executionContext,
105
+ executionContext,
106
+ ]);
107
+
108
+ expect(stateRepositoryMock.removeDocument).to.have.been.calledOnceWithExactly(
109
+ documentTransitions[2].getDataContract(),
110
+ documentTransitions[2].getType(),
111
+ documentTransitions[2].getId(),
112
+ executionContext,
113
+ );
114
+ });
115
+
116
+ it('should throw an error if document was not provided for a replacement', async () => {
117
+ fetchDocumentsMock.resolves([]);
118
+
119
+ const replaceDocumentTransition = documentTransitions[1];
120
+
121
+ try {
122
+ await applyDocumentsBatchTransition(stateTransition);
123
+ expect.fail('Error was not thrown');
124
+ } catch (e) {
125
+ expect(e).to.be.an.instanceOf(DocumentNotProvidedError);
126
+ expect(e.getDocumentTransition()).to.deep.equal(replaceDocumentTransition);
127
+ }
128
+ });
129
+
130
+ it('should call `replace` functions on dry run', async () => {
131
+ documentTransitions = getDocumentTransitionsFixture({
132
+ create: [],
133
+ replace: [documents[0]],
134
+ delete: [],
135
+ });
136
+
137
+ stateTransition = new DocumentsBatchTransition({
138
+ protocolVersion: protocolVersion.latestVersion,
139
+ ownerId,
140
+ transitions: documentTransitions.map((t) => t.toObject()),
141
+ }, [dataContract]);
142
+
143
+ stateTransition.getExecutionContext().enableDryRun();
144
+
145
+ await applyDocumentsBatchTransition(stateTransition);
146
+
147
+ stateTransition.getExecutionContext().disableDryRun();
148
+
149
+ expect(stateRepositoryMock.fetchLatestPlatformBlockHeader).to.have.been.calledOnceWith();
150
+
151
+ const [documentTransition] = stateTransition.getTransitions();
152
+ const newDocument = new Document({
153
+ $protocolVersion: stateTransition.getProtocolVersion(),
154
+ $id: documentTransition.getId(),
155
+ $type: documentTransition.getType(),
156
+ $dataContractId: documentTransition.getDataContractId(),
157
+ $ownerId: stateTransition.getOwnerId(),
158
+ $createdAt: 86400 * 1000,
159
+ ...documentTransition.getData(),
160
+ }, documentTransition.getDataContract());
161
+
162
+ newDocument.setRevision(documentTransition.getRevision());
163
+ newDocument.setData(documentTransition.getData());
164
+ newDocument.setUpdatedAt(documentTransition.getUpdatedAt());
165
+
166
+ expect(stateRepositoryMock.updateDocument).to.have.been.calledOnceWithExactly(
167
+ newDocument,
168
+ executionContext,
169
+ );
170
+ });
171
+ });
@@ -0,0 +1,25 @@
1
+ const getDocumentTransitionsFixture = require('../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
2
+
3
+ describe('DocumentCreateTransition', () => {
4
+ let documentTransition;
5
+
6
+ beforeEach(() => {
7
+ [documentTransition] = getDocumentTransitionsFixture();
8
+ });
9
+
10
+ describe('toJSON', () => {
11
+ it('should return json representation', () => {
12
+ const jsonDocumentTransition = documentTransition.toJSON();
13
+
14
+ expect(jsonDocumentTransition).to.deep.equal({
15
+ $id: documentTransition.getId().toString(),
16
+ $type: documentTransition.getType(),
17
+ $action: documentTransition.getAction(),
18
+ $dataContractId: documentTransition.getDataContractId().toString(),
19
+ $entropy: documentTransition.getEntropy().toString('base64'),
20
+ $createdAt: documentTransition.getCreatedAt().getTime(),
21
+ name: documentTransition.getData().name,
22
+ });
23
+ });
24
+ });
25
+ });
@@ -0,0 +1,31 @@
1
+ const findDuplicateDocuments = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/validation/basic/findDuplicatesById');
2
+
3
+ const getDocumentTransitionsFixture = require('../../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
4
+
5
+ describe('findDuplicatesById', () => {
6
+ let rawDocumentTransitions;
7
+
8
+ beforeEach(() => {
9
+ rawDocumentTransitions = getDocumentTransitionsFixture().map((t) => t.toObject());
10
+ });
11
+
12
+ it('should return empty array if there are no duplicated Documents', () => {
13
+ const result = findDuplicateDocuments(rawDocumentTransitions);
14
+
15
+ expect(result).to.be.an('array');
16
+ expect(result).to.have.lengthOf(0);
17
+ });
18
+
19
+ it('should return duplicated Documents', () => {
20
+ rawDocumentTransitions.push(rawDocumentTransitions[0]);
21
+
22
+ const result = findDuplicateDocuments(rawDocumentTransitions);
23
+
24
+ expect(result).to.be.an('array');
25
+ expect(result).to.have.lengthOf(2);
26
+ expect(result).to.have.deep.members([
27
+ rawDocumentTransitions[0],
28
+ rawDocumentTransitions[0],
29
+ ]);
30
+ });
31
+ });
@@ -0,0 +1,122 @@
1
+ const Document = require('../../../../../../../lib/document/Document');
2
+
3
+ const findDuplicateDocumentsByIndices = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/validation/basic/findDuplicatesByIndices');
4
+
5
+ const getDataContractFixture = require('../../../../../../../lib/test/fixtures/getDataContractFixture');
6
+ const getDocumentsFixture = require('../../../../../../../lib/test/fixtures/getDocumentsFixture');
7
+ const getDocumentTransitionsFixture = require('../../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
8
+
9
+ const { generate: generateEntropy } = require('../../../../../../../lib/util/entropyGenerator');
10
+
11
+ describe('findDuplicatesByIndices', () => {
12
+ let documents;
13
+ let contract;
14
+ let documentTransitions;
15
+
16
+ beforeEach(() => {
17
+ contract = getDataContractFixture();
18
+ contract.setDocumentSchema('nonUniqueIndexDocument', {
19
+ indices: [
20
+ {
21
+ name: 'ownerIdLastName',
22
+ properties: [
23
+ { $ownerId: 'asc' },
24
+ { lastName: 'asc' },
25
+ ],
26
+ unique: false,
27
+ },
28
+ ],
29
+ properties: {
30
+ firstName: {
31
+ type: 'string',
32
+ },
33
+ lastName: {
34
+ type: 'string',
35
+ },
36
+ },
37
+ required: ['lastName'],
38
+ additionalProperties: false,
39
+ });
40
+
41
+ contract.setDocumentSchema('singleDocument', {
42
+ indices: [
43
+ {
44
+ name: 'ownerIdLastName',
45
+ properties: [
46
+ { $ownerId: 'asc' },
47
+ { lastName: 'asc' },
48
+ ],
49
+ unique: true,
50
+ },
51
+ ],
52
+ properties: {
53
+ firstName: {
54
+ type: 'string',
55
+ },
56
+ lastName: {
57
+ type: 'string',
58
+ },
59
+ },
60
+ required: ['lastName'],
61
+ additionalProperties: false,
62
+ });
63
+
64
+ documents = getDocumentsFixture(contract);
65
+ documents.forEach((doc) => {
66
+ // eslint-disable-next-line no-param-reassign
67
+ doc.dataContract = contract;
68
+ // eslint-disable-next-line no-param-reassign
69
+ doc.dataContractId = contract.getId();
70
+ });
71
+
72
+ const [, , , william] = documents;
73
+
74
+ let document = new Document({
75
+ ...william.toObject(),
76
+ $type: 'nonUniqueIndexDocument',
77
+ $entropy: generateEntropy(),
78
+ }, contract);
79
+
80
+ document.setEntropy(generateEntropy());
81
+
82
+ documents.push(document);
83
+
84
+ document = new Document({
85
+ ...william.toObject(),
86
+ $type: 'singleDocument',
87
+ $entropy: generateEntropy(),
88
+ }, contract);
89
+
90
+ document.setEntropy(generateEntropy());
91
+
92
+ documents.push(document);
93
+
94
+ documentTransitions = getDocumentTransitionsFixture({
95
+ create: documents,
96
+ }).map((t) => t.toObject());
97
+ });
98
+
99
+ it('should return duplicate documents if they are present', () => {
100
+ const [, , , , leon] = documents;
101
+
102
+ leon.set('lastName', 'Birkin');
103
+
104
+ documentTransitions = getDocumentTransitionsFixture({
105
+ create: documents,
106
+ }).map((t) => t.toObject());
107
+
108
+ const duplicates = findDuplicateDocumentsByIndices(documentTransitions, contract);
109
+ expect(duplicates).to.have.deep.members(
110
+ [
111
+ documentTransitions[3],
112
+ documentTransitions[4],
113
+ ],
114
+ );
115
+ });
116
+
117
+ it('should return an empty array of there are no duplicates', () => {
118
+ const duplicates = findDuplicateDocumentsByIndices(documentTransitions, contract);
119
+
120
+ expect(duplicates.length).to.equal(0);
121
+ });
122
+ });
@@ -0,0 +1,75 @@
1
+ const validatePartialCompoundIndices = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/validation/basic/validatePartialCompoundIndices');
2
+ const InconsistentCompoundIndexDataError = require('../../../../../../../lib/errors/consensus/basic/document/InconsistentCompoundIndexDataError');
3
+
4
+ const getDocumentsFixture = require('../../../../../../../lib/test/fixtures/getDocumentsFixture');
5
+ const getContractFixture = require('../../../../../../../lib/test/fixtures/getDataContractFixture');
6
+ const getDocumentTransitionsFixture = require('../../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
7
+
8
+ const ValidationResult = require('../../../../../../../lib/validation/ValidationResult');
9
+ const { expectValidationError } = require('../../../../../../../lib/test/expect/expectError');
10
+
11
+ describe('validatePartialCompoundIndices', () => {
12
+ let documents;
13
+ let rawDocumentTransitions;
14
+ let dataContract;
15
+ let ownerId;
16
+
17
+ beforeEach(() => {
18
+ dataContract = getContractFixture();
19
+ ownerId = dataContract.getOwnerId();
20
+ });
21
+
22
+ it('should return invalid result if compound index contains not all fields', () => {
23
+ const document = getDocumentsFixture(dataContract)[9];
24
+ document.set('lastName', undefined);
25
+
26
+ documents = [document];
27
+ rawDocumentTransitions = getDocumentTransitionsFixture({
28
+ create: documents,
29
+ }).map((documentTransition) => documentTransition.toObject());
30
+
31
+ const result = validatePartialCompoundIndices(ownerId, rawDocumentTransitions, dataContract);
32
+
33
+ expectValidationError(result, InconsistentCompoundIndexDataError);
34
+
35
+ const [error] = result.getErrors();
36
+
37
+ expect(error.getCode()).to.equal(1021);
38
+
39
+ const { optionalUniqueIndexedDocument } = dataContract.getDocuments();
40
+
41
+ expect(error.getIndexedProperties()).to.deep.equal(
42
+ optionalUniqueIndexedDocument.indices[1].properties.map((i) => Object.keys(i)[0]),
43
+ );
44
+
45
+ expect(error.getDocumentType()).to.equal('optionalUniqueIndexedDocument');
46
+ });
47
+
48
+ it('should return valid result if compound index contains no fields', () => {
49
+ const document = getDocumentsFixture(dataContract)[8];
50
+ document.setData({ });
51
+
52
+ documents = [document];
53
+
54
+ rawDocumentTransitions = getDocumentTransitionsFixture({
55
+ create: documents,
56
+ }).map((documentTransition) => documentTransition.toObject());
57
+
58
+ const result = validatePartialCompoundIndices(ownerId, rawDocumentTransitions, dataContract);
59
+
60
+ expect(result).to.be.an.instanceOf(ValidationResult);
61
+ expect(result.isValid()).to.be.true();
62
+ });
63
+
64
+ it('should return valid result if compound index contains all fields', () => {
65
+ documents = [getDocumentsFixture(dataContract)[8]];
66
+ rawDocumentTransitions = getDocumentTransitionsFixture({
67
+ create: documents,
68
+ }).map((documentTransition) => documentTransition.toObject());
69
+
70
+ const result = validatePartialCompoundIndices(ownerId, rawDocumentTransitions, dataContract);
71
+
72
+ expect(result).to.be.an.instanceOf(ValidationResult);
73
+ expect(result.isValid()).to.be.true();
74
+ });
75
+ });
@@ -0,0 +1,128 @@
1
+ const getDocumentsFixture = require('../../../../../../../lib/test/fixtures/getDocumentsFixture');
2
+ const getDocumentTransitionsFixture = require('../../../../../../../lib/test/fixtures/getDocumentTransitionsFixture');
3
+
4
+ const fetchDocumentsFactory = require('../../../../../../../lib/document/stateTransition/DocumentsBatchTransition/validation/state/fetchDocumentsFactory');
5
+
6
+ const createStateRepositoryMock = require('../../../../../../../lib/test/mocks/createStateRepositoryMock');
7
+
8
+ const generateRandomIdentifier = require('../../../../../../../lib/test/utils/generateRandomIdentifier');
9
+ const StateTransitionExecutionContext = require('../../../../../../../lib/stateTransition/StateTransitionExecutionContext');
10
+
11
+ describe('fetchDocumentsFactory', () => {
12
+ let fetchDocuments;
13
+ let stateRepositoryMock;
14
+ let documentTransitions;
15
+ let documents;
16
+ let executionContext;
17
+
18
+ beforeEach(function beforeEach() {
19
+ stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox);
20
+
21
+ fetchDocuments = fetchDocumentsFactory(stateRepositoryMock);
22
+
23
+ executionContext = new StateTransitionExecutionContext();
24
+
25
+ documents = getDocumentsFixture().slice(0, 5);
26
+
27
+ documentTransitions = getDocumentTransitionsFixture({
28
+ create: documents,
29
+ });
30
+ });
31
+
32
+ it('should fetch specified Documents using StateRepository', async () => {
33
+ const firstDocumentDataContractId = generateRandomIdentifier().toBuffer();
34
+
35
+ documentTransitions[0].dataContractId = firstDocumentDataContractId;
36
+ documents[0].dataContractId = firstDocumentDataContractId;
37
+
38
+ stateRepositoryMock.fetchDocuments.withArgs(
39
+ documentTransitions[0].getDataContractId(),
40
+ documentTransitions[0].getType(),
41
+ ).resolves([documents[0]]);
42
+
43
+ stateRepositoryMock.fetchDocuments.withArgs(
44
+ documentTransitions[1].getDataContractId(),
45
+ documentTransitions[1].getType(),
46
+ ).resolves([documents[1], documents[2]]);
47
+
48
+ stateRepositoryMock.fetchDocuments.withArgs(
49
+ documentTransitions[3].getDataContractId(),
50
+ documentTransitions[3].getType(),
51
+ ).resolves([documents[3], documents[4]]);
52
+
53
+ const fetchedDocuments = await fetchDocuments(documentTransitions, executionContext);
54
+
55
+ expect(stateRepositoryMock.fetchDocuments).to.have.been.calledThrice();
56
+
57
+ const callArgsOne = [
58
+ documents[0].getDataContractId(),
59
+ documents[0].getType(),
60
+ {
61
+ where: [
62
+ ['$id', 'in', [documents[0].getId()]],
63
+ ],
64
+ orderBy: [
65
+ [
66
+ '$id',
67
+ 'asc',
68
+ ],
69
+ ],
70
+ },
71
+ executionContext,
72
+ ];
73
+
74
+ const callArgsTwo = [
75
+ documents[1].getDataContractId(),
76
+ documents[1].getType(),
77
+ {
78
+ where: [
79
+ ['$id', 'in', [
80
+ documents[1].getId(),
81
+ documents[2].getId(),
82
+ ]],
83
+ ],
84
+ orderBy: [
85
+ [
86
+ '$id',
87
+ 'asc',
88
+ ],
89
+ ],
90
+ },
91
+ executionContext,
92
+ ];
93
+
94
+ const callArgsThree = [
95
+ documents[3].getDataContractId(),
96
+ documents[3].getType(),
97
+ {
98
+ where: [
99
+ ['$id', 'in', [
100
+ documents[3].getId(),
101
+ documents[4].getId(),
102
+ ]],
103
+ ],
104
+ orderBy: [
105
+ [
106
+ '$id',
107
+ 'asc',
108
+ ],
109
+ ],
110
+ },
111
+ executionContext,
112
+ ];
113
+
114
+ const callsArgs = [];
115
+ for (let i = 0; i < stateRepositoryMock.fetchDocuments.callCount; i++) {
116
+ const call = stateRepositoryMock.fetchDocuments.getCall(i);
117
+ callsArgs.push(call.args);
118
+ }
119
+
120
+ expect(callsArgs).to.have.deep.members([
121
+ callArgsOne,
122
+ callArgsTwo,
123
+ callArgsThree,
124
+ ]);
125
+
126
+ expect(fetchedDocuments).to.deep.equal(documents);
127
+ });
128
+ });