Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions tests/70-conformance.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@ for(const suiteName of cryptosuites) {
mandatoryPointers,
selectivePointers
} = credentials.create[vcVersion];
for(const keyType of vectors.keyTypes) {
conformanceSuite({
verifiers,
suiteName,
keyType,
vcVersion,
credential: document,
mandatoryPointers,
selectivePointers
});
}
conformanceSuite({
verifiers,
suiteName,
keyTypes: vectors.keyTypes,
vcVersion,
credential: document,
mandatoryPointers,
selectivePointers
});
}
}
37 changes: 37 additions & 0 deletions tests/80-data-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*!
* Copyright 2024 Digital Bazaar, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
import {dataModelSuite} from './suites/data-model.js';
import {endpoints} from 'vc-test-suite-implementations';
import {getSuiteConfig} from './test-config.js';

const cryptosuites = [
'ecdsa-rdfc-2019',
'ecdsa-sd-2023'
//FIXME implement jcs 'ecdsa-jcs-2019'
];

for(const suiteName of cryptosuites) {
const {tags, credentials, vectors} = getSuiteConfig(suiteName);
const {match: issuers} = endpoints.filterByTag({
tags: [...tags],
property: 'issuers'
});
for(const vcVersion of vectors.vcTypes) {
const {
document,
mandatoryPointers,
selectivePointers
} = credentials.create[vcVersion];
dataModelSuite({
issuers,
suiteName,
keyTypes: vectors.keyTypes,
vcVersion,
credential: document,
mandatoryPointers,
selectivePointers
});
}
}
86 changes: 46 additions & 40 deletions tests/suites/conformance.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {getSuite} from '../vc-generator/cryptosuites.js';
export function conformanceSuite({
verifiers,
suiteName,
keyType,
keyTypes,
vcVersion,
credential,
mandatoryPointers,
Expand All @@ -24,52 +24,58 @@ export function conformanceSuite({
return describe(`${suiteName} - Conformance - VC ${vcVersion}`, function() {
this.matrix = true;
this.report = true;
this.implemented = [...verifiers];
this.implemented = [];
this.rowLabel = 'Test Name';
this.columnLabel = 'Implementation';
let credentials = new Map();
const credentials = new Map(keyTypes.map(kt => [kt, null]));
before(async function() {
credentials = await setup({
credential,
mandatoryPointers,
selectivePointers,
suiteName,
keyType
});
for(const keyType of keyTypes) {
credentials.set(keyType, await setup({
credential,
mandatoryPointers,
selectivePointers,
suiteName,
keyType
}));
}
});
for(const [name, {endpoints}] of verifiers) {
const [verifier] = endpoints;
describe(`${name}: ${keyType}`, function() {
beforeEach(function() {
this.currentTest.cell = {
rowId: this.currentTest.title,
columnId: this.currentTest.parent.title
};
});
it('Specifically, all relevant normative statements in Sections 2. ' +
'Data Model and 3. Algorithms of this document MUST be enforced.',
async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#:~:text=Specifically%2C%20all%20relevant%20normative%20statements%20in%20Sections%202.%20Data%20Model%20and%203.%20Algorithms%20of%20this%20document%20MUST%20be%20enforced.';
for(const [key, credential] of credentials) {
await assertions.verificationFail({
verifier,
credential,
reason: `Should not verify VC with ${key}`
});
}
});
it('Conforming processors MUST produce errors when non-conforming ' +
'documents are consumed.', async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#:~:text=Conforming%20processors%20MUST%20produce%20errors%20when%20non%2Dconforming%20documents%20are%20consumed.';
for(const [key, credential] of credentials) {
await assertions.verificationFail({
verifier,
credential,
reason: `Should not verify VC with ${key}`
});
}
for(const keyType of keyTypes) {
// add implementer name and keyType to test report
this.implemented.push(`${name}: ${keyType}`);
describe(`${name}: ${keyType}`, function() {
beforeEach(function() {
this.currentTest.cell = {
rowId: this.currentTest.title,
columnId: this.currentTest.parent.title
};
});
it('Specifically, all relevant normative statements in Sections 2. ' +
'Data Model and 3. Algorithms of this document MUST be enforced.',
async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#:~:text=Specifically%2C%20all%20relevant%20normative%20statements%20in%20Sections%202.%20Data%20Model%20and%203.%20Algorithms%20of%20this%20document%20MUST%20be%20enforced.';
for(const [key, credential] of credentials.get(keyType)) {
await assertions.verificationFail({
verifier,
credential,
reason: `Should not verify VC with ${key}`
});
}
});
it('Conforming processors MUST produce errors when non-conforming ' +
'documents are consumed.', async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#:~:text=Conforming%20processors%20MUST%20produce%20errors%20when%20non%2Dconforming%20documents%20are%20consumed.';
for(const [key, credential] of credentials.get(keyType)) {
await assertions.verificationFail({
verifier,
credential,
reason: `Should not verify VC with ${key}`
});
}
});
});
});
}
}
});
}
Expand Down
130 changes: 130 additions & 0 deletions tests/suites/data-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*!
* Copyright 2024 Digital Bazaar, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
import {createInitialVc, endpointCheck} from '../helpers.js';
import {
assertions,
} from 'data-integrity-test-suite-assertion';
import {didResolver} from '../didResolver.js';
import {expect} from 'chai';

export function dataModelSuite({
issuers,
suiteName,
keyTypes,
vcVersion,
credential,
mandatoryPointers
}) {
return describe(`${suiteName} - Data Model - VC ${vcVersion}`, function() {
this.matrix = true;
this.report = true;
this.implemented = [];
this.rowLabel = 'Test Name';
this.columnLabel = 'Implementation';
for(const [name, {endpoints}] of issuers) {
for(const keyType of keyTypes) {
for(const issuer of endpoints) {
// does the endpoint support this test?
if(!endpointCheck({endpoint: issuer, keyType, vcVersion})) {
continue;
}
// add implementer name and keyType to test report
this.implemented.push(`${name}: ${keyType}`);
describe(`${name}: ${keyType}`, function() {
let securedCredential = null;
let proofs = [];
before(async function() {
securedCredential = await createInitialVc({
issuer,
vcVersion,
vc: credential,
mandatoryPointers
});
if(securedCredential) {
proofs = Array.isArray(securedCredential.proof) ?
securedCredential?.proof : [securedCredential?.proof];
// only test proofs that match the relevant cryptosuite
proofs = proofs.filter(p => p?.cryptosuite === suiteName);
}
});
beforeEach(function() {
this.currentTest.cell = {
rowId: this.currentTest.title,
columnId: this.currentTest.parent.title
};
});
function assertBefore() {
expect(
securedCredential,
`Expected issuer ${name}: ${keyType} to issue a VC.`
).to.exist;
expect(
securedCredential,
'Expected VC to be an object.'
).to.be.an('object');
}
it('The publicKeyMultibase value of the verification method MUST ' +
'start with the base-58-btc prefix (z), as defined in the ' +
'Multibase section of Controller Documents 1.0. ',
async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#data-model:~:text=The%20publicKeyMultibase%20value%20of%20the%20verification%20method%20MUST%20start%20with%20the%20base%2D58%2Dbtc%20prefix%20(z)%2C%20as%20defined%20in%20the%20Multibase%20section%20of%20Controller%20Documents%201.0.';
assertBefore();
for(const proof of proofs) {
expect(proof.verificationMethod).to.exist;
expect(proof.verificationMethod).to.be.a('string');
const didDoc = await didResolver({
url: proof.verificationMethod});
expect(didDoc).to.be.an('object');
expect(didDoc.publicKeyMultibase).to.be.a('string');
expect(
assertions.shouldBeBs58(didDoc.publicKeyMultibase),
'Expected "publicKeyMultibase" to be Base58 encoded.'
).to.be.true;
}
});
it('Any other encoding MUST NOT be allowed. (verificationMethod)',
async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#multikey';
assertBefore();
for(const proof of proofs) {
expect(proof.verificationMethod).to.exist;
expect(proof.verificationMethod).to.be.a('string');
const didDoc = await didResolver({
url: proof.verificationMethod});
expect(didDoc).to.be.an('object');
expect(didDoc.publicKeyMultibase).to.be.a('string');
expect(
assertions.shouldBeBs58(didDoc.publicKeyMultibase),
'Expected "publicKeyMultibase" to be Base58 encoded.'
).to.be.true;
}
});
it('The type property MUST be DataIntegrityProof.',
async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#multikey:~:text=The%20type%20property%20MUST%20be%20DataIntegrityProof.';
assertBefore();
for(const proof of proofs) {
expect(proof.type).to.exist;
expect(proof.type).to.be.a('string');
expect(proof.type).to.equal('DataIntegrityProof');
}
});
it('The cryptosuite property MUST be ecdsa-rdfc-2019, ' +
'ecdsa-jcs-2019, or ecdsa-sd-2023.', async function() {
this.test.link = 'https://w3c.github.io/vc-di-ecdsa/#multikey:~:text=The%20cryptosuite%20property%20MUST%20be%20ecdsa%2Drdfc%2D2019%2C%20ecdsa%2Djcs%2D2019%2C%20or%20ecdsa%2Dsd%2D2023.';
assertBefore();
for(const proof of proofs) {
expect(proof.cryptosuite).to.exist;
expect(proof.cryptosuite).to.be.a('string');
expect(proof.cryptosuite).to.be.oneOf(
['ecdsa-rdfc-2019', 'edcsa-jcs-2019', 'ecdsa-sd-2023']);
}
});
});
}
}
}
});
}