diff --git a/test/10-issue.spec.js b/test/10-issue.spec.js new file mode 100644 index 00000000..b7ef58df --- /dev/null +++ b/test/10-issue.spec.js @@ -0,0 +1,381 @@ +/*! + * Copyright (c) 2019-2024 Digital Bazaar, Inc. All rights reserved. + */ +import * as vc from '../lib/index.js'; +import { + documentLoader, + remoteDocuments, +} from './testDocumentLoader.js'; +import {assertionController} from './mocks/assertionController.js'; +import chai from 'chai'; +import {createSkewedTimeStamp} from './helpers.js'; +import {credentials} from './mocks/mock.data.js'; +import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020'; +import { + Ed25519VerificationKey2020 +} from '@digitalbazaar/ed25519-verification-key-2020'; +import {v4 as uuid} from 'uuid'; +import {versionedCredentials} from './mocks/credential.js'; + +const should = chai.should(); + +// do ed25519 setup... +let suite; +let keyPair; +before(async () => { + // set up the Ed25519 key pair that will be signing and verifying + keyPair = await Ed25519VerificationKey2020.generate({ + id: 'https://example.edu/issuers/keys/1', + controller: 'https://example.edu/issuers/565049' + }); + + // add the key to the controller doc (authorizes its use for assertion) + assertionController.assertionMethod.push(keyPair.id); + // also add the key for authentication (VP) purposes + // FIXME: this shortcut to reuse the same key and sign VPs as issuer can + // confuse developers trying to learn from the test suite and it should + // be changed + assertionController.authentication.push(keyPair.id); + + // register the controller document and the key document with documentLoader + remoteDocuments.set( + 'https://example.edu/issuers/565049', assertionController); + remoteDocuments.set( + 'https://example.edu/issuers/keys/1', + await keyPair.export({publicKey: true})); + + // set up the signature suite, using the generated key + suite = new Ed25519Signature2020({ + verificationMethod: 'https://example.edu/issuers/keys/1', + key: keyPair, + canonizeOptions: { + rdfDirection: 'i18n-datatype', + } + }); +}); + +// run tests on each version of VCs +for(const [version, mockCredential] of versionedCredentials) { + describe(`Verifiable Credentials Data Model ${version}`, async function() { + describe('vc.issue()', () => { + it('should issue a verifiable credential with proof', async () => { + const credential = mockCredential(); + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + it('should issue a verifiable credential with out id', async () => { + const credential = mockCredential(); + delete credential.id; + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + should.not.exist(verifiableCredential.id, 'Expected no "vc.id".'); + }); + it('should throw an error on missing verificationMethod', async () => { + const suite = new Ed25519Signature2020({ + // Note no key id or verificationMethod passed to suite + key: await Ed25519VerificationKey2020.generate() + }); + let error; + try { + await vc.issue({ + credential: mockCredential(), + suite + }); + } catch(e) { + error = e; + } + should.exist(error, + 'Should throw error when "verificationMethod" property is missing'); + error.should.be.instanceof(TypeError); + error.message.should + .contain('"suite.verificationMethod" property is required.'); + }); + if(version === 1.0) { + it('should issue an expired verifiable credential', async () => { + const keyPair = await Ed25519VerificationKey2020.generate(); + const fp = keyPair.fingerprint(); + keyPair.id = `did:key:${fp}#${fp}`; + const credential = mockCredential(); + credential.id = `urn:uuid:${uuid()}`; + credential.issuer = `did:key:${fp}`; + credential.expirationDate = '2020-05-31T19:21:25Z'; + const verifiableCredential = await vc.issue({ + credential, + suite: new Ed25519Signature2020({ + key: keyPair + }), + // set `now` to expiration date, allowing the credential + // to be issued + // without failing the expired check + now: (new Date('2020-05-31T19:21:25Z')), + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + it('should add "issuanceDate" to verifiable credentials', async () => { + const credential = mockCredential(); + delete credential.issuanceDate; + const now = new Date(); + const expectedIssuanceDate = `${now.toISOString().slice(0, -5)}Z`; + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader, + now + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + verifiableCredential.should.have.property( + 'issuanceDate', + expectedIssuanceDate + ); + }); + } + if(version === 2.0) { + it('should issue "validUntil" in the future', async () => { + const credential = mockCredential(); + credential.issuer = 'did:example:12345'; + // set validUntil one year in the future + credential.validUntil = createSkewedTimeStamp({skewYear: 1}); + let error; + let verifiableCredential; + try { + verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + } catch(e) { + error = e; + } + should.not.exist(error, + 'Should not throw error when issuing "validUntil" in future'); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + // ensure validUntil is present and has correct timestamp + verifiableCredential.should.have.property( + 'validUntil', + credential.validUntil + ); + }); + it('should issue "validUntil" in the past', async () => { + const credential = mockCredential(); + credential.issuer = 'did:example:12345'; + // set validUntil one year in the past + credential.validUntil = createSkewedTimeStamp({skewYear: -1}); + let error; + let verifiableCredential; + try { + verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + } catch(e) { + error = e; + } + should.not.exist(error, + 'Should not throw error when issuing with "validUntil" in past'); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + // ensure validUntil is present and has correct timestamp + verifiableCredential.should.have.property( + 'validUntil', + credential.validUntil + ); + }); + it('should issue "validFrom" in the past', async () => { + const credential = mockCredential(); + credential.issuer = 'did:example:12345'; + credential.validFrom = createSkewedTimeStamp({skewYear: -1}); + let error; + let verifiableCredential; + try { + verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + } catch(e) { + error = e; + } + should.not.exist(error, + 'Should not throw error when issuing "validFrom" in past'); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + // ensure validFrom is present and has correct timestamp + verifiableCredential.should.have.property( + 'validFrom', + credential.validFrom + ); + }); + it('should issue "validFrom" in the future', async () => { + const credential = mockCredential(); + credential.issuer = 'did:example:12345'; + credential.validFrom = createSkewedTimeStamp({skewYear: 1}); + let error; + let verifiableCredential; + try { + verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + } catch(e) { + error = e; + } + should.not.exist(error, + 'Should not throw error when issuing "validFrom" in future'); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + // ensure validFrom is present and has correct timestamp + verifiableCredential.should.have.property( + 'validFrom', + credential.validFrom + ); + }); + it('should issue both "validFrom" and "validUntil"', async () => { + const credential = mockCredential(); + credential.issuer = 'did:example:12345'; + credential.validFrom = createSkewedTimeStamp({skewYear: -1}); + credential.validUntil = createSkewedTimeStamp({skewYear: 1}); + let error; + let verifiableCredential; + try { + verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + } catch(e) { + error = e; + } + should.not.exist( + error, + 'Should not throw when issuing VC with both "validFrom" and' + + '"validUntil"' + ); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + // ensure validFrom & validUntil are present + // and have correct timestamps + verifiableCredential.should.have.property( + 'validFrom', + credential.validFrom + ); + verifiableCredential.should.have.property( + 'validUntil', + credential.validUntil + ); + }); + it('should issue a VC with multiple languages', async function() { + const credential = structuredClone( + credentials.features.multiple.languages); + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + it('should issue a VC with multiple languages & directions', + async function() { + const credential = structuredClone( + credentials.features.multiple.directions); + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + it('should issue a VC with a single language', async function() { + const credential = structuredClone( + credentials.features.single.language); + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + it('should issue a VC with a single language & direction', + async function() { + const credential = structuredClone( + credentials.features.single.direction); + const verifiableCredential = await vc.issue({ + credential, + suite, + documentLoader + }); + verifiableCredential.should.exist; + verifiableCredential.should.be.an('object'); + verifiableCredential.should.have.property('proof'); + verifiableCredential.proof.should.be.an('object'); + }); + } + }); + describe('vc.signPresentation()', () => { + it('should create a signed VP', async () => { + const presentation = vc.createPresentation({ + verifiableCredential: mockCredential(), + id: 'test:ebc6f1c2', + holder: 'did:ex:holder123', + version + }); + const vp = await vc.signPresentation({ + presentation, + suite, // from before() block + challenge: '12ec21', + documentLoader + }); + vp.should.have.property('proof'); + vp.proof.should.have.property('type', 'Ed25519Signature2020'); + vp.proof.should.have.property('proofPurpose', 'authentication'); + vp.proof.should.have.property('verificationMethod', + 'https://example.edu/issuers/keys/1'); + vp.proof.should.have.property('challenge', '12ec21'); + vp.proof.should.have.property('created'); + vp.proof.should.not.have.property('jws'); + }); + }); + }); +} diff --git a/test/10-verify.spec.js b/test/20-verify.spec.js similarity index 78% rename from test/10-verify.spec.js rename to test/20-verify.spec.js index 968f36df..9c368b23 100644 --- a/test/10-verify.spec.js +++ b/test/20-verify.spec.js @@ -101,252 +101,6 @@ before(async () => { // run tests on each version of VCs for(const [version, mockCredential] of versionedCredentials) { describe(`Verifiable Credentials Data Model ${version}`, async function() { - describe('vc.issue()', () => { - it('should issue a verifiable credential with proof', async () => { - const credential = mockCredential(); - const verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - }); - it('should issue a verifiable credential with out id', async () => { - const credential = mockCredential(); - delete credential.id; - const verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - should.not.exist(verifiableCredential.id, 'Expected no "vc.id".'); - }); - it('should throw an error on missing verificationMethod', async () => { - const suite = new Ed25519Signature2018({ - // Note no key id or verificationMethod passed to suite - key: await Ed25519VerificationKey2018.generate() - }); - let error; - try { - await vc.issue({ - credential: mockCredential(), - suite - }); - } catch(e) { - error = e; - } - should.exist(error, - 'Should throw error when "verificationMethod" property is missing'); - error.should.be.instanceof(TypeError); - error.message.should - .contain('"suite.verificationMethod" property is required.'); - }); - if(version === 1.0) { - it('should issue an expired verifiable credential', async () => { - const keyPair = await Ed25519VerificationKey2018.generate(); - const fp = Ed25519VerificationKey2018 - .fingerprintFromPublicKey({ - publicKeyBase58: keyPair.publicKeyBase58 - }); - keyPair.id = `did:key:${fp}#${fp}`; - const credential = mockCredential(); - credential.id = `urn:uuid:${uuid()}`; - credential.issuer = `did:key:${fp}`; - credential.expirationDate = '2020-05-31T19:21:25Z'; - const verifiableCredential = await vc.issue({ - credential, - suite: new Ed25519Signature2018({ - key: keyPair - }), - // set `now` to expiration date, allowing the credential - // to be issued - // without failing the expired check - now: (new Date('2020-05-31T19:21:25Z')), - documentLoader - }); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - }); - it('should add "issuanceDate" to verifiable credentials', async () => { - const credential = mockCredential(); - delete credential.issuanceDate; - const now = new Date(); - const expectedIssuanceDate = `${now.toISOString().slice(0, -5)}Z`; - const verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader, - now - }); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - verifiableCredential.should.have.property( - 'issuanceDate', - expectedIssuanceDate - ); - }); - } - if(version === 2.0) { - it('should issue "validUntil" in the future', async () => { - const credential = mockCredential(); - credential.issuer = 'did:example:12345'; - // set validUntil one year in the future - credential.validUntil = createSkewedTimeStamp({skewYear: 1}); - let error; - let verifiableCredential; - try { - verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - } catch(e) { - error = e; - } - should.not.exist(error, - 'Should not throw error when issuing "validUntil" in future'); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - // ensure validUntil is present and has correct timestamp - verifiableCredential.should.have.property( - 'validUntil', - credential.validUntil - ); - }); - it('should issue "validUntil" in the past', async () => { - const credential = mockCredential(); - credential.issuer = 'did:example:12345'; - // set validUntil one year in the past - credential.validUntil = createSkewedTimeStamp({skewYear: -1}); - let error; - let verifiableCredential; - try { - verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - } catch(e) { - error = e; - } - should.not.exist(error, - 'Should not throw error when issuing with "validUntil" in past'); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - // ensure validUntil is present and has correct timestamp - verifiableCredential.should.have.property( - 'validUntil', - credential.validUntil - ); - }); - it('should issue "validFrom" in the past', async () => { - const credential = mockCredential(); - credential.issuer = 'did:example:12345'; - credential.validFrom = createSkewedTimeStamp({skewYear: -1}); - let error; - let verifiableCredential; - try { - verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - } catch(e) { - error = e; - } - should.not.exist(error, - 'Should not throw error when issuing "validFrom" in past'); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - // ensure validFrom is present and has correct timestamp - verifiableCredential.should.have.property( - 'validFrom', - credential.validFrom - ); - }); - it('should issue "validFrom" in the future', async () => { - const credential = mockCredential(); - credential.issuer = 'did:example:12345'; - credential.validFrom = createSkewedTimeStamp({skewYear: 1}); - let error; - let verifiableCredential; - try { - verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - } catch(e) { - error = e; - } - should.not.exist(error, - 'Should not throw error when issuing "validFrom" in future'); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - // ensure validFrom is present and has correct timestamp - verifiableCredential.should.have.property( - 'validFrom', - credential.validFrom - ); - }); - it('should issue both "validFrom" and "validUntil"', async () => { - const credential = mockCredential(); - credential.issuer = 'did:example:12345'; - credential.validFrom = createSkewedTimeStamp({skewYear: -1}); - credential.validUntil = createSkewedTimeStamp({skewYear: 1}); - let error; - let verifiableCredential; - try { - verifiableCredential = await vc.issue({ - credential, - suite, - documentLoader - }); - } catch(e) { - error = e; - } - should.not.exist( - error, - 'Should not throw when issuing VC with both "validFrom" and' + - '"validUntil"' - ); - verifiableCredential.should.exist; - verifiableCredential.should.be.an('object'); - verifiableCredential.should.have.property('proof'); - verifiableCredential.proof.should.be.an('object'); - // ensure validFrom & validUntil are present - // and have correct timestamps - verifiableCredential.should.have.property( - 'validFrom', - credential.validFrom - ); - verifiableCredential.should.have.property( - 'validUntil', - credential.validUntil - ); - }); - } - }); - describe('vc.createPresentation()', () => { it('should create an unsigned presentation', () => { const presentation = vc.createPresentation({ @@ -361,32 +115,6 @@ for(const [version, mockCredential] of versionedCredentials) { presentation.should.not.have.property('proof'); }); }); - - describe('vc.signPresentation()', () => { - it('should create a signed VP', async () => { - const presentation = vc.createPresentation({ - verifiableCredential: mockCredential(), - id: 'test:ebc6f1c2', - holder: 'did:ex:holder123', - version - }); - const vp = await vc.signPresentation({ - presentation, - suite, // from before() block - challenge: '12ec21', - documentLoader - }); - vp.should.have.property('proof'); - vp.proof.should.have.property('type', 'Ed25519Signature2018'); - vp.proof.should.have.property('proofPurpose', 'authentication'); - vp.proof.should.have.property('verificationMethod', - 'https://example.edu/issuers/keys/1'); - vp.proof.should.have.property('challenge', '12ec21'); - vp.proof.should.have.property('created'); - vp.proof.should.have.property('jws'); - }); - }); - describe('verify API (credentials)', () => { it('should verify a vc', async () => { const verifiableCredential = await vc.issue({ diff --git a/test/20-dateRegex.spec.js b/test/30-dateRegex.spec.js similarity index 100% rename from test/20-dateRegex.spec.js rename to test/30-dateRegex.spec.js diff --git a/test/contexts/index.js b/test/contexts/index.js index c2efb969..38569827 100644 --- a/test/contexts/index.js +++ b/test/contexts/index.js @@ -14,9 +14,13 @@ import { contexts as didContexts } from 'did-context'; import { - constants as ed25519Constants, - contexts as ed25519Contexts, + constants as ed25519Constants2018, + contexts as ed25519Contexts2018, } from 'ed25519-signature-2018-context'; +import { + constants as ed25519Constants2020, + contexts as ed25519Contexts2020, +} from 'ed25519-signature-2020-context'; import { CONTEXT_V1 as odrlCtx, CONTEXT_URL_V1 as odrlCtxUrl @@ -38,7 +42,8 @@ import {nullId} from './null_id.js'; import {nullType} from './null_type.js'; import {nullVersion} from './null_version.js'; -const {CONTEXT_URL: ED25519_CONTEXT_URL} = ed25519Constants; +const {CONTEXT_URL: ED25519_2018_CONTEXT_URL} = ed25519Constants2018; +const {CONTEXT_URL: ED25519_2020_CONTEXT_URL} = ed25519Constants2020; const {CREDENTIALS_CONTEXT_V1_URL} = credentialsConstants; const {CONTEXT_URL: CREDENTIALS_CONTEXT_V2_URL} = credentialsV2Constants; const {CREDENTIALS_V2_EXAMPLE_CONTEXT_URL} = vcExamplesV2Constants; @@ -62,9 +67,13 @@ export const validContexts = { url: CREDENTIALS_CONTEXT_V2_URL, value: credentialsV2Contexts.get(CREDENTIALS_CONTEXT_V2_URL) }, - ed25519Context: { - url: ED25519_CONTEXT_URL, - value: ed25519Contexts.get(ED25519_CONTEXT_URL) + ed25519Suite2018Context: { + url: ED25519_2018_CONTEXT_URL, + value: ed25519Contexts2018.get(ED25519_2018_CONTEXT_URL) + }, + ed25519Suite2020Context: { + url: ED25519_2020_CONTEXT_URL, + value: ed25519Contexts2020.get(ED25519_2020_CONTEXT_URL) }, odrl: { url: odrlCtxUrl, diff --git a/test/mocks/credential-issuer-multi-direction-name-ok.json b/test/mocks/credential-issuer-multi-direction-name-ok.json new file mode 100644 index 00000000..3b7c9380 --- /dev/null +++ b/test/mocks/credential-issuer-multi-direction-name-ok.json @@ -0,0 +1,28 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2" + ], + "type": [ + "VerifiableCredential" + ], + "issuer": { + "id": "did:issuer:dog", + "name": [{ + "@value":"Dog", + "@language": "en", + "@direction": "ltr" + }, { + "@value":"Chien", + "@language": "fr", + "@direction": "ltr" + + }, { + "@value":"Cane", + "@language": "it", + "@direction": "ltr" + }] + }, + "credentialSubject": { + "id": "did:example:subject" + } +} diff --git a/test/mocks/credential-issuer-multi-language-description-ok.json b/test/mocks/credential-issuer-multi-language-description-ok.json new file mode 100644 index 00000000..692ba1de --- /dev/null +++ b/test/mocks/credential-issuer-multi-language-description-ok.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2" + ], + "type": [ + "VerifiableCredential" + ], + "issuer": { + "id": "did:issuer:dog", + "description": [{ + "@value":"Dog", + "@language": "en" + }, { + "@value":"Chien", + "@language": "fr" + }, { + "@value":"Cane", + "@language": "it" + }] + }, + "credentialSubject": { + "id": "did:example:subject" + } +} diff --git a/test/mocks/credential-issuer-name-language-direction-en-ok.json b/test/mocks/credential-issuer-name-language-direction-en-ok.json new file mode 100644 index 00000000..31aa5355 --- /dev/null +++ b/test/mocks/credential-issuer-name-language-direction-en-ok.json @@ -0,0 +1,19 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2" + ], + "type": [ + "VerifiableCredential" + ], + "issuer": { + "id": "did:example:issuer", + "name": { + "@value":"ExampleIssuer", + "@language": "en", + "@direction": "rtl" + } + }, + "credentialSubject": { + "id": "did:example:subject" + } +} diff --git a/test/mocks/credential-issuer-name-language-en-ok.json b/test/mocks/credential-issuer-name-language-en-ok.json new file mode 100644 index 00000000..24840821 --- /dev/null +++ b/test/mocks/credential-issuer-name-language-en-ok.json @@ -0,0 +1,18 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2" + ], + "type": [ + "VerifiableCredential" + ], + "issuer": { + "id": "did:example:issuer", + "name": { + "@value":"ExampleIssuer", + "@language": "en" + } + }, + "credentialSubject": { + "id": "did:example:subject" + } +} diff --git a/test/mocks/mock.data.js b/test/mocks/mock.data.js index 111bfc8e..052d5055 100644 --- a/test/mocks/mock.data.js +++ b/test/mocks/mock.data.js @@ -1,7 +1,10 @@ /* eslint-disable quotes, quote-props, max-len */ import constants from '../constants.js'; +import {createRequire} from 'node:module'; import {versionedCredentials} from './credential.js'; +const require = createRequire(import.meta.url); + export const mock = {}; const didContexts = [ @@ -31,7 +34,16 @@ const _mixedCredential = () => { export const credentials = mock.credentials = {}; credentials.mixed = _mixedCredential(); - +credentials.features = { + multiple: { + languages: require('./credential-issuer-multi-language-description-ok.json'), + directions: require('./credential-issuer-multi-direction-name-ok.json') + }, + single: { + language: require('./credential-issuer-name-language-en-ok.json'), + direction: require('./credential-issuer-name-language-direction-en-ok.json') + } +}; credentials.alpha = { "@context": [ constants.CREDENTIALS_CONTEXT_URL, {