@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,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
|
+
});
|