From 495c47d441c9c85ff9d3569325a1e3bff05e1356 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 09:32:28 +0100 Subject: [PATCH 01/11] Added generate ssid test --- src/index.spec.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/index.spec.js b/src/index.spec.js index 1b7c0b8..78b721b 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1,11 +1,29 @@ import { expect } from "chai"; import * as discipl from '../src/index.js'; -describe("index test", () => { - describe("getConnector function", () => { - it("should be able to get the memory connector", async () => { - const connector = await discipl.getConnector("memory"); - expect(connector.getName(), "memory") +describe("desciple-core-api", () => { + describe("The disciple core API", () => { + it("should be able to get the memory connector asynchronously", async () => { + const connector = await discipl.getConnector("memory") + expect(connector.getName()).to.equal("memory") + + expect(connector.getName(), "when loaded for the second time").to.equal("memory") + }) + + it("should be able to retrieve a new ssid asynchronously", async () => { + let ssid = await discipl.newSsid('memory') + + it("which should contain a large random public key, private key and connector object", () => { + expect(ssid.pubkey).to.be.a('string') + expect(ssid.pubkey.length).to.equal(88) + expect(ssid.privkey).to.be.a('string') + expect(ssid.privkey.length).to.equal(88) + expect(ssid.pubkey).to.not.equal(ssid.privkey) + expect(ssid.did).to.equal('did:discipl:memory:' + ssid.pubkey) + expect(ssid.connector.getName()).to.equal('memory') + }) }) }) }) + + From 2091418cbb7ab99d7b7d321f7b94dbc3e6ced887 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 09:59:57 +0100 Subject: [PATCH 02/11] Add claim test --- src/index.spec.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/index.spec.js b/src/index.spec.js index 78b721b..4d7c4f1 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -13,15 +13,22 @@ describe("desciple-core-api", () => { it("should be able to retrieve a new ssid asynchronously", async () => { let ssid = await discipl.newSsid('memory') - it("which should contain a large random public key, private key and connector object", () => { - expect(ssid.pubkey).to.be.a('string') - expect(ssid.pubkey.length).to.equal(88) - expect(ssid.privkey).to.be.a('string') - expect(ssid.privkey.length).to.equal(88) - expect(ssid.pubkey).to.not.equal(ssid.privkey) - expect(ssid.did).to.equal('did:discipl:memory:' + ssid.pubkey) - expect(ssid.connector.getName()).to.equal('memory') - }) + expect(ssid.pubkey).to.be.a('string') + expect(ssid.pubkey.length).to.equal(88) + expect(ssid.privkey).to.be.a('string') + expect(ssid.privkey.length).to.equal(88) + expect(ssid.pubkey).to.not.equal(ssid.privkey) + expect(ssid.did).to.equal('did:discipl:memory:' + ssid.pubkey) + expect(ssid.connector.getName()).to.equal('memory') + }) + + + it("should be able to add a first claim to some new channel through a claim() method", async () => { + let ssid = await discipl.newSsid('memory') + let claimlink = await discipl.claim(tmpSsid, {'need':'beer'}) + + expect(claimlink).to.be.a('string') + expect(claimlink.length).to.equal(108) }) }) }) From 6edc5e8a9b552f7cda5c5afeef0444e69f846922 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 14:50:28 +0100 Subject: [PATCH 03/11] Adding stubbed tests and registerConnector method --- package-lock.json | 110 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- src/index.js | 13 +++++- src/index.spec.js | 72 +++++++++++++++++++++++++++--- 4 files changed, 189 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e5af8e..dc3a05c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -762,6 +762,35 @@ "to-fast-properties": "^2.0.0" } }, + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, + "@sinonjs/samsam": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.0.2.tgz", + "integrity": "sha512-m08g4CS3J6lwRQk1pj1EO+KEVWbrbXsmi9Pw0ySmrIbcVxVaedoFgLvFsV8wHLwh01EpROVz3KvVcD1Jmks9FQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash.get": "^4.4.2" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -771,6 +800,12 @@ "color-convert": "^1.9.0" } }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -1093,6 +1128,12 @@ "loose-envify": "^1.0.0" } }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, "js-levenshtein": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz", @@ -1120,6 +1161,12 @@ "minimist": "^1.2.0" } }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -1136,6 +1183,18 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lolex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz", + "integrity": "sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ==", + "dev": true + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1221,6 +1280,27 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "nise": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", @@ -1305,6 +1385,15 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -1423,6 +1512,21 @@ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, + "sinon": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.2.tgz", + "integrity": "sha512-WLagdMHiEsrRmee3jr6IIDntOF4kbI6N2pfbi8wkv50qaUQcBglkzkjtoOEbeJ2vf1EsrHhLI+5Ny8//WHdMoA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.2.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.7", + "supports-color": "^5.5.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -1456,6 +1560,12 @@ "has-flag": "^3.0.0" } }, + "text-encoding": { + "version": "0.6.4", + "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", diff --git a/package.json b/package.json index 80ccff8..f34d57e 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "babel-plugin-dynamic-import-node": "^2.2.0", "chai": "^4.2.0", "discipl-core-memory": "git+https://github.com/discipl/discipl-core-memory.git", - "mocha": "^5.2.0" + "mocha": "^5.2.0", + "sinon": "^7.2.2" } } diff --git a/src/index.js b/src/index.js index 7ada41f..196a17c 100644 --- a/src/index.js +++ b/src/index.js @@ -20,7 +20,7 @@ const initializeConnector = async (connector) => { if(!Object.keys(disciplCoreConnectors).includes(connector)) { import(CONNECTOR_MODULE_PREFIX+connector).then(module => { let connectorModuleClass = module.default - disciplCoreConnectors[connector] = new connectorModuleClass() + registerConnector(connector, new connectorModuleClass()) }) } } @@ -33,6 +33,16 @@ const getConnector = async (connector) => { return disciplCoreConnectors[connector] } +/** + * Registers a connector explicitly. + * + * @param name of the connector. Packages containing a connector follow the naming convention CONNECTOR_MODULE_PREFIX + name + * @param connector instantiated object representing the connector + */ +const registerConnector = (name, connector) => { + disciplCoreConnectors[name] = connector; +} + /** * extracts connector name and reference from a link string and returns it as a json object in the form of: {connector, reference} */ @@ -268,6 +278,7 @@ const revoke = async (ssid, link) => { export { getConnector, + registerConnector, newSsid, claim, attest, diff --git a/src/index.spec.js b/src/index.spec.js index 4d7c4f1..d0e6197 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1,18 +1,21 @@ -import { expect } from "chai"; +import { expect, use } from "chai"; import * as discipl from '../src/index.js'; +import sinon from 'sinon'; + describe("desciple-core-api", () => { - describe("The disciple core API", () => { - it("should be able to get the memory connector asynchronously", async () => { + describe("The disciple core API with memory connector", () => { + + it("should be able to get the connector asynchronously", async () => { const connector = await discipl.getConnector("memory") expect(connector.getName()).to.equal("memory") - + expect(connector.getName(), "when loaded for the second time").to.equal("memory") }) it("should be able to retrieve a new ssid asynchronously", async () => { let ssid = await discipl.newSsid('memory') - + expect(ssid.pubkey).to.be.a('string') expect(ssid.pubkey.length).to.equal(88) expect(ssid.privkey).to.be.a('string') @@ -22,15 +25,70 @@ describe("desciple-core-api", () => { expect(ssid.connector.getName()).to.equal('memory') }) - it("should be able to add a first claim to some new channel through a claim() method", async () => { let ssid = await discipl.newSsid('memory') - let claimlink = await discipl.claim(tmpSsid, {'need':'beer'}) + let claimlink = await discipl.claim(ssid, {'need': 'beer'}) expect(claimlink).to.be.a('string') expect(claimlink.length).to.equal(108) }) + }, + describe("The disciple core API with mocked connector", () => { + + it("should be able to retrieve a new mocked ssid asynchronously", async () => { + let newSsidStub = sinon.stub().returns({pubkey: "".padStart(88,"1"), privkey: "".padStart(88,"2")}) + let getNameStub = sinon.stub().returns("mock") + let stubConnector = {newSsid: newSsidStub, getName: getNameStub}; + + + await discipl.registerConnector('mock', stubConnector) + let ssid = await discipl.newSsid('mock') + + expect(newSsidStub.calledOnce).to.equal(true) + expect(getNameStub.calledOnce).to.equal(true) + + expect(ssid.pubkey).to.equal("".padStart(88,"1")) + expect(ssid.privkey).to.equal("".padStart(88, "2")) + expect(ssid.did).to.equal('did:discipl:mock:' + "".padStart(88,"1")) + expect(ssid.connector.getName()).to.equal('mock') + }) + + it("should be able to add a claim to some new channel through a claim() method through a mocked connector", async () => { + let ssid = {did: 'did:discipl:mock:111'} + let claimStub = sinon.stub().returns("claimRef"); + let getNameStub = sinon.stub().returns("mock") + let stubConnector = {claim: claimStub, getName: getNameStub}; + + + await discipl.registerConnector('mock', stubConnector) + let claimlink = await discipl.claim(ssid, {'need':'beer'}) + + expect(claimStub.calledOnceWith({did: 'did:discipl:mock:111', connector: stubConnector, pubkey: '111'}, {'need':'beer'})).to.equal(true) + expect(getNameStub.calledOnce).to.be.equal(true) + + + expect(claimlink).to.equal('link:discipl:mock:claimRef') + }) + + it("should be able to add a claim to some new channel through a claim() method with an object as reference", async () => { + let ssid = {did: 'did:discipl:mock:111'} + let claimStub = sinon.stub().returns({someKey:"infoNeededByConnector"}); + let getNameStub = sinon.stub().returns("mock") + let stubConnector = {claim: claimStub, getName: getNameStub}; + + + await discipl.registerConnector('mock', stubConnector) + let claimlink = await discipl.claim(ssid, {'need':'beer'}) + + expect(claimStub.calledOnceWith({did: 'did:discipl:mock:111', connector: stubConnector, pubkey: '111'}, {'need':'beer'})).to.equal(true) + expect(getNameStub.calledOnce).to.be.equal(true) + + expect(claimlink).to.equal('link:discipl:mock:jdkIBFi8PojrrOV/Z9qtuS+8hDyUUMUkono9Rof4ZxlA6OIQjOWcHeSWGD73fn2I') + }) + + }) + ) }) From 25d0b51239e4a9799892ff019e31a2755dc86ff1 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 15:48:45 +0100 Subject: [PATCH 04/11] Add npm test back in to travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 090940a..b9cf79f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,6 @@ addons: sonarcloud: organization: "discipl" # the key of the org you chose at step #3 script: + - npm test # other script steps might be done before running the actual analysis - sonar-scanner From dffebf4b699f043ca44a5a03e8a4765bdb559f97 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 15:55:28 +0100 Subject: [PATCH 05/11] Make sonar scanner conditional on non-pr --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b9cf79f..e4aa5bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ addons: script: - npm test # other script steps might be done before running the actual analysis - - sonar-scanner + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then sonar-scanner; fi' From 6452111ea2c2871304236d39b40eea72e1ad431b Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Wed, 19 Dec 2018 16:23:16 +0100 Subject: [PATCH 06/11] Adding claim retrival tests --- src/index.spec.js | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/index.spec.js b/src/index.spec.js index d0e6197..19930da 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1,4 +1,4 @@ -import { expect, use } from "chai"; +import { expect } from "chai"; import * as discipl from '../src/index.js'; import sinon from 'sinon'; @@ -32,9 +32,19 @@ describe("desciple-core-api", () => { expect(claimlink).to.be.a('string') expect(claimlink.length).to.equal(108) }) + + it("should be able to get a claim added through claim, with link to previous", async () => { + let ssid = await discipl.newSsid('memory') + let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) + + let claim = await discipl.get(claimlink2) + expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) + expect(claim.previous).to.equal(claimlink1) + + }) }, describe("The disciple core API with mocked connector", () => { - it("should be able to retrieve a new mocked ssid asynchronously", async () => { let newSsidStub = sinon.stub().returns({pubkey: "".padStart(88,"1"), privkey: "".padStart(88,"2")}) let getNameStub = sinon.stub().returns("mock") @@ -64,7 +74,7 @@ describe("desciple-core-api", () => { let claimlink = await discipl.claim(ssid, {'need':'beer'}) expect(claimStub.calledOnceWith({did: 'did:discipl:mock:111', connector: stubConnector, pubkey: '111'}, {'need':'beer'})).to.equal(true) - expect(getNameStub.calledOnce).to.be.equal(true) + expect(getNameStub.calledOnce).to.equal(true) expect(claimlink).to.equal('link:discipl:mock:claimRef') @@ -81,12 +91,30 @@ describe("desciple-core-api", () => { let claimlink = await discipl.claim(ssid, {'need':'beer'}) expect(claimStub.calledOnceWith({did: 'did:discipl:mock:111', connector: stubConnector, pubkey: '111'}, {'need':'beer'})).to.equal(true) - expect(getNameStub.calledOnce).to.be.equal(true) + expect(getNameStub.calledOnce).to.equal(true) expect(claimlink).to.equal('link:discipl:mock:jdkIBFi8PojrrOV/Z9qtuS+8hDyUUMUkono9Rof4ZxlA6OIQjOWcHeSWGD73fn2I') }) + it("should be able to get a claim added through claims", async () => { + let claimlink = 'link:discipl:mock:claimRef' + let prevClaimlink = 'link:discipl:mock:previous' + let getStub = sinon.stub().returns({'data':{'need': 'wine'}, 'previous': 'previous'}) + let getNameStub = sinon.stub().returns("mock") + + let stubConnector = {get: getStub, getName: getNameStub} + await discipl.registerConnector('mock', stubConnector) + + let claim = await discipl.get(claimlink) + + expect(getStub.calledOnceWith("claimRef", null)).to.equal(true) + expect(getNameStub.calledOnce).to.equal(true) + + expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) + expect(claim.previous).to.equal(prevClaimlink) + + }) }) ) }) From cdabee6ba15d4fe6e37136cfe99d2704f5e05bcd Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Thu, 20 Dec 2018 09:43:53 +0100 Subject: [PATCH 07/11] Attestation tests --- src/index.spec.js | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/index.spec.js b/src/index.spec.js index 19930da..c27a9d7 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -38,10 +38,27 @@ describe("desciple-core-api", () => { let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) + let claim = await discipl.get(claimlink2) + + + let attestorSsid = await discipl.newSsid('memory') + + let attestationLink = await discipl.attest(attestorSsid, 'agree', claimlink2); + + let attestation = await discipl.get(attestationLink) + + expect(attestation.data.agree).to.equal(claimlink2) + expect(attestation.previous).to.equal(null) + }) + + it("should be able to attest to a second claim in a chain", async () => { + let ssid = await discipl.newSsid('memory') + let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) + let claim = await discipl.get(claimlink2) expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) expect(claim.previous).to.equal(claimlink1) - }) }, describe("The disciple core API with mocked connector", () => { @@ -113,7 +130,23 @@ describe("desciple-core-api", () => { expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) expect(claim.previous).to.equal(prevClaimlink) + }) + + it("should be able to attest a claim", async() => { + let ssid = {did: 'did:discipl:mock:111'} + let claimlink = 'link:discipl:mock:claimRef' + + let claimStub = sinon.stub().returns("attestationRef") + let getNameStub = sinon.stub().returns("mock") + let stubConnector = {claim: claimStub, getName: getNameStub} + + await discipl.registerConnector('mock', stubConnector) + + let attestationLink = await discipl.attest(ssid, 'agree', claimlink); + expect(getNameStub.calledOnce).to.equal(true) + expect(claimStub.calledOnceWith({did: 'did:discipl:mock:111', connector: stubConnector, pubkey: '111'}, {'agree':claimlink})).to.equal(true) + expect(attestationLink).to.equal('link:discipl:mock:attestationRef') }) }) ) From bece3b05ee460da0275ce9248095a33ae33e1299 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Thu, 20 Dec 2018 12:09:03 +0100 Subject: [PATCH 08/11] Attestation revocation tests --- src/index.spec.js | 110 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/src/index.spec.js b/src/index.spec.js index c27a9d7..0578c45 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -39,7 +39,14 @@ describe("desciple-core-api", () => { let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) let claim = await discipl.get(claimlink2) + expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) + expect(claim.previous).to.equal(claimlink1) + }) + it("should be able to attest to a second claim in a chain", async () => { + let ssid = await discipl.newSsid('memory') + let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) let attestorSsid = await discipl.newSsid('memory') @@ -51,14 +58,18 @@ describe("desciple-core-api", () => { expect(attestation.previous).to.equal(null) }) - it("should be able to attest to a second claim in a chain", async () => { + it("should be able to verify an attestation", async () => { let ssid = await discipl.newSsid('memory') let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) - let claim = await discipl.get(claimlink2) - expect(JSON.stringify(claim.data)).to.equal(JSON.stringify({'need':'wine'})) - expect(claim.previous).to.equal(claimlink1) + let attestorSsid = await discipl.newSsid('memory') + + let attestationLink = await discipl.attest(attestorSsid, 'agree', claimlink2); + + let verifiedAttestor = await discipl.verify('agree', claimlink2, [ssid, null, {'did':'did:discipl:memory:1234'}, attestorSsid]) + + expect(verifiedAttestor).to.equal(attestorSsid) }) }, describe("The disciple core API with mocked connector", () => { @@ -148,6 +159,97 @@ describe("desciple-core-api", () => { expect(attestationLink).to.equal('link:discipl:mock:attestationRef') }) + + it("should be able to verify an attestation", async() => { + let ssid = {did: 'did:discipl:mock:111'} + let attestorSsid = {did: 'did:discipl:mock:attestor'} + let claimlink = 'link:discipl:mock:claimRef' + let attestationlink = 'link:discipl:mock:attestationRef' + + let verifyStub = sinon.stub() + + verifyStub.onCall(0).returns('attestationRef') + verifyStub.onCall(1).returns(null) + verifyStub.onCall(2).returns(null) + + let getNameStub = sinon.stub().returns("mock") + + let getSsidOfClaimStub = sinon.stub().returns({pubkey: "111"}) + + let stubConnector = {verify: verifyStub, getName: getNameStub, getSsidOfClaim: getSsidOfClaimStub} + + await discipl.registerConnector('mock', stubConnector) + + let verifiedAttestor = await discipl.verify('agree', claimlink, [attestorSsid]) + + expect(verifyStub.calledThrice).to.equal(true) + expect(verifyStub.args[0]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {agree: claimlink}]) + expect(verifyStub.args[1]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {revoke: attestationlink}]) + expect(verifyStub.args[2]).to.deep.equal([{did: ssid.did, connector: stubConnector, pubkey: '111'}, {revoke: claimlink}]) + expect(getNameStub.calledTwice).to.equal(true) + expect(getSsidOfClaimStub.calledOnce).to.equal(true) + expect(getSsidOfClaimStub.args[0]).to.deep.equal(['claimRef']) + expect(verifiedAttestor.did).to.equal(attestorSsid.did) + }) + + it("should not be able to verify an attestation, if there is no matching claim", async() => { + let attestorSsid = {did: 'did:discipl:mock:attestor'} + let claimlink = 'link:discipl:mock:claimRef' + + let verifyStub = sinon.stub().returns(null) + + let stubConnector = {verify: verifyStub} + + await discipl.registerConnector('mock', stubConnector) + + let verifiedAttestor = await discipl.verify('agree', claimlink, [attestorSsid]) + + expect(verifyStub.calledOnce).to.equal(true) + expect(verifyStub.args[0]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {agree: claimlink}]) + + expect(verifiedAttestor).to.equal(null) + }) + + it("should not be able to verify an attestation, if the attestation is revoked", async() => { + let ssid = {did: 'did:discipl:mock:111'} + let attestorSsid = {did: 'did:discipl:mock:attestor'} + let claimlink = 'link:discipl:mock:claimRef' + let attestationlink = 'link:discipl:mock:attestationRef' + let attestationrevocationlink = 'link:discipl:mock:attestationRevocationRef' + + let verifyStub = sinon.stub() + + verifyStub.onCall(0).returns('attestationRef') + verifyStub.onCall(1).returns('attestationRevocationRef') + verifyStub.onCall(2).returns(null) + verifyStub.onCall(3).returns(null) + + let getSsidOfClaimStub = sinon.stub().returns({pubkey: "attestor"}) + + let getNameStub = sinon.stub().returns("mock") + + + let stubConnector = {verify: verifyStub, getName: getNameStub, getSsidOfClaim: getSsidOfClaimStub} + + await discipl.registerConnector('mock', stubConnector) + + let verifiedAttestor = await discipl.verify('agree', claimlink, [attestorSsid]) + + expect(verifyStub.callCount).to.equal(4) + expect(verifyStub.args[0]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {agree: claimlink}]) + expect(verifyStub.args[1]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {revoke: attestationlink}]) + expect(verifyStub.args[2]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {revoke: attestationrevocationlink}]) + expect(verifyStub.args[3]).to.deep.equal([{did: 'did:discipl:mock:attestor', connector: stubConnector, pubkey: 'attestor'}, {revoke: attestationlink}]) + + expect(getSsidOfClaimStub.calledOnce).to.equal(true) + expect(getSsidOfClaimStub.args[0]).to.deep.equal(['attestationRef']) + + expect(getNameStub.callCount).to.equal(3) + + expect(verifiedAttestor).to.equal(null) + }) + + }) ) }) From 921f4ea496b1884bbc9242d1c408d7edf5788067 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Thu, 20 Dec 2018 13:23:19 +0100 Subject: [PATCH 09/11] Adding export integration test --- src/index.js | 11 +++++------ src/index.spec.js | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 196a17c..5d7dc7a 100644 --- a/src/index.js +++ b/src/index.js @@ -18,10 +18,9 @@ var disciplCoreConnectors = [] */ const initializeConnector = async (connector) => { if(!Object.keys(disciplCoreConnectors).includes(connector)) { - import(CONNECTOR_MODULE_PREFIX+connector).then(module => { - let connectorModuleClass = module.default - registerConnector(connector, new connectorModuleClass()) - }) + let module = await import(CONNECTOR_MODULE_PREFIX+connector); + let connectorModuleClass = module.default + registerConnector(connector, new connectorModuleClass()) } } @@ -243,13 +242,13 @@ const exportLD = async (SsidDidOrLink, maxdepth = 3, ssid = null, visitedStack = let res = await get(currentLink, ssid) if(res != null) { - data = res.data + let data = res.data if(res.previous && (SsidDidOrLink.indexOf(DID_PREFIX) == 0)) { console.log('Get previous of channel'+res.previous) exportData[currentSsid.did] = await exportLD(res.previous, maxdepth, ssid, visitedStack) } exportData[currentSsid.did][currentLink] = {} - for(elem in data) { + for(let elem in data) { exportData[currentSsid.did][currentLink][elem] = {} let value = data[elem] try { diff --git a/src/index.spec.js b/src/index.spec.js index 0578c45..d18836e 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1,4 +1,4 @@ -import { expect } from "chai"; +import {expect} from "chai"; import * as discipl from '../src/index.js'; import sinon from 'sinon'; @@ -71,6 +71,20 @@ describe("desciple-core-api", () => { expect(verifiedAttestor).to.equal(attestorSsid) }) + + it("should be able to export linked verifiable claim channels", async () => { + let ssid = await discipl.newSsid('memory') + let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) + + let attestorSsid = await discipl.newSsid('memory') + + let attestationLink = await discipl.attest(attestorSsid, 'agree', claimlink2); + let exportedData = await discipl.exportLD(attestorSsid) + + + expect(exportedData[attestorSsid.did][attestationLink]['agree'][ssid.did][claimlink2]).to.deep.equal({'need': 'wine'}) + }) }, describe("The disciple core API with mocked connector", () => { it("should be able to retrieve a new mocked ssid asynchronously", async () => { From 6db6e958e738f63c222591a8be05d28631757cc2 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Thu, 20 Dec 2018 13:24:56 +0100 Subject: [PATCH 10/11] Removing unused variables --- src/index.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.spec.js b/src/index.spec.js index d18836e..e391d5d 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -45,7 +45,7 @@ describe("desciple-core-api", () => { it("should be able to attest to a second claim in a chain", async () => { let ssid = await discipl.newSsid('memory') - let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + await discipl.claim(ssid, {'need': 'beer'}) let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) let attestorSsid = await discipl.newSsid('memory') @@ -60,12 +60,12 @@ describe("desciple-core-api", () => { it("should be able to verify an attestation", async () => { let ssid = await discipl.newSsid('memory') - let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + await discipl.claim(ssid, {'need': 'beer'}) let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) let attestorSsid = await discipl.newSsid('memory') - let attestationLink = await discipl.attest(attestorSsid, 'agree', claimlink2); + await discipl.attest(attestorSsid, 'agree', claimlink2); let verifiedAttestor = await discipl.verify('agree', claimlink2, [ssid, null, {'did':'did:discipl:memory:1234'}, attestorSsid]) @@ -74,7 +74,7 @@ describe("desciple-core-api", () => { it("should be able to export linked verifiable claim channels", async () => { let ssid = await discipl.newSsid('memory') - let claimlink1 = await discipl.claim(ssid, {'need': 'beer'}) + await discipl.claim(ssid, {'need': 'beer'}) let claimlink2 = await discipl.claim(ssid, {'need': 'wine'}) let attestorSsid = await discipl.newSsid('memory') From c70d470030806eb64bcaac498ef9d50c9dd96286 Mon Sep 17 00:00:00 2001 From: Pim Otte Date: Thu, 20 Dec 2018 13:31:31 +0100 Subject: [PATCH 11/11] Comments for most convoluted parts --- src/index.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.spec.js b/src/index.spec.js index e391d5d..cc2c404 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -69,6 +69,7 @@ describe("desciple-core-api", () => { let verifiedAttestor = await discipl.verify('agree', claimlink2, [ssid, null, {'did':'did:discipl:memory:1234'}, attestorSsid]) + // The first ssid that is valid and proves the attestation should be returned expect(verifiedAttestor).to.equal(attestorSsid) }) @@ -183,6 +184,7 @@ describe("desciple-core-api", () => { let verifyStub = sinon.stub() verifyStub.onCall(0).returns('attestationRef') + // No revocations will be found verifyStub.onCall(1).returns(null) verifyStub.onCall(2).returns(null) @@ -234,7 +236,9 @@ describe("desciple-core-api", () => { let verifyStub = sinon.stub() verifyStub.onCall(0).returns('attestationRef') + // A revocation of the attestation will be found verifyStub.onCall(1).returns('attestationRevocationRef') + // No revocations of the revocation of the attestation will be found verifyStub.onCall(2).returns(null) verifyStub.onCall(3).returns(null)