From 7aa326f55b0f81f93e7e097102abaa274a4dac68 Mon Sep 17 00:00:00 2001 From: varsha Date: Mon, 19 Dec 2022 10:31:04 +0530 Subject: [PATCH 1/2] test case using chai and mocha --- package.json | 95 +++--- src/constants.ts | 122 ++++---- src/did/did.ts | 6 +- src/tests/config.ts | 41 +++ src/tests/did.ts | 380 ++++++++++++++++++++++++ src/tests/didRpc.ts | 244 ++++++++++++++++ src/tests/schema.ts | 214 ++++++++++++++ src/tests/schemaRpc.ts | 236 +++++++++++++++ src/tests/vc.ts | 648 +++++++++++++++++++++++++++++++++++++++++ test/ssi/schema.js | 2 +- 10 files changed, 1876 insertions(+), 112 deletions(-) create mode 100644 src/tests/config.ts create mode 100644 src/tests/did.ts create mode 100644 src/tests/didRpc.ts create mode 100644 src/tests/schema.ts create mode 100644 src/tests/schemaRpc.ts create mode 100644 src/tests/vc.ts diff --git a/package.json b/package.json index 6bf2d76..6f22886 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,52 @@ { - "name": "hs-ssi-sdk", - "version": "6.2.0", - "description": "sdk is an implementation of proposed DID by W3C", - "main": "build/src/index.js", - "scripts": { - "test": "cd test/ssi && node did.js && node private-did.js && node schema.js && cd credentials && node test1.js && node test2.js", - "start": "node build/index.js", - "build": "npm run lint:fix && npm run prettier && rimraf build && tsc -p .", - "prettier": "prettier --config .prettierrc.json --write src/**/*.ts", - "prepublish": "npm run build", - "lint": "eslint . --ext .ts", - "lint:fix": "npm run lint -- --fix", - "prepare": "husky install" - }, - "author": "Hypersign Team", - "license": "ISC", - "dependencies": { - "@cosmjs/proto-signing": "^0.27.0", - "@cosmjs/stargate": "^0.27.0", - "@digitalbazaar/ed25519-signature-2020": "^3.0.0", - "@digitalbazaar/ed25519-verification-key-2018": "^3.1.2", - "@digitalbazaar/ed25519-verification-key-2020": "^3.3.0", - "@stablelib/ed25519": "^1.0.2", - "axios": "^0.19.0", - "crypto-ld": "^6.0.0", - "jsonld": "^3.1.1", - "jsonld-signatures": "^9.0.0", - "node-fetch": "^2.6.1", - "protobufjs": "^6.11.2", - "uuid": "^8.3.0", - "vc-js": "https://github.com/hypersign-protocol/vc-js" - }, - "devDependencies": { - "@types/jest": "^27.5.1", - "@types/node": "^14.11.2", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", - "eslint": "^7.32.0", - "husky": "^7.0.4", - "jest": "^28.1.0", - "prettier": "^2.4.1", - "rimraf": "^3.0.2", - "ts-jest": "^28.0.3", - "typescript": "^4.5.5" - } + "name": "hs-ssi-sdk", + "version": "6.2.0", + "description": "sdk is an implementation of proposed DID by W3C", + "main": "build/src/index.js", + "scripts": { + "test": "cd test/ssi && node did.js && node private-did.js && node schema.js && cd credentials && node test1.js && node test2.js", + "test_chai": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register 'src/tests/*.ts' --exit --timeout 40000", + "start": "node build/index.js", + "build": "npm run lint:fix && npm run prettier && rimraf build && tsc -p .", + "prettier": "prettier --config .prettierrc.json --write src/**/*.ts", + "prepublish": "npm run build", + "lint": "eslint . --ext .ts", + "lint:fix": "npm run lint -- --fix", + "prepare": "husky install" + }, + "author": "Hypersign Team", + "license": "ISC", + "dependencies": { + "@cosmjs/proto-signing": "^0.27.0", + "@cosmjs/stargate": "^0.27.0", + "@digitalbazaar/ed25519-signature-2020": "^3.0.0", + "@digitalbazaar/ed25519-verification-key-2018": "^3.1.2", + "@digitalbazaar/ed25519-verification-key-2020": "^3.3.0", + "@stablelib/ed25519": "^1.0.2", + "axios": "^0.19.0", + "crypto-ld": "^6.0.0", + "jsonld": "^3.1.1", + "jsonld-signatures": "^9.0.0", + "node-fetch": "^2.6.1", + "protobufjs": "^6.11.2", + "uuid": "^8.3.0", + "vc-js": "https://github.com/hypersign-protocol/vc-js" + }, + "devDependencies": { + "@types/chai": "^4.3.4", + "@types/mocha": "^10.0.1", + "@types/node": "^14.11.2", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", + "chai": "^4.3.7", + "eslint": "^7.32.0", + "husky": "^7.0.4", + "jest": "^28.1.0", + "mocha": "^10.2.0", + "prettier": "^2.4.1", + "rimraf": "^3.0.2", + "ts-jest": "^28.0.3", + "ts-node": "^10.9.1", + "typescript": "^4.5.5" + } } diff --git a/src/constants.ts b/src/constants.ts index 2fbdada..197bed8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,85 +1,81 @@ -"use strict" +'use strict'; export const compactProof = false; +export const HYPERSIGN_TESTNET_RPC = 'http://localhost:26657'; +export const HYPERSIGN_TESTNET_REST = 'http://localhost:1317'; -export const HYPERSIGN_TESTNET_RPC ="http://localhost:26657" -export const HYPERSIGN_TESTNET_REST="http://localhost:1317" +export const HYPERSIGN_MAINNET_RPC = 'http://localhost:26657'; +export const HYPERSIGN_MAINNET_REST = 'http://localhost:1317'; -export const HYPERSIGN_MAINNET_RPC ="http://localhost:26657" -export const HYPERSIGN_MAINNET_REST="http://localhost:1317" - -export const HID_COSMOS_MODULE='/hypersignprotocol.hidnode.ssi' -export const HYPERSIGN_NETWORK_DID_PATH="hypersign-protocol/hidnode/ssi/did" -export const HYPERSIGN_NETWORK_SCHEMA_PATH="hypersign-protocol/hidnode/ssi/schema" -export const HYPERSIGN_NETWORK_CREDENTIALSTATUS_PATH="hypersign-protocol/hidnode/ssi/credential" -export const HYPERSIGN_NETWORK_BANK_BALANCE_PATH="/bank/balances/" +export const HID_COSMOS_MODULE = '/hypersignprotocol.hidnode.ssi'; +export const HYPERSIGN_NETWORK_DID_PATH = 'hypersign-protocol/hidnode/ssi/did'; +export const HYPERSIGN_NETWORK_SCHEMA_PATH = 'hypersign-protocol/hidnode/ssi/schema'; +export const HYPERSIGN_NETWORK_CREDENTIALSTATUS_PATH = 'hypersign-protocol/hidnode/ssi/credential'; +export const HYPERSIGN_NETWORK_BANK_BALANCE_PATH = '/bank/balances/'; export enum HIDRpcEnums { - MsgCreateDID = "MsgCreateDID", - MsgUpdateDID = "MsgUpdateDID", - MsgDeactivateDID = "MsgDeactivateDID", - MsgCreateSchema = "MsgCreateSchema", - MsgRegisterCredentialStatus= "MsgRegisterCredentialStatus" + MsgCreateDID = 'MsgCreateDID', + MsgUpdateDID = 'MsgUpdateDID', + MsgDeactivateDID = 'MsgDeactivateDID', + MsgCreateSchema = 'MsgCreateSchema', + MsgRegisterCredentialStatus = 'MsgRegisterCredentialStatus', } -Object.freeze(HIDRpcEnums) +Object.freeze(HIDRpcEnums); export enum CredentialStatusEnums { - LIVE = "Live" + LIVE = 'Live', } - export const DID = { - CONTROLLER_CONTEXT: "https://w3id.org/security/v2", - SCHEME: "did", - METHOD: "hid", - NAMESPACE:"devnet", // this is not used - DID_BASE_CONTEXT: "https://www.w3.org/ns/did/v1", - VERIFICATION_METHOD_TYPE: "Ed25519VerificationKey2020" -} -Object.freeze(DID) + CONTROLLER_CONTEXT: 'https://w3id.org/security/v2', + SCHEME: 'did', + METHOD: 'hid', + NAMESPACE: 'devnet', // this is not used + DID_BASE_CONTEXT: 'https://www.w3.org/ns/did/v1', + VERIFICATION_METHOD_TYPE: 'Ed25519VerificationKey2020', +}; +Object.freeze(DID); export const VC = { - SCHEME: "vc", - METHOD: "hid", - NAMESPACE:"devnet", - PREFIX: "vc:" + DID.METHOD + ":" + DID.NAMESPACE + ":", - CREDENTAIL_SCHEMA_VALIDATOR_TYPE: "JsonSchemaValidator2018", - CREDENTAIL_STATUS_TYPE: "CredentialStatusList2017", - CREDENTAIL_BASE_CONTEXT: "https://www.w3.org/2018/credentials/v1", - CREDENTAIL_SECURITY_CONTEXT_V2: "https://w3id.org/security/v2", - CREDENTAIL_SECURITY_SUITE: "https://w3id.org/security/suites/ed25519-2020/v1", - PROOF_PURPOSE: "assertion", - VERIFICATION_METHOD_TYPE: "Ed25519VerificationKey2020", - CRED_STATUS_TYPES: CredentialStatusEnums -} -Object.freeze(VC) + SCHEME: 'vc', + METHOD: 'hid', + NAMESPACE: 'devnet', + PREFIX: 'vc:' + DID.METHOD + ':' + DID.NAMESPACE + ':', + CREDENTAIL_SCHEMA_VALIDATOR_TYPE: 'JsonSchemaValidator2018', + CREDENTAIL_STATUS_TYPE: 'CredentialStatusList2017', + CREDENTAIL_BASE_CONTEXT: 'https://www.w3.org/2018/credentials/v1', + CREDENTAIL_SECURITY_CONTEXT_V2: 'https://w3id.org/security/v2', + CREDENTAIL_SECURITY_SUITE: 'https://w3id.org/security/suites/ed25519-2020/v1', + PROOF_PURPOSE: 'assertion', + VERIFICATION_METHOD_TYPE: 'Ed25519Signature2020', + CRED_STATUS_TYPES: CredentialStatusEnums, +}; +Object.freeze(VC); export const VP = { - PREFIX: "vp:", - SCHEME: "vp", - METHOD: "hid", - NAMESPACE:"devnet", -} -Object.freeze(VP) + PREFIX: 'vp:', + SCHEME: 'vp', + METHOD: 'hid', + NAMESPACE: 'devnet', +}; +Object.freeze(VP); export const SCHEMA = { - SCHEME: "sch", - METHOD: "hid", - NAMESPACE:"devnet", - SCHEMA_JSON: 'http://json-schema.org/draft-07/schema', - SCHEMA_TYPE: 'https://w3c-ccg.github.io/vc-json-schemas/v1/schema/1.0/schema.json' -} -Object.freeze(SCHEMA) + SCHEME: 'sch', + METHOD: 'hid', + NAMESPACE: 'devnet', + SCHEMA_JSON: 'http://json-schema.org/draft-07/schema', + SCHEMA_TYPE: 'https://w3c-ccg.github.io/vc-json-schemas/v1/schema/1.0/schema.json', +}; +Object.freeze(SCHEMA); export const KEY_HEADERS = { - MULTICODEC_ED25519_PUB_HEADER : new Uint8Array([0xed, 0x01]), - MULTICODEC_ED25519_PRIV_HEADER : new Uint8Array([0x80, 0x26]) -} -Object.freeze(KEY_HEADERS) + MULTICODEC_ED25519_PUB_HEADER: new Uint8Array([0xed, 0x01]), + MULTICODEC_ED25519_PRIV_HEADER: new Uint8Array([0x80, 0x26]), +}; +Object.freeze(KEY_HEADERS); -export const GAS_PRICE='0.1'; +export const GAS_PRICE = '0.1'; export const HID_DECIMAL = 6; export const HID_DNOMINATION = 'uhid'; -export const HID_MIN_GAS='200000' -export const HID_MIN_FEE='5000' - - +export const HID_MIN_GAS = '200000'; +export const HID_MIN_FEE = '5000'; diff --git a/src/did/did.ts b/src/did/did.ts index 100c338..c378459 100644 --- a/src/did/did.ts +++ b/src/did/did.ts @@ -121,7 +121,7 @@ export default class HypersignDID implements IDID { throw new Error('HID-SSI-SDK:: Error: params.privateKeyMultibase is required to register a did'); } - if (!params.privateKeyMultibase) { + if (!params.verificationMethodId) { throw new Error('HID-SSI-SDK:: Error: params.verificationMethodId is required to register a did'); } @@ -164,7 +164,7 @@ export default class HypersignDID implements IDID { throw new Error('HID-SSI-SDK:: Error: params.privateKeyMultibase is required to update a did'); } - if (!params.privateKeyMultibase) { + if (!params.verificationMethodId) { throw new Error('HID-SSI-SDK:: Error: params.verificationMethodId is required to update a did'); } if (!params.versionId) { @@ -191,7 +191,7 @@ export default class HypersignDID implements IDID { throw new Error('HID-SSI-SDK:: Error: params.privateKeyMultibase is required to deactivate a did'); } - if (!params.privateKeyMultibase) { + if (!params.verificationMethodId) { throw new Error('HID-SSI-SDK:: Error: params.verificationMethodId is required to deactivate a did'); } if (!params.versionId) { diff --git a/src/tests/config.ts b/src/tests/config.ts new file mode 100644 index 0000000..fa481e3 --- /dev/null +++ b/src/tests/config.ts @@ -0,0 +1,41 @@ +const { DirectSecp256k1HdWallet } = require('@cosmjs/proto-signing'); +const { HdPath, Slip10RawIndex } = require('@cosmjs/crypto'); + +export const mnemonic = + 'zero require alcohol swamp hover punch celery common merge embrace flock dumb unit capital problem future canal improve auto home apple avoid tragic mechanic'; //"judge harvest lion steak possible ship dog outside local hunt portion fix blast answer walnut injury food clever hen wrist casual humble script alter"//"napkin delay purchase easily camp mimic share wait stereo reflect allow soccer believe exhibit laptop upset tired talent transfer talk surface solution omit crack" + +export const hidNodeEp = { + rpc: 'https://jagrat.hypersign.id/rpc', + rest: 'https://jagrat.hypersign.id/rest', + namespace: 'testnet', +}; +export function makeCosmoshubPath(a) { + return [ + Slip10RawIndex.hardened(44), + Slip10RawIndex.hardened(118), + Slip10RawIndex.hardened(0), + Slip10RawIndex.normal(0), + Slip10RawIndex.normal(a), + ]; +} + +export const createWallet = async (mnemonic) => { + let options; + if (!mnemonic) { + return await DirectSecp256k1HdWallet.generate( + 24, + (options = { + prefix: 'hid', + hdPaths: [makeCosmoshubPath(0)], + }) + ); + } else { + return await DirectSecp256k1HdWallet.fromMnemonic( + mnemonic, + (options = { + prefix: 'hid', + hdPaths: [makeCosmoshubPath(0)], + }) + ); + } +}; diff --git a/src/tests/did.ts b/src/tests/did.ts new file mode 100644 index 0000000..bf627cd --- /dev/null +++ b/src/tests/did.ts @@ -0,0 +1,380 @@ +import HypersignDID from '../did/did'; +import { expect, should } from 'chai'; +import { IPublicKey, IController } from '../did/IDID'; +const hypersignDid = new HypersignDID(); +const seed = ''; +let privateKeyMultibase; +let publicKeyMultibase; +let verificationMethodId; +let didDocument; +let didDocId; +let signedDocument; +const challenge = '1231231231'; +const domain = 'www.adbv.com'; + +describe('#generateKeys() method to generate publicKyeMultibase and privateKeyMultiBase', function () { + it('should return publickeyMultibase and privateKeyMultibase', async function () { + const result = await hypersignDid.generateKeys({ seed }); + privateKeyMultibase = result.privateKeyMultibase; + publicKeyMultibase = result.publicKeyMultibase; + expect(result).to.be.a('object'); + should().exist(result.privateKeyMultibase); + should().exist(result.publicKeyMultibase); + }); +}); +describe('#generate() method to generate did document', function () { + it('should not able to generate did document and throw error as publickKeyMultibase is not passed or it is empty', function () { + return hypersignDid.generate({ publicKeyMultibase: '' }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.publicKeyMultibase is required to generate new did didoc'); + }); + }); + it('should return didDocument', async function () { + didDocument = await hypersignDid.generate({ publicKeyMultibase }); + didDocId = didDocument['id']; + verificationMethodId = didDocument['verificationMethod'][0].id; + expect(didDocument).to.be.a('object'); + should().exist(didDocument['@context']); + should().exist(didDocument['id']); + should().exist(didDocument['controller']); + should().exist(didDocument['alsoKnownAs']); + + should().exist(didDocument['verificationMethod']); + expect( + didDocument['verificationMethod'] && + didDocument['authentication'] && + didDocument['assertionMethod'] && + didDocument['keyAgreement'] && + didDocument['capabilityInvocation'] && + didDocument['capabilityDelegation'] && + didDocument['service'] + ).to.be.a('array'); + should().exist(didDocument['authentication']); + should().exist(didDocument['assertionMethod']); + should().exist(didDocument['keyAgreement']); + should().exist(didDocument['capabilityInvocation']); + should().exist(didDocument['capabilityDelegation']); + should().exist(didDocument['service']); + }); +}); +describe('#sign() this is to sign didDoc', function () { + const publicKey: IPublicKey = { + '@context': '', + id: '', + type: '', + publicKeyBase58: '', + }; + const controller: IController = { + '@context': '', + id: '', + authentication: [], + }; + + it('should not able to sign did document and throw error as privateKey is not passed or it is empty', function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: didDocId, + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + params.privateKey = ''; + return hypersignDid.signDid(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKey is required to sign a did'); + }); + }); + it('should not able to sign did document and throw error as challenge is not passed or it is empty', function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: didDocId, + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + params.challenge = ''; + return hypersignDid.signDid(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.challenge is required to sign a did'); + }); + }); + it('should not able to sign did document and throw error as domain is not passed or it is empty', function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: didDocId, + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + params.domain = ''; + return hypersignDid.signDid(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.domain is required to sign a did'); + }); + }); + it('should not able to sign did document and throw error as did is not resolved', function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: didDocId as string, + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + return hypersignDid.signDid(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.did is required to resolve a public did'); + }); + }); + // it('should not able to sign did document and throw error as neither did nor doc is passed', function () { + // const params = { + // privateKey: privateKeyMultibase as string, + // challenge: challenge as string, + // domain: domain as string, + // did: didDocId as string, + // doc: didDocId, + // verificationMethodId: verificationMethodId as string, + // publicKey, + // controller, + // }; + // params.did = ''; + // return hypersignDid.signDid(params).catch(function (err) { + // expect(function () { + // throw err; + // }).to.throw(Error, 'HID-SSI-SDK:: Error: params.did or params.doc is required to sign a did'); + // }); + // }); + it('should able to sign did document', async function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: '', + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + signedDocument = await hypersignDid.signDid(params); + expect(signedDocument).to.be.a('object'); + signedDocument = signedDocument.signedDidDocument; + should().exist(signedDocument['@context']); + should().exist(signedDocument['id']); + expect(didDocId).to.be.equal(signedDocument['id']); + should().exist(signedDocument['controller']); + should().exist(signedDocument['alsoKnownAs']); + should().exist(signedDocument['verificationMethod']); + should().exist(signedDocument['authentication']); + should().exist(signedDocument['assertionMethod']); + should().exist(signedDocument['keyAgreement']); + should().exist(signedDocument['capabilityInvocation']); + should().exist(signedDocument['capabilityDelegation']); + should().exist(signedDocument['service']); + should().exist(signedDocument['proof']); + }); +}); +describe('#verify() method to verify did document', function () { + it('should not able to verify did document and throw error as verificationMethodId is not passed or it is empty', function () { + return hypersignDid + .verify({ doc: signedDocument, verificationMethodId: '', challenge, domain }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to verify a did'); + }); + }); + it('should not able to verify did document and throw error as challenge is not passed or it is empty', function () { + return hypersignDid + .verify({ doc: signedDocument, verificationMethodId, challenge: '', domain }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.challenge is required to verify a did'); + }); + }); + + it('should return verification result', async function () { + const result = await hypersignDid.verify({ + doc: signedDocument, + verificationMethodId, + challenge, + domain, + }); + expect(result).to.be.a('object'); + should().exist(result.verificationResult); + should().exist(result.verificationResult.verified); + should().exist(result.verificationResult.results); + expect(result.verificationResult.results).to.be.a('array'); + expect(result.verificationResult.verified).to.equal(true); + }); +}); + +describe('#register() this is to register didDoc on blockchain', function () { + // it('should not be able to register did document on blockchain as didDocument is null or empty', function () { + // return hypersignDid.register({ didDocument: {}, privateKeyMultibase, verificationMethodId }).catch(function (err) { + // expect(function () { + // throw err; + // }).to.throw(Error, 'HID-SSI-SDK:: Error: params.didDocString is required to register a did'); + // }); + // }); + it('should not be able to register did document on blockchain as privateKeyMultibase is null or empty', function () { + return hypersignDid + .register({ didDocument: signedDocument, privateKeyMultibase: '', verificationMethodId }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to register a did'); + }); + }); + it('should not be able to register did document on blockchain as verificationMethodId is null or empty', function () { + return hypersignDid + .register({ didDocument: signedDocument, privateKeyMultibase, verificationMethodId: '' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to register a did'); + }); + }); + it("should not be able to register did document on blockchain as wallet has no balance and hidClient can't be initialized", function () { + return hypersignDid + .register({ didDocument: signedDocument, privateKeyMultibase, verificationMethodId }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, "Cannot read property 'signAndBroadcast' of undefined"); + }); + }); +}); + +describe('#resolve() this is to resolve didDoc', function () { + it('should not be able to resolve didDocument as did is not passed or it is empty', function () { + const params = { + did: '', + }; + return hypersignDid.resolve(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.did is required to resolve a did'); + }); + }); + it("should not be able to resolve did document on blockchain as hidClient can't be initialized", function () { + const params = { did: didDocId }; + return hypersignDid.resolve(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'connect ECONNREFUSED 127.0.0.1:80'); + }); + }); +}); + +describe('#update() this is to update didDoc', function () { + // it('should not be able to update did document as didDocument is null or empty', function () { + // return hypersignDid + // .update({ didDocument: {}, privateKeyMultibase, verificationMethodId, versionId: '1.0' }) + // .catch(function (err) { + // expect(function () { + // throw err; + // }).to.throw(Error, 'HID-SSI-SDK:: Error: params.didDocument is required to update a did'); + // }); + // }); + it('should not be able to update did document as privateKeyMultibase is null or empty', function () { + return hypersignDid + .update({ didDocument, privateKeyMultibase: '', verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to update a did'); + }); + }); + it('should not be able to update did document as verificationMethodId is null or empty', function () { + return hypersignDid + .update({ didDocument, privateKeyMultibase, verificationMethodId: '', versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to update a did'); + }); + }); + it('should not be able to update did document as versionId is null or empty', function () { + return hypersignDid + .update({ didDocument, privateKeyMultibase, verificationMethodId, versionId: '' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.versionId is required to update a did'); + }); + }); + it("should not be able to update did document on hidClient can't be initialized", function () { + return hypersignDid + .update({ didDocument: didDocument, privateKeyMultibase, verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, "Cannot read property 'signAndBroadcast' of undefined"); + }); + }); +}); + +describe('#deactivate() this is to deactivate didDoc', function () { + // it('should not be able to deactivate did document as didDocument is null or empty', function () { + // return hypersignDid + // .deactivate({ didDocument: {}, privateKeyMultibase, verificationMethodId, versionId: '1.0' }) + // .catch(function (err) { + // expect(function () { + // throw err; + // }).to.throw(Error, 'HID-SSI-SDK:: Error: params.didDocument is required to deactivate a did'); + // }); + // }); + it('should not be able to deactivate did document as privateKeyMultibase is null or empty', function () { + return hypersignDid + .deactivate({ didDocument, privateKeyMultibase: '', verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to deactivate a did'); + }); + }); + it('should not be able to deactivate did document as verificationMethodId is null or empty', function () { + return hypersignDid + .deactivate({ didDocument, privateKeyMultibase, verificationMethodId: '', versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to deactivate a did'); + }); + }); + it('should not be able to deactivate did document as versionId is null or empty', function () { + return hypersignDid + .deactivate({ didDocument, privateKeyMultibase, verificationMethodId, versionId: '' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.versionId is required to deactivate a did'); + }); + }); + it("should not be able to deactivate did document on hidClient can't be initialized", function () { + return hypersignDid + .deactivate({ didDocument: didDocument, privateKeyMultibase, verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, "Cannot read property 'signAndBroadcast' of undefined"); + }); + }); +}); diff --git a/src/tests/didRpc.ts b/src/tests/didRpc.ts new file mode 100644 index 0000000..74cc428 --- /dev/null +++ b/src/tests/didRpc.ts @@ -0,0 +1,244 @@ +import { expect, should } from 'chai'; +import HypersignSSISdk from '../index'; + +import { createWallet, mnemonic, hidNodeEp } from './config'; +let hsSdk; +const seed = ''; +let privateKeyMultibase; +let publicKeyMultibase; +let verificationMethodId; +let didDocument; +let didDocId; +let offlineSigner; +let transactionHash; +let versionId; + +//add mnemonic of wallet that have balance + +beforeEach(async function () { + offlineSigner = await createWallet(mnemonic); + hsSdk = new HypersignSSISdk(offlineSigner, hidNodeEp.rpc, hidNodeEp.rest, hidNodeEp.namespace); + await hsSdk.init(); +}); + +//remove seed while creating did so that wallet can generate different +describe('#generateKeys() method to generate publicKyeMultibase and privateKeyMultiBase', function () { + it('should return publickeyMultibase and privateKeyMultibase', async function () { + const kp = await hsSdk.did.generateKeys(); + privateKeyMultibase = kp.privateKeyMultibase; + publicKeyMultibase = kp.publicKeyMultibase; + expect(kp).to.be.a('object'); + should().exist(kp.privateKeyMultibase); + should().exist(kp.publicKeyMultibase); + }); +}); +describe('#generate() to generate did', function () { + it('should not be able to generate did document and throw error as publicKeyMultibase passed is null or empty', function () { + return hsSdk.did.generate({ publicKeyMultibase: '' }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.publicKeyMultibase is required to generate new did didoc'); + }); + }); + it('should be able to generate didDocument', async function () { + didDocument = await hsSdk.did.generate({ publicKeyMultibase }); + didDocId = didDocument['id']; + verificationMethodId = didDocument['verificationMethod'][0].id; + expect(didDocument).to.be.a('object'); + should().exist(didDocument['@context']); + should().exist(didDocument['id']); + should().exist(didDocument['controller']); + should().exist(didDocument['alsoKnownAs']); + + should().exist(didDocument['verificationMethod']); + expect( + didDocument['verificationMethod'] && + didDocument['authentication'] && + didDocument['assertionMethod'] && + didDocument['keyAgreement'] && + didDocument['capabilityInvocation'] && + didDocument['capabilityDelegation'] && + didDocument['service'] + ).to.be.a('array'); + should().exist(didDocument['authentication']); + should().exist(didDocument['assertionMethod']); + should().exist(didDocument['keyAgreement']); + should().exist(didDocument['capabilityInvocation']); + should().exist(didDocument['capabilityDelegation']); + should().exist(didDocument['service']); + }); +}); +describe('#register() this is to register did on the blockchain', function () { + it('should not able to register did document and throw error as didDocument is not passed or it is empty', function () { + return hsSdk.did.register({ didDocument: {}, privateKeyMultibase, verificationMethodId }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, "Cannot read property 'length' of undefined"); + }); + }); + it('should not be able to register did document as privateKeyMultibase is null or empty', function () { + return hsSdk.did.register({ didDocument, privateKeyMultibase: '', verificationMethodId }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to register a did'); + }); + }); + it('should not be able to register did document as verificationMethodId is null or empty', function () { + return hsSdk.did.register({ didDocument, privateKeyMultibase, verificationMethodId: '' }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to register a did'); + }); + }); + it('should be able to register didDocument in the blockchain', async function () { + const result = await hsSdk.did.register({ didDocument, privateKeyMultibase, verificationMethodId }); + transactionHash = result.transactionHash; + should().exist(result.code); + should().exist(result.height); + should().exist(result.rawLog); + should().exist(result.transactionHash); + should().exist(result.gasUsed); + should().exist(result.gasWanted); + }); +}); + +describe('#resolve() this is to resolve didDocument based on didDocId', function () { + it('should not able to resolve did document and throw error didDocId is not passed', function () { + return hsSdk.did.resolve({ params: { did: '' } }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.did is required to resolve a did'); + }); + }); + it('should be able to resolve did', async function () { + const params = { + did: didDocId, + }; + const result = await hsSdk.did.resolve(params); + expect(result).to.be.a('object'); + expect(result.didDocument.id).to.be.equal(didDocId); + expect(result.didDocumentMetadata).to.be.a('object'); + versionId = result.didDocumentMetadata.versionId; + }); +}); + +describe('#update() this is to update didDocument based on didDocId', function () { + it('should not be able to update did document as privateKeyMultibase is null or empty', function () { + return hsSdk.did + .update({ didDocument, privateKeyMultibase: '', verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to update a did'); + }); + }); + it('should not be able to update did document as verificationMethodId is null or empty', function () { + return hsSdk.did + .update({ didDocument, privateKeyMultibase, verificationMethodId: '', versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to update a did'); + }); + }); + it('should not be able to update did document as versionId is null or empty', function () { + return hsSdk.did + .update({ didDocument, privateKeyMultibase, verificationMethodId, versionId: '' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.versionId is required to update a did'); + }); + }); + it('should not be able to update did document as versionId pased is incorrect', function () { + const updateBody = { didDocument, privateKeyMultibase, verificationMethodId, versionId: '1.0.1' }; + return hsSdk.did.update(updateBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw( + Error, + `Query failed with (18): failed to execute message; message index: 0: Expected ${didDocId} with version ${versionId}. Got version ${updateBody.versionId}: Unexpected DID version: invalid request` + ); + }); + }); + it('should be able to update did document', async function () { + const result = await hsSdk.did.update({ + didDocument, + privateKeyMultibase, + verificationMethodId, + versionId, + }); + should().exist(result.code); + should().exist(result.height); + should().exist(result.rawLog); + should().exist(result.transactionHash); + should().exist(result.gasUsed); + should().exist(result.gasWanted); + }); +}); +describe('#resolve() did after updating did document', function () { + it('should be able to resolve did', async function () { + const params = { + did: didDocId, + }; + const result = await hsSdk.did.resolve(params); + expect(result).to.be.a('object'); + expect(result.didDocument.id).to.be.equal(didDocId); + expect(result.didDocumentMetadata).to.be.a('object'); + versionId = result.didDocumentMetadata.versionId; + }); +}); +describe('#deactivate() this is to deactivate didDocument based on didDocId', function () { + it('should not be able to deactivate did document as privateKeyMultibase is null or empty', function () { + return hsSdk.did + .deactivate({ didDocument, privateKeyMultibase: '', verificationMethodId, versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKeyMultibase is required to deactivate a did'); + }); + }); + it('should not be able to deactivate did document as verificationMethodId is null or empty', function () { + return hsSdk.did + .deactivate({ didDocument, privateKeyMultibase, verificationMethodId: '', versionId: '1.0' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to deactivate a did'); + }); + }); + it('should not be able to deactivate did document as versionId is null or empty', function () { + return hsSdk.did + .deactivate({ didDocument, privateKeyMultibase, verificationMethodId, versionId: '' }) + .catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.versionId is required to deactivate a did'); + }); + }); + it('should not be able to deactivate did document as versionId pased is incorrect', function () { + const deactivateBody = { didDocument, privateKeyMultibase, verificationMethodId, versionId: '1.0.1' }; + return hsSdk.did.deactivate(deactivateBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw( + Error, + `Query failed with (18): failed to execute message; message index: 0: Expected ${didDocId} with version ${versionId}. Got version ${deactivateBody.versionId}: Unexpected DID version: invalid request` + ); + }); + }); + it('should be able to deactivate did document', async function () { + const result = await hsSdk.did.deactivate({ + didDocument, + privateKeyMultibase, + verificationMethodId, + versionId, + }); + should().exist(result.code); + should().exist(result.height); + should().exist(result.rawLog); + should().exist(result.transactionHash); + should().exist(result.gasUsed); + should().exist(result.gasWanted); + }); +}); diff --git a/src/tests/schema.ts b/src/tests/schema.ts new file mode 100644 index 0000000..78f62ac --- /dev/null +++ b/src/tests/schema.ts @@ -0,0 +1,214 @@ +import HyperSignSchema from '../schema/schema'; +import HypersignDID from '../did/did'; +import { should, expect } from 'chai'; +const hypersignDid = new HypersignDID(); +const hypersignSchema = new HyperSignSchema(); +const seed = ''; +let schemaSignature; +let privateKeyMultibase; +let publicKeyMultibase; +let didDocId; +let schemaId; +let schemaObject; +let didDocument; +let verificationMethod; +const schemaBody = { + name: 'testSchema', + description: 'This is a test schema generation', + author: '', + fields: [{ name: 'name', type: 'integer', isRequired: false }], + additionalProperties: false, +}; +describe('#generateKeys() method to generate publicKyeMultibase and privateKeyMultiBase', function () { + it('should return publickeyMultibase and privateKeyMultibase', async function () { + const result = await hypersignDid.generateKeys({ seed }); + privateKeyMultibase = result.privateKeyMultibase; + publicKeyMultibase = result.publicKeyMultibase; + expect(result).to.be.a('object'); + should().exist(result.privateKeyMultibase); + should().exist(result.publicKeyMultibase); + }); +}); +describe('#generate() method to generate did document', function () { + it('should return didDocument', async function () { + didDocument = await hypersignDid.generate({ publicKeyMultibase }); + didDocId = didDocument['id']; + expect(didDocument).to.be.a('object'); + should().exist(didDocument['@context']); + should().exist(didDocument['id']); + should().exist(didDocument['controller']); + should().exist(didDocument['alsoKnownAs']); + verificationMethod = didDocument['verificationMethod']; + should().exist(didDocument['verificationMethod']); + expect( + didDocument['verificationMethod'] && + didDocument['authentication'] && + didDocument['assertionMethod'] && + didDocument['keyAgreement'] && + didDocument['capabilityInvocation'] && + didDocument['capabilityDelegation'] && + didDocument['service'] + ).to.be.a('array'); + should().exist(didDocument['authentication']); + should().exist(didDocument['assertionMethod']); + should().exist(didDocument['keyAgreement']); + should().exist(didDocument['capabilityInvocation']); + should().exist(didDocument['capabilityDelegation']); + should().exist(didDocument['service']); + }); +}); +describe('#getSchema() method to create schema', function () { + it('should not be able to create a new schema as author is not passed', function () { + const tempSchemaBody = { ...schemaBody }; + return hypersignSchema.getSchema(tempSchemaBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Author must be passed'); + }); + }); + it('should able to create a new schema', async function () { + const tempSchemaBody = { ...schemaBody }; + tempSchemaBody.author = didDocId; + schemaObject = await hypersignSchema.getSchema(tempSchemaBody); + schemaId = schemaObject['id']; + expect(schemaObject).to.be.a('object'); + should().exist(schemaObject['type']); + should().exist(schemaObject['modelVersion']); + should().exist(schemaObject['id']); + should().exist(schemaObject['name']); + should().exist(schemaObject['author']); + should().exist(schemaObject['authored']); + should().exist(schemaObject['schema']); + expect(schemaObject.schema).to.be.a('object'); + expect(schemaObject['name']).to.be.equal(tempSchemaBody.name); + expect(schemaObject['author']).to.be.equal(tempSchemaBody.author); + }); +}); + +describe('#signSchema() method to sign schema', function () { + it('should not be able to sign newly created schema as privateKey is not passed or empty', function () { + return hypersignSchema.signSchema({ privateKey: '', schema: schemaObject }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: PrivateKey must be passed'); + }); + }); + it('should be able to sign newly created schema', async function () { + const signedSchema = await hypersignSchema.signSchema({ privateKey: privateKeyMultibase, schema: schemaObject }); + schemaSignature = signedSchema; + expect(signedSchema).to.be.a('string'); + }); +}); + +describe('#registerSchema() method to register schema on blockchain', function () { + const schema = schemaObject; + const proof = { + type: 'Ed25519Signature2020', + created: '', + verificationMethod: '', + proofValue: '', + proofPurpose: 'assertion', + }; + const params = { schema, proof }; + it('should not be able to register newly created schema on blockchain as schema is not passed', function () { + const tempParam = { ...params }; + tempParam.schema = undefined; + tempParam.proof.created = ''; + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Schema must be passed'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.created is null or empty', function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = ''; + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain created'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.proofPurpose is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofPurpose = ''; + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain proofPurpose'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.proofValue is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.created = schemaObject.authored; + + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain proofValue'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.type is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofValue = schemaSignature; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.type = ''; + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain type'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.verificationMethod is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofValue = schemaSignature; + tempParam.proof.type = 'Ed25519Signature2020'; + return hypersignSchema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain verificationMethod'); + }); + }); + it('should not be able to register newly created schema on blockchain as wallet do not have balance', async function () { + proof['created'] = schemaObject.authored; + proof['proofValue'] = schemaSignature; + proof['type'] = 'Ed25519Signature2020'; + proof['proofPurpose'] = 'assertion'; + proof['verificationMethod'] = verificationMethod; + const schema = schemaObject; + const params = { schema, proof }; + return hypersignSchema.registerSchema(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(TypeError, "Cannot read property 'signAndBroadcast' of undefined"); + }); + }); +}); +describe('#resolve() method to resolve schema', function () { + it('should not be able to resolve schema as schemaId is not passed or it is null', async function () { + const params = { schemaId: '' }; + return hypersignSchema.resolve(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: SchemaId must be passed'); + }); + }); + it("should not be able to resolve schema as hidClient can't be initialized", async function () { + const params = { schemaId }; + return hypersignSchema.resolve(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'connect ECONNREFUSED 127.0.0.1:80'); + }); + }); +}); diff --git a/src/tests/schemaRpc.ts b/src/tests/schemaRpc.ts new file mode 100644 index 0000000..732d008 --- /dev/null +++ b/src/tests/schemaRpc.ts @@ -0,0 +1,236 @@ +import { expect, should } from 'chai'; +import HypersignSSISdk from '../index'; +import { createWallet, mnemonic, hidNodeEp } from './config'; +let hsSdk; +let privateKeyMultibase; +let publicKeyMultibase; +let verificationMethodId; +let didDocument; +let didDocId; +let offlineSigner; +let schemaSignature; +let schemaObject; +let schemaId; +let verificationMethod; +const schemaBody = { + name: 'testSchema', + description: 'This is a test schema generation', + author: '', + fields: [{ name: 'name', type: 'integer', isRequired: false }], + additionalProperties: false, +}; + +//add mnemonic of wallet that have balance + +beforeEach(async function () { + offlineSigner = await createWallet(mnemonic); + hsSdk = new HypersignSSISdk(offlineSigner, hidNodeEp.rpc, hidNodeEp.rest, hidNodeEp.namespace); + await hsSdk.init(); +}); + +describe('#generateKeys() method to generate publicKyeMultibase and privateKeyMultiBase', function () { + it('should return publickeyMultibase and privateKeyMultibase', async function () { + const kp = await hsSdk.did.generateKeys(); + privateKeyMultibase = kp.privateKeyMultibase; + publicKeyMultibase = kp.publicKeyMultibase; + expect(kp).to.be.a('object'); + should().exist(kp.privateKeyMultibase); + should().exist(kp.publicKeyMultibase); + }); +}); +describe('#generate() to generate did', function () { + it('should not be able to generate did document and throw error as publicKeyMultibase passed is null or empty', function () { + return hsSdk.did.generate({ publicKeyMultibase: '' }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.publicKeyMultibase is required to generate new did didoc'); + }); + }); + it('should be able to generate didDocument', async function () { + didDocument = await hsSdk.did.generate({ publicKeyMultibase }); + didDocId = didDocument['id']; + verificationMethod = didDocument['assertionMethod'][0]; + verificationMethodId = didDocument['verificationMethod'][0].id; + expect(didDocument).to.be.a('object'); + should().exist(didDocument['@context']); + should().exist(didDocument['id']); + should().exist(didDocument['controller']); + should().exist(didDocument['alsoKnownAs']); + + should().exist(didDocument['verificationMethod']); + expect( + didDocument['verificationMethod'] && + didDocument['authentication'] && + didDocument['assertionMethod'] && + didDocument['keyAgreement'] && + didDocument['capabilityInvocation'] && + didDocument['capabilityDelegation'] && + didDocument['service'] + ).to.be.a('array'); + should().exist(didDocument['authentication']); + should().exist(didDocument['assertionMethod']); + should().exist(didDocument['keyAgreement']); + should().exist(didDocument['capabilityInvocation']); + should().exist(didDocument['capabilityDelegation']); + should().exist(didDocument['service']); + }); +}); + +describe('#register() this is to register did on the blockchain', function () { + it('should be able to register didDocument in the blockchain', async function () { + const result = await hsSdk.did.register({ didDocument, privateKeyMultibase, verificationMethodId }); + should().exist(result.code); + should().exist(result.height); + should().exist(result.rawLog); + should().exist(result.transactionHash); + should().exist(result.gasUsed); + should().exist(result.gasWanted); + }); +}); + +describe('#getSchema() method to create schema', function () { + it('should able to create a new schema', async function () { + const tempSchemaBody = { ...schemaBody }; + tempSchemaBody.author = didDocId; + schemaObject = await hsSdk.schema.getSchema(tempSchemaBody); + schemaId = schemaObject['id']; + expect(schemaObject).to.be.a('object'); + should().exist(schemaObject['type']); + should().exist(schemaObject['modelVersion']); + should().exist(schemaObject['id']); + should().exist(schemaObject['name']); + should().exist(schemaObject['author']); + should().exist(schemaObject['authored']); + should().exist(schemaObject['schema']); + expect(schemaObject.schema).to.be.a('object'); + expect(schemaObject['name']).to.be.equal(tempSchemaBody.name); + expect(schemaObject['author']).to.be.equal(tempSchemaBody.author); + }); +}); +describe('#sign() function to sign schema', function () { + it('should be able to sign newly created schema', async function () { + const signedSchema = await hsSdk.schema.signSchema({ privateKey: privateKeyMultibase, schema: schemaObject }); + schemaSignature = signedSchema; + expect(signedSchema).to.be.a('string'); + }); +}); +describe('#registerSchema() function to register schema on blockchain', function () { + const schema = schemaObject; + const proof = { + type: 'Ed25519Signature2020', + created: '', + verificationMethod: '', + proofValue: '', + proofPurpose: 'assertion', + }; + const params = { schema, proof }; + it('should not be able to register newly created schema on blockchain as schema is not passed', function () { + const tempParam = { ...params }; + tempParam.schema = undefined; + tempParam.proof.created = ''; + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Schema must be passed'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.created is null or empty', function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = ''; + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain created'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.proofPurpose is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofPurpose = ''; + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain proofPurpose'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.proofValue is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.created = schemaObject.authored; + + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain proofValue'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.type is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofValue = schemaSignature; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.type = ''; + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain type'); + }); + }); + it('should not be able to register newly created schema on blockchain as proof.verificationMethod is null or empty', async function () { + const tempParam = { ...params }; + tempParam.schema = schemaObject; + tempParam.proof.proofPurpose = 'assertion'; + tempParam.proof.created = schemaObject.authored; + tempParam.proof.proofValue = schemaSignature; + tempParam.proof.type = 'Ed25519VerificationKey2020'; + return hsSdk.schema.registerSchema(tempParam).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Proof must Contain verificationMethod'); + }); + }); + + it('should be able to register schema on blockchain', async function () { + const proof = {}; + proof['type'] = 'Ed25519Signature2020'; + proof['created'] = schemaObject.authored; + proof['verificationMethod'] = didDocument['assertionMethod'][0]; + proof['proofValue'] = schemaSignature; + proof['proofPurpose'] = 'assertion'; + const schema = schemaObject; + const params = { schema, proof }; + const registeredSchema = await hsSdk.schema.registerSchema(params); + expect(registeredSchema).to.be.a('object'); + should().exist(registeredSchema.code); + should().exist(registeredSchema.height); + should().exist(registeredSchema.rawLog); + should().exist(registeredSchema.transactionHash); + should().exist(registeredSchema.gasUsed); + should().exist(registeredSchema.gasWanted); + expect(registeredSchema.rawLog).to.be.a('string'); + }); +}); + +describe('#resolve() this is to resolve schema', function () { + it('should not able to resolve schema and throw error didDocId is not passed', function () { + return hsSdk.schema.resolve({ params: { schemaId: '' } }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: SchemaId must be passed'); + }); + }); + it('should be able to resolve schema', async function () { + const params = { + schemaId, + }; + const result = await hsSdk.schema.resolve(params); + expect(result).to.be.a('object'); + expect(result.id).to.be.equal(schemaId); + expect(result.proof.verificationMethod).to.be.equal(verificationMethod); + expect(result.proof).to.be.a('object'); + }); +}); diff --git a/src/tests/vc.ts b/src/tests/vc.ts new file mode 100644 index 0000000..2a98411 --- /dev/null +++ b/src/tests/vc.ts @@ -0,0 +1,648 @@ +import { expect, should } from 'chai'; +import HypersignSSISdk from '../index'; +import { createWallet, mnemonic, hidNodeEp } from './config'; +let privateKeyMultibase; +let publicKeyMultibase; +let didDocId; +let schemaId; +let signedDocument; +let verificationMethodId; +let didDocument; +let schemaObject; +let schemaSignature; +const challenge = '1231231231'; +const domain = 'www.adbv.com'; +let offlineSigner; +let hsSdk; +let credentialId; +let credentialDetail; +let verifiablePresentation; +let signedPresentation; +let verifiableCredentialPresentationId; +const credentialBody = { + schemaId: '', + subjectDid: '', + type: [], + issuerDid: '', + fields: { name: 'Varsha' }, +}; +const schemaBody = { + name: 'testSchema', + description: 'This is a test schema generation', + author: '', + fields: [{ name: 'name', type: 'string', isRequired: false }], + additionalProperties: false, +}; +const issueCredentialBody = { + credential: credentialDetail, + issuerDid: didDocId, + verificationMethodId, + privateKey: privateKeyMultibase, +}; +beforeEach(async function () { + offlineSigner = await createWallet(mnemonic); + hsSdk = new HypersignSSISdk(offlineSigner, hidNodeEp.rpc, hidNodeEp.rest, hidNodeEp.namespace); + await hsSdk.init(); +}); +// Generate public and private key pair +describe('#generateKeys() method to generate publicKyeMultibase and privateKeyMultiBase', function () { + it('should return publickeyMultibase and privateKeyMultibase', async function () { + const kp = await hsSdk.did.generateKeys(); + privateKeyMultibase = kp.privateKeyMultibase; + publicKeyMultibase = kp.publicKeyMultibase; + expect(kp).to.be.a('object'); + should().exist(kp.privateKeyMultibase); + should().exist(kp.publicKeyMultibase); + }); +}); +//Generate did +describe('#generate() to generate did', function () { + it('should be able to generate didDocument', async function () { + didDocument = await hsSdk.did.generate({ publicKeyMultibase }); + didDocId = didDocument['id']; + verificationMethodId = didDocument['verificationMethod'][0].id; + expect(didDocument).to.be.a('object'); + should().exist(didDocument['@context']); + should().exist(didDocument['id']); + should().exist(didDocument['controller']); + should().exist(didDocument['alsoKnownAs']); + + should().exist(didDocument['verificationMethod']); + expect( + didDocument['verificationMethod'] && + didDocument['authentication'] && + didDocument['assertionMethod'] && + didDocument['keyAgreement'] && + didDocument['capabilityInvocation'] && + didDocument['capabilityDelegation'] && + didDocument['service'] + ).to.be.a('array'); + should().exist(didDocument['authentication']); + should().exist(didDocument['assertionMethod']); + should().exist(didDocument['keyAgreement']); + should().exist(didDocument['capabilityInvocation']); + should().exist(didDocument['capabilityDelegation']); + should().exist(didDocument['service']); + }); +}); +describe('#sign() this is to sign didDoc', function () { + const publicKey = { + '@context': '', + id: '', + type: '', + publicKeyBase58: '', + }; + const controller = { + '@context': '', + id: '', + authentication: [], + }; + it('should able to sign did document', async function () { + const params = { + privateKey: privateKeyMultibase as string, + challenge: challenge as string, + domain: domain as string, + did: '', + doc: didDocument as object, + verificationMethodId: verificationMethodId as string, + publicKey, + controller, + }; + signedDocument = await hsSdk.did.signDid(params); + expect(signedDocument).to.be.a('object'); + signedDocument = signedDocument.signedDidDocument; + should().exist(signedDocument['@context']); + should().exist(signedDocument['id']); + expect(didDocId).to.be.equal(signedDocument['id']); + should().exist(signedDocument['controller']); + should().exist(signedDocument['alsoKnownAs']); + should().exist(signedDocument['verificationMethod']); + should().exist(signedDocument['authentication']); + should().exist(signedDocument['assertionMethod']); + should().exist(signedDocument['keyAgreement']); + should().exist(signedDocument['capabilityInvocation']); + should().exist(signedDocument['capabilityDelegation']); + should().exist(signedDocument['service']); + should().exist(signedDocument['proof']); + }); +}); +describe('#register() this is to register did on the blockchain', function () { + it('should be able to register didDocument in the blockchain', async function () { + const result = await hsSdk.did.register({ didDocument, privateKeyMultibase, verificationMethodId }); + should().exist(result.code); + should().exist(result.height); + should().exist(result.rawLog); + should().exist(result.transactionHash); + should().exist(result.gasUsed); + should().exist(result.gasWanted); + }); +}); +// Generate schema +describe('#getSchema() method to create schema', function () { + it('should able to create a new schema', async function () { + schemaBody.author = didDocId; + schemaObject = await hsSdk.schema.getSchema(schemaBody); + schemaId = schemaObject['id']; + expect(schemaObject).to.be.a('object'); + should().exist(schemaObject['type']); + should().exist(schemaObject['modelVersion']); + should().exist(schemaObject['id']); + should().exist(schemaObject['name']); + should().exist(schemaObject['author']); + should().exist(schemaObject['authored']); + should().exist(schemaObject['schema']); + expect(schemaObject.schema).to.be.a('object'); + expect(schemaObject['name']).to.be.equal(schemaBody.name); + expect(schemaObject['author']).to.be.equal(schemaBody.author); + }); +}); +describe('#sign() function to sign schema', function () { + it('should be able to sign newly created schema', async function () { + const signedSchema = await hsSdk.schema.signSchema({ privateKey: privateKeyMultibase, schema: schemaObject }); + schemaSignature = signedSchema; + expect(signedSchema).to.be.a('string'); + }); +}); +describe('#registerSchema() function to register schema on blockchain', function () { + it('should be able to register schema on blockchain', async function () { + const proof = {}; + proof['type'] = 'Ed25519Signature2020'; + proof['created'] = schemaObject.authored; + proof['verificationMethod'] = didDocument['assertionMethod'][0]; + proof['proofValue'] = schemaSignature; + proof['proofPurpose'] = 'assertion'; + const schema = schemaObject; + const params = { schema, proof }; + const registeredSchema = await hsSdk.schema.registerSchema(params); + expect(registeredSchema).to.be.a('object'); + should().exist(registeredSchema.code); + should().exist(registeredSchema.height); + should().exist(registeredSchema.rawLog); + should().exist(registeredSchema.transactionHash); + should().exist(registeredSchema.gasUsed); + should().exist(registeredSchema.gasWanted); + expect(registeredSchema.rawLog).to.be.a('string'); + }); +}); +// Test case related to credential + +describe('#getCredential() method to generate a credential', function () { + it('should not be able to generate new credential for a schema as both subjectDid and subjectDidDocSigned is passed', async function () { + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.issuerDid = didDocId; + tempCredentialBody.subjectDid = didDocId; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Both subjectDid and subjectDidDoc cannot be passed'); + }); + }); + it('should not be able to generate new credential for a schema as not able to resolve subjectDid or subjectDidDoc as neither subjectDid nor subjectDidDocSigned is passed', async function () { + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.issuerDid = didDocId; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: Could not resolve the subjectDid or subjectDidDoc'); + }); + }); + it('should not be able to generate new credential for a schema as nether schemaId nor schema Context is passed', async function () { + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.issuerDid = didDocId; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'schemaId is required when schemaContext and type not passed'); + }); + }); + it('should not be able to generate new credential for a schema as wrong issuer did is passed', async function () { + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.schemaId = schemaId; + tempCredentialBody.issuerDid = didDocId + 'xyz'; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw( + Error, + `HID-SSI-SDK:: Error: Could not fetch issuer did doc, issuer did = ${tempCredentialBody.issuerDid}` + ); + }); + }); + it('should not be able to generate new credential for a schema as not able to get subject did doc based on subjectDid passed', async function () { + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.schemaId = schemaId; + tempCredentialBody.issuerDid = didDocId; + tempCredentialBody['subjectDid'] = didDocId; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw( + Error, + `HID-SSI-SDK:: Error: Could not fetch subject did doc, subject did ${tempCredentialBody.subjectDid}` + ); + }); + }); + it('should not be able to generate new credential for a schema as expiration date is passed in wrong format', async function () { + const todaysDate = new Date(); + const tempExpirationDate = todaysDate.setDate(todaysDate.getDate() + 2); + const expirationDate = tempExpirationDate.toString(); + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.schemaId = schemaId; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + tempCredentialBody['expirationDate'] = expirationDate; + tempCredentialBody.issuerDid = didDocId; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'Invalid time value'); + }); + }); + it('should not be able to generate new credential for a schema as additional properties in schema is set to false but sending additional properties in field value at the time of generating credential', async function () { + const expirationDate = new Date('12/11/2027'); + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.schemaId = schemaId; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + tempCredentialBody['expirationDate'] = expirationDate; + tempCredentialBody.issuerDid = didDocId; + tempCredentialBody.fields['type'] = 'string'; + tempCredentialBody.fields['value'] = 'Varsha'; + tempCredentialBody.fields['name'] = 'name'; + return hsSdk.vc.getCredential(tempCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw( + Error, + `Only ["${schemaBody.fields[0].name}"] attributes are possible. additionalProperties is false in the schema` + ); + }); + }); + it('should be able to generate new credential for a schema', async function () { + const expirationDate = new Date('12/11/2027'); + const tempCredentialBody = { ...credentialBody }; + tempCredentialBody.schemaId = schemaId; + tempCredentialBody['subjectDidDocSigned'] = signedDocument; + tempCredentialBody['expirationDate'] = expirationDate; + tempCredentialBody.issuerDid = didDocId; + tempCredentialBody.fields = { name: 'varsha' }; + credentialDetail = await hsSdk.vc.getCredential(tempCredentialBody); + expect(credentialDetail).to.be.a('object'); + should().exist(credentialDetail['@context']); + should().exist(credentialDetail['id']); + credentialId = credentialDetail.id; + should().exist(credentialDetail['type']); + should().exist(credentialDetail['expirationDate']); + should().exist(credentialDetail['issuanceDate']); + should().exist(credentialDetail['issuer']); + should().exist(credentialDetail['credentialSubject']); + should().exist(credentialDetail['credentialSchema']); + should().exist(credentialDetail['credentialStatus']); + expect(credentialDetail['credentialStatus'].type).to.be.equal('CredentialStatusList2017'); + }); +}); + +describe('#issueCredential() method for issuing credential', function () { + it('should not be able to issueCredential as verificationMethodId is null or empty', async function () { + const tempIssueCredentialBody = { ...issueCredentialBody }; + tempIssueCredentialBody.credential = credentialDetail; + tempIssueCredentialBody.issuerDid = didDocId; + tempIssueCredentialBody.verificationMethodId = ''; + tempIssueCredentialBody.privateKey = privateKeyMultibase; + return hsSdk.vc.issueCredential(tempIssueCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to issue credential'); + }); + }); + it('should not be able to issueCredential as credentialObject is null or undefined', async function () { + const tempIssueCredentialBody = { ...issueCredentialBody }; + tempIssueCredentialBody.credential = undefined; + tempIssueCredentialBody.issuerDid = didDocId; + tempIssueCredentialBody.verificationMethodId = verificationMethodId; + tempIssueCredentialBody.privateKey = privateKeyMultibase; + return hsSdk.vc.issueCredential(tempIssueCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.credential is required to issue credential'); + }); + }); + it('should not be able to issueCredential as privateKey is null or empty', async function () { + const tempIssueCredentialBody = { ...issueCredentialBody }; + tempIssueCredentialBody.credential = credentialDetail; + tempIssueCredentialBody.issuerDid = didDocId; + tempIssueCredentialBody.verificationMethodId = verificationMethodId; + tempIssueCredentialBody.privateKey = ''; + return hsSdk.vc.issueCredential(tempIssueCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.privateKey is required to issue credential'); + }); + }); + it('should not be able to issueCredential as issuerDid is null or empty', async function () { + const tempIssueCredentialBody = { ...issueCredentialBody }; + tempIssueCredentialBody.credential = credentialDetail; + tempIssueCredentialBody.issuerDid = ''; + tempIssueCredentialBody.verificationMethodId = verificationMethodId; + tempIssueCredentialBody.privateKey = publicKeyMultibase; + return hsSdk.vc.issueCredential(tempIssueCredentialBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.issuerDid is required to issue credential'); + }); + }); + it('should be able to issue credential to particular user', async function () { + const tempIssueCredentialBody = { ...issueCredentialBody }; + tempIssueCredentialBody.credential = credentialDetail; + tempIssueCredentialBody.issuerDid = didDocId; + tempIssueCredentialBody.verificationMethodId = verificationMethodId; + tempIssueCredentialBody.privateKey = privateKeyMultibase; + const issuedCredResult = await hsSdk.vc.issueCredential(tempIssueCredentialBody); + expect(issuedCredResult).to.be.a('object'); + should().exist(issuedCredResult['@context']); + should().exist(issuedCredResult['id']); + should().exist(issuedCredResult['type']); + should().exist(issuedCredResult['expirationDate']); + should().exist(issuedCredResult['issuanceDate']); + should().exist(issuedCredResult['issuer']); + should().exist(issuedCredResult['credentialSubject']); + should().exist(issuedCredResult['credentialSchema']); + should().exist(issuedCredResult['credentialStatus']); + should().exist(issuedCredResult['proof']); + expect(issuedCredResult['id']).to.be.equal(credentialId); + }); +}); + +describe('#verifyCredential() method to verify a credential', function () { + it('should not be able to verify credential as verificationMethodId is null or empty', async function () { + const params = { + credential: credentialDetail, + issuerDid: didDocId, + verificationMethodId, + }; + params.verificationMethodId = ''; + return hsSdk.vc.verifyCredential(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.verificationMethodId is required to verify credential'); + }); + }); + it('should not be able to verify credential as credential is null or undefined', async function () { + const params = { + credential: credentialDetail, + issuerDid: didDocId, + verificationMethodId, + }; + params.credential = undefined; + return hsSdk.vc.verifyCredential(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Credential is required to verify credential'); + }); + }); + it('should not be able to verify credential as credential is null or empty', async function () { + const params = { + credential: credentialDetail, + issuerDid: didDocId, + verificationMethodId, + }; + params.issuerDid = ''; + return hsSdk.vc.verifyCredential(params).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Error: params.issuerDid is required to verify credential'); + }); + }); + it('should be able to verify credential', async function () { + const params = { + credential: credentialDetail, + issuerDid: didDocId, + verificationMethodId, + }; + const verificationResult = await hsSdk.vc.verifyCredential(params); + expect(verificationResult).to.be.a('object'); + should().exist(verificationResult.verified); + expect(verificationResult.verified).to.be.equal(true); + should().exist(verificationResult.results); + expect(verificationResult.results).to.be.a('array'); + should().exist(verificationResult.statusResult); + expect(verificationResult.statusResult.verified).to.be.equal(true); + }); +}); + +describe('#checkCredentialStatus() method to check status of the credential', function () { + it('should not be able to verify credential as credentialId is null or empty', async function () { + return hsSdk.vc.checkCredentialStatus().catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'CredentialId must be passed to check its status'); + }); + }); + it('should not be able to verify credential as credentialId is invalid', async function () { + return hsSdk.vc.checkCredentialStatus({ credentialId: credentialId + 'x' }).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'No credential status found. Probably invalid credentialId'); + }); + }); + it('should be able to check credential status', async function () { + const credentialStatus = await hsSdk.vc.checkCredentialStatus(credentialId); + expect(credentialStatus).to.be.a('object'); + should().exist(credentialStatus.verified); + expect(credentialStatus.verified).to.be.equal(true); + }); +}); + +//Test case for verifying presentation + +describe('#getPresentation() method to generate presentation', function () { + const presentationBody = { + verifiableCredentials: [credentialDetail], + holderDid: didDocId, + }; + it('should be able to generate presentation', async function () { + const tempPresentationBody = { ...presentationBody }; + tempPresentationBody.verifiableCredentials[0] = credentialDetail; + tempPresentationBody.holderDid = didDocId; + verifiablePresentation = await hsSdk.vp.getPresentation(tempPresentationBody); + should().exist(verifiablePresentation['@context']); + should().exist(verifiablePresentation['type']); + expect(verifiablePresentation.type[0]).to.be.equal('VerifiablePresentation'); + should().exist(verifiablePresentation['verifiableCredential']); + expect(verifiablePresentation.verifiableCredential).to.be.a('array'); + should().exist(verifiablePresentation['id']); + should().exist(verifiablePresentation['holder']); + verifiableCredentialPresentationId = verifiablePresentation.id; + expect(verifiablePresentation['verifiableCredential'][0].id).to.be.equal(credentialId); + }); +}); + +describe('#signPresentation() method to sign presentation', function () { + const signPresentationBody = { + presentation: verifiablePresentation, + holderDid: didDocId, + verificationMethodId, + privateKey: privateKeyMultibase, + challenge, + }; + it('should not be able to sign presentation as either holderDid or holderDidDocSigned is required but passed both', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.presentation = verifiablePresentation; + tempSignPresentationBody.holderDid = didDocId; + tempSignPresentationBody.verificationMethodId = verificationMethodId; + tempSignPresentationBody.privateKey = privateKeyMultibase; + tempSignPresentationBody['holderDidDocSigned'] = signedDocument; + return hsSdk.vp.signPresentation(tempSignPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Either holderDid or holderDidDocSigned should be provided'); + }); + }); + it('should not be able to sign presentation as privateKey in null or empty', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.privateKey = ''; + return hsSdk.vp.signPresentation(tempSignPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.privateKey is required for signinng a presentation'); + }); + }); + it('should not be able to sign presentation as either holderDid or holderDidDocSigned is required but passed both', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.privateKey = privateKeyMultibase; + tempSignPresentationBody.presentation = undefined; + + return hsSdk.vp.signPresentation(tempSignPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.presentation is required for signinng a presentation'); + }); + }); + it('should not be able to sign presentation as either holderDid or holderDidDocSigned is required but passed both', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.privateKey = privateKeyMultibase; + tempSignPresentationBody.presentation = verifiablePresentation; + tempSignPresentationBody.challenge = ''; + return hsSdk.vp.signPresentation(tempSignPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.challenge is required for signinng a presentation'); + }); + }); + it('should not be able to sign presentation as either holderDid or holderDidDocSigned is required but passed both', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.privateKey = privateKeyMultibase; + tempSignPresentationBody.presentation = verifiablePresentation; + tempSignPresentationBody.challenge = challenge; + tempSignPresentationBody.verificationMethodId = ''; + return hsSdk.vp.signPresentation(tempSignPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.verificationMethodId is required for signinng a presentation'); + }); + }); + it('should be able to sign presentation', async function () { + const tempSignPresentationBody = { ...signPresentationBody }; + tempSignPresentationBody.presentation = verifiablePresentation; + tempSignPresentationBody.holderDid = didDocId; + tempSignPresentationBody.verificationMethodId = verificationMethodId; + tempSignPresentationBody.privateKey = privateKeyMultibase; + signedPresentation = await hsSdk.vp.signPresentation(tempSignPresentationBody); + should().exist(signedPresentation['@context']); + should().exist(signedPresentation['type']); + expect(signedPresentation.type[0]).to.be.equal('VerifiablePresentation'); + should().exist(signedPresentation['verifiableCredential']); + expect(signedPresentation.id).to.be.equal(verifiableCredentialPresentationId); + }); +}); + +describe('#verifyPresentation() method to verify presentation', function () { + const verifyPresentationBody = { + signedPresentation: signedPresentation, + holderDid: didDocId, + holderVerificationMethodId: verificationMethodId, + issuerVerificationMethodId: verificationMethodId, + privateKey: privateKeyMultibase, + challenge, + issuerDid: didDocId, + }; + it('should not be able to verify presentation as either holderDid or holderDidDocSigned is required but passed both', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.signedPresentation = signedPresentation; + tempverifyPresentationBody.holderDid = didDocId; + tempverifyPresentationBody.holderVerificationMethodId = verificationMethodId; + tempverifyPresentationBody.issuerVerificationMethodId = verificationMethodId; + tempverifyPresentationBody.privateKey = privateKeyMultibase; + tempverifyPresentationBody['holderDidDocSigned'] = signedDocument; + return hsSdk.vp.verifyPresentation(tempverifyPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: Either holderDid or holderDidDocSigned should be provided'); + }); + }); + it('should not be able to verify presentation as issuerDid is null or empty', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.issuerDid = ''; + return hsSdk.vp.verifyPresentation(tempverifyPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.issuerDid is required for verifying a presentation'); + }); + }); + it('should not be able to verify presentation as challenge is null or empty', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.issuerDid = didDocId; + tempverifyPresentationBody.challenge = ''; + + return hsSdk.vp.verifyPresentation(tempverifyPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.challenge is required for verifying a presentation'); + }); + }); + it('should not be able to verify presentation as holderVerificationMethodId is null or empty', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.issuerDid = didDocId; + tempverifyPresentationBody.challenge = challenge; + tempverifyPresentationBody.holderVerificationMethodId = ''; + + return hsSdk.vp.verifyPresentation(tempverifyPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.holderVerificationMethodId is required for verifying a presentation'); + }); + }); + it('should not be able to verify presentation as issuerVerificationMethodId is null or empty', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.issuerDid = didDocId; + tempverifyPresentationBody.challenge = challenge; + tempverifyPresentationBody.holderVerificationMethodId = verificationMethodId; + tempverifyPresentationBody.issuerVerificationMethodId = ''; + + return hsSdk.vp.verifyPresentation(tempverifyPresentationBody).catch(function (err) { + expect(function () { + throw err; + }).to.throw(Error, 'HID-SSI-SDK:: params.issuerVerificationMethodId is required for verifying a presentation'); + }); + }); + it('should be able to verify presentation', async function () { + const tempverifyPresentationBody = { ...verifyPresentationBody }; + tempverifyPresentationBody.signedPresentation = signedPresentation; + tempverifyPresentationBody.issuerDid = didDocId; + tempverifyPresentationBody.holderDid = didDocId; + tempverifyPresentationBody.holderVerificationMethodId = verificationMethodId; + tempverifyPresentationBody.issuerVerificationMethodId = verificationMethodId; + tempverifyPresentationBody.challenge = didDocId; + const verifiedPresentationDetail = await hsSdk.vp.verifyPresentation(tempverifyPresentationBody); + should().exist(verifiedPresentationDetail.verified); + expect(verifiedPresentationDetail.verified).to.be.equal(true); + expect(verifiedPresentationDetail).to.be.a('object'); + should().exist(verifiedPresentationDetail.results); + expect(verifiedPresentationDetail.results).to.be.a('array'); + should().exist(verifiedPresentationDetail.credentialResults); + expect(verifiedPresentationDetail.credentialResults).to.be.a('array'); + expect(verifiedPresentationDetail.credentialResults[0].verified).to.be.equal(true); + expect(verifiedPresentationDetail.credentialResults[0].credentialId).to.be.equal(credentialId); + }); +}); diff --git a/test/ssi/schema.js b/test/ssi/schema.js index 68bb719..d083f78 100644 --- a/test/ssi/schema.js +++ b/test/ssi/schema.js @@ -17,7 +17,7 @@ const author = id; let hsSdk; let schema; let proof = { - "type": "Ed25519VerificationKey2020", + "type": "Ed25519Signature2020", "created": "", "verificationMethod": assertionMethod[0], "proofValue": "", From 1c3bec96eb6acb0671aa39fafcea9d79a8aa6730 Mon Sep 17 00:00:00 2001 From: varsha Date: Mon, 19 Dec 2022 13:17:45 +0530 Subject: [PATCH 2/2] removed commented mnemonics --- src/tests/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/config.ts b/src/tests/config.ts index fa481e3..f2e3654 100644 --- a/src/tests/config.ts +++ b/src/tests/config.ts @@ -2,7 +2,7 @@ const { DirectSecp256k1HdWallet } = require('@cosmjs/proto-signing'); const { HdPath, Slip10RawIndex } = require('@cosmjs/crypto'); export const mnemonic = - 'zero require alcohol swamp hover punch celery common merge embrace flock dumb unit capital problem future canal improve auto home apple avoid tragic mechanic'; //"judge harvest lion steak possible ship dog outside local hunt portion fix blast answer walnut injury food clever hen wrist casual humble script alter"//"napkin delay purchase easily camp mimic share wait stereo reflect allow soccer believe exhibit laptop upset tired talent transfer talk surface solution omit crack" + 'zero require alcohol swamp hover punch celery common merge embrace flock dumb unit capital problem future canal improve auto home apple avoid tragic mechanic'; export const hidNodeEp = { rpc: 'https://jagrat.hypersign.id/rpc',