Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Related resource integrity test #151

Merged
merged 3 commits into from
Dec 17, 2024
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
123 changes: 89 additions & 34 deletions tests/5-advanced-concepts.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import {addPerTestMetadata, setupMatrix} from './helpers.js';
import {credential, relatedResource} from './fixtures.js';
import assert from 'node:assert/strict';
import chai from 'chai';
import {createRequire} from 'module';
Expand All @@ -22,6 +23,8 @@ const {match} = filterByTag({tags: [tag]});
// 5. Advanced Concepts https://w3c.github.io/vc-data-model/#advanced-concepts
describe('Advanced Concepts', function() {
setupMatrix.call(this, match);
let positiveFixture;
let negativeFixture;
for(const [name, implementation] of match) {
const endpoints = new TestEndpoints({implementation, tag});

Expand Down Expand Up @@ -55,58 +58,110 @@ describe('Advanced Concepts', function() {
it('The value of the relatedResource property MUST be one or more ' +
'objects of the following form:', async function() {
this.test.link = `https://w3c.github.io/vc-data-model/#integrity-of-related-resources:~:text=The%20value%20of%20the%20relatedResource%20property%20MUST%20be%20one%20or%20more%20objects%20of%20the%20following%20form%3A`;
await assert.doesNotReject(endpoints.issue(require(
'./input/relatedResource/relatedResource-digest-sri-ok.json'
)), 'Failed to accept a VC with valid relatedResource objects.');
await assert.doesNotReject(endpoints.issue(require(
'./input/relatedResource/relatedResource-digest-multibase-ok.json'
)), 'Failed to accept a VC with valid relatedResource objects.');
await assert.doesNotReject(endpoints.issue(require(
'./input/relatedResource/relatedResource-with-mediaType-ok.json'
)),
'Failed to accept a VC with valid relatedResource.mediaType values.');
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-list-of-strings-fail.json'
)),
'Failed to reject a VC with a relatedResource as an array of strings.');

positiveFixture = structuredClone(credential);

// digestSRI positive test
positiveFixture.relatedResource = {
id: relatedResource.id,
digestSRI: relatedResource.digestSRI,
};
await assert.doesNotReject(endpoints.issue(positiveFixture),
'Failed to accept a VC with valid relatedResource objects.');

// digestMultibase positive test
positiveFixture.relatedResource = {
id: relatedResource.id,
digestMultibase: relatedResource.digestMultibase,
};
await assert.doesNotReject(endpoints.issue(positiveFixture),
'Failed to accept a VC with valid relatedResource objects.');

// mediaType positive test
positiveFixture.relatedResource = [{
id: relatedResource.id,
mediaType: relatedResource.mediaType,
digestSRI: relatedResource.digestSRI,
}];
await assert.doesNotReject(endpoints.issue(positiveFixture),
'Failed to accept a VC with valid relatedResource mediaType.');

negativeFixture = structuredClone(credential);

// Data model negative test (array of strings)
negativeFixture.relatedResource = [
relatedResource.id
];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource as array of strings.');
});
it('The identifier for the resource is REQUIRED and conforms to the ' +
'format defined in Section 4.4 Identifiers.', async function() {
this.test.link = `https://w3c.github.io/vc-data-model/#integrity-of-related-resources:~:text=The%20identifier%20for%20the%20resource%20is%20REQUIRED%20and%20conforms%20to%20the%20format%20defined%20in%20Section%204.4%20Identifiers.%20The%20value%20MUST%20be%20unique%20among%20the%20list%20of%20related%20resource%20objects.`;
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-missing-id-fail.json'
)),
'Failed to reject a VC with a relatedResource with no `id` field.');

negativeFixture = structuredClone(credential);

// Missing ID negative test
negativeFixture.relatedResource = [{
digestMultibase: relatedResource.digestMultibase,
}];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource with no `id` field.');
});
it('The value MUST be unique ' +
'among the list of related resource objects.', async function() {
this.test.link = `https://w3c.github.io/vc-data-model/#integrity-of-related-resources:~:text=The%20identifier%20for%20the%20resource%20is%20REQUIRED%20and%20conforms%20to%20the%20format%20defined%20in%20Section%204.4%20Identifiers.%20The%20value%20MUST%20be%20unique%20among%20the%20list%20of%20related%20resource%20objects.`;
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-duplicate-id-fail.json'
)),
'Failed to reject a VC with a relatedResource with ' +

negativeFixture = structuredClone(credential);

// Duplicate ID negative test
negativeFixture.relatedResource = [{
id: relatedResource.id,
digestSRI: relatedResource.digestSRI,
}, {
id: relatedResource.id,
digestMultibase: relatedResource.digestMultibase,
}];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource with ' +
'a duplicate `id` field.');
});
it('Each object associated with relatedResource MUST contain at least ' +
'a digestSRI or a digestMultibase value.', async function() {
this.test.link = `https://w3c.github.io/vc-data-model/#integrity-of-related-resources:~:text=Each%20object%20associated%20with%20relatedResource%20MUST%20contain%20at%20least%20a%20digestSRI%20or%20a%20digestMultibase%20value.`;
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-no-digest-fail.json'
)),
'Failed to reject a VC with a relatedResource with no digest info.');

negativeFixture = structuredClone(credential);

// Missing digest negative test
negativeFixture.relatedResource = [{
id: relatedResource.id
}];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource with no digest info.');
});
it('If the digest provided by the issuer does not match the digest ' +
'computed for the retrieved resource, the conforming verifier ' +
'implementation MUST produce an error.', async function() {
this.test.link = `https://w3c.github.io/vc-data-model/#integrity-of-related-resources:~:text=If%20the%20digest%20provided%20by%20the%20issuer%20does%20not%20match%20the%20digest%20computed%20for%20the%20retrieved%20resource%2C%20the%20conforming%20verifier%20implementation%20MUST%20produce%20an%20error.`;
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-digest-sri-fail.json'
)),
'Failed to reject a VC with a relatedResource with wrong digest.');
await assert.rejects(endpoints.issue(require(
'./input/relatedResource/relatedResource-digest-multibase-fail.json'
)),
'Failed to reject a VC with a relatedResource with wrong digest.');

negativeFixture = structuredClone(credential);

// Wrong digestMultibase negative test
negativeFixture.relatedResource = [{
id: relatedResource.id,
digestMultibase: 'uM4RgWQc3RUDtjJCSgTJtTfvpZ7SPEg_LNO0ESlovQC0'
}];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource with wrong digest.');

// Wrong digestSRI negative test
negativeFixture.relatedResource = [{
id: relatedResource.id,
digestSRI: 'sha384-' +
'_rCVIV7fSXXTNIvpiq26jRDyj8JG8TDjij-tD0ewLk4JpnXEz6a5AeeY_1qQ0d0P'
}];
await assert.rejects(endpoints.issue(negativeFixture),
'Failed to reject a VC with a relatedResource with wrong digest.');
});

// 5.4 Refreshing https://w3c.github.io/vc-data-model/#integrity-of-related-resources
Expand Down
7 changes: 7 additions & 0 deletions tests/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,10 @@ export const envelopedPresentation = {
type: 'EnvelopedVerifiablePresentation',
id: `data:application/vp+jwt,${vp_jwt}`
};

export const relatedResource = {
id: 'https://www.w3.org/ns/credentials/v2',
mediaType: 'application/ld+json',
digestSRI: 'sha384-NSOcNpmdIVUxIJGvGUoe22FjTWrXiaXlsZ8q6912LdnR3KraQO2n75Ica4wK4Qeg',
digestMultibase: 'uJKGMkOmFbVJhEfKTduMC2XCyvRAYLjOVmZWwIH1wQ7k',
};

This file was deleted.

This file was deleted.

16 changes: 0 additions & 16 deletions tests/input/relatedResource/relatedResource-digest-sri-fail.json

This file was deleted.

16 changes: 0 additions & 16 deletions tests/input/relatedResource/relatedResource-digest-sri-ok.json

This file was deleted.

19 changes: 0 additions & 19 deletions tests/input/relatedResource/relatedResource-duplicate-id-fail.json

This file was deleted.

This file was deleted.

14 changes: 0 additions & 14 deletions tests/input/relatedResource/relatedResource-missing-id-fail.json

This file was deleted.

16 changes: 0 additions & 16 deletions tests/input/relatedResource/relatedResource-no-digest-fail.json

This file was deleted.

21 changes: 0 additions & 21 deletions tests/input/relatedResource/relatedResource-with-mediaType-ok.json

This file was deleted.

Loading