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

Implement remaining DID Resolution tests. #86

Merged
merged 11 commits into from
May 6, 2021
276 changes: 136 additions & 140 deletions packages/did-core-test-server/suites/did-resolution/did-resolution.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ if (!suiteConfig) {
suiteConfig = require('./default.js');
}

const utils = require('./utils');
const utils = require('../resolution-utils');

describe('7.1.x DID Resolution', () => {
suiteConfig.resolvers.forEach((implementation) => {
suiteConfig.resolvers.forEach((implementation) => {
let implementationName = `7.1.x DID Resolution - ${implementation.implementation} - ${implementation.implementer}`;

describe(implementationName, () => {
it('All conformant DID resolvers MUST implement the DID resolution functions for at least one DID method and MUST be able to return a DID document in at least one conformant representation.', async () => {
expect(implementation.executions).not.toBeEmpty();
const execution = implementation.executions.find((execution) => (execution.function === 'resolveRepresentation'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the structure of the test 👍

expect(execution).not.toBeFalsy();
utils.expectConformantDidDocumentRepresentation(execution.output.didDocumentStream, execution.output.didResolutionMetadata.contentType);
});
let i = 0;
implementation.executions.forEach((execution) => {
const expectedOutcome = utils.findExpectedOutcome(implementation.expectedOutcomes, i++);
require('./did-resolution').didResolutionTests(execution, expectedOutcome);
require('./did-resolution').didResolutionTests(execution, expectedOutcome, implementation);
});
});
});
102 changes: 0 additions & 102 deletions packages/did-core-test-server/suites/did-resolution/utils.js

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
const isErrorExpectedOutcome = require('./utils').isErrorExpectedOutcome;
const parseDidMethod = require('./utils').parseDidMethod;
const expectAsciiString = require('./utils').expectAsciiString;
const expectXmlDateTimeNormalizedToUtcWithoutPrecision = require('./utils').expectXmlDateTimeNormalizedToUtcWithoutPrecision;
const expectMediaType = require('./utils').expectMediaType;
const expectConformantDidUrl = require('./utils').expectConformantDidUrl;
const expectConformantDidDocument = require('./utils').expectConformantDidDocument;
const expectConformantMetadataStructure = require('./utils').expectConformantMetadataStructure;
const expectKnownConformantMediaType = require('./utils').expectKnownConformantMediaType;
const expectConformantRepresentation = require('./utils').expectConformantRepresentation;
const utils = require('../resolution-utils');
const resolution = require('../did-resolution/did-resolution.js');

const didUrlDereferencingTests = (execution, expectedOutcome) => {
const didUrlDereferencingTests = (execution, expectedOutcome, implementation) => {
const { didUrl, dereferenceOptions } = execution.input;
const { dereferencingMetadata, contentStream, contentMetadata } = execution.output;
describe(didUrl + ' (expected outcome: ' + expectedOutcome + ')', () => {
Expand All @@ -24,36 +16,43 @@ const didUrlDereferencingTests = (execution, expectedOutcome) => {
it.todo('3.2.2 Relative DID URLs - When resolving a relative DID URL reference, the algorithm specified in RFC3986 Section 5: Reference Resolution MUST be used.');
it('A conformant DID URL as a single string.', async() => {
if (! dereferencingMetadata.hasOwnProperty('error') || dereferencingMetadata['error'] !== 'invalidDidUrl') {
expectConformantDidUrl(didUrl);
expect(didUrl).toBeValidDidUrl();
}
});
it('To dereference a DID fragment, the complete DID URL including the DID fragment MUST be used.', async () => {
if(didUrl.includes('#')) {
const didUrlWithoutFragment = didUrl.substring(0, didUrl.indexOf('#'));
const executionWithoutFragment = utils.findExecutionByDidUrl(implementation, didUrlWithoutFragment);
if (executionWithoutFragment !== undefined) {
const contentStreamWithoutFragment = executionWithoutFragment.output.contentStream;
expect(contentStreamWithoutFragment).not.toBe(contentStream);
}
}
});

it.todo('To dereference a DID fragment, the complete DID URL including the DID fragment MUST be used.');

it('This input is REQUIRED.', async () => {
expect(didUrl).not.toBeFalsy();
});
});
describe('dereferenceOptions', () => {
it('A metadata structure.', async () => {
expectConformantMetadataStructure(dereferenceOptions);
utils.expectConformantMetadataStructure(dereferenceOptions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be merged with my part of the test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I was planning to do this later (i.e. better re-use existing test code), after this PR is merged.

});
it('This input is REQUIRED, but the structure MAY be empty.', async () => {
expect(dereferenceOptions).not.toBeFalsy();
});
});
describe('dereferencingMetadata', () => {
it('A metadata structure.', async () => {
expectConformantMetadataStructure(dereferencingMetadata);
utils.expectConformantMetadataStructure(dereferencingMetadata);
});
it('This structure is REQUIRED, and in the case of an error in the dereferencing process, this MUST NOT be empty.', async () => {
expect(dereferencingMetadata).not.toBeFalsy();
if (isErrorExpectedOutcome(expectedOutcome)) {
if (utils.isErrorExpectedOutcome(expectedOutcome)) {
expect(Object.keys(dereferencingMetadata)).not.toHaveLength(0);
}
});
it('If the dereferencing is not successful, this structure MUST contain an error property describing the error.', async () => {
if (isErrorExpectedOutcome(expectedOutcome)) {
if (utils.isErrorExpectedOutcome(expectedOutcome)) {
expect(Object.keys(dereferencingMetadata)).toContain('error');
expect(dereferencingMetadata['error']).toBeTruthy();
}
Expand All @@ -77,15 +76,21 @@ const didUrlDereferencingTests = (execution, expectedOutcome) => {
describe('contentMetadata', () => {
it('If the dereferencing is successful, this MUST be a metadata structure, but the structure MAY be empty.', async () => {
if (! dereferencingMetadata.hasOwnProperty('error')) {
expectConformantMetadataStructure(contentMetadata);
utils.expectConformantMetadataStructure(contentMetadata);
}
});
it('If the contentStream is a DID document, this MUST be a didDocumentMetadata structure as described in DID Resolution.', async () => {
// TODO
describe('If the contentStream is a DID document, this MUST be a didDocumentMetadata structure as described in DID Resolution.', () => {
if (! dereferencingMetadata.hasOwnProperty('error')) {
const didDocument = utils.consumeRepresentation(contentStream, dereferencingMetadata['contentType']);
if (didDocument) {
utils.expectConformantMetadataStructure(contentMetadata);
resolution.testDidDocumentMetadata(contentMetadata, didDocument, execution);
}
}
});
it('If the dereferencing is unsuccessful, this output MUST be an empty metadata structure.', async () => {
if (dereferencingMetadata.hasOwnProperty('error')) {
expectConformantMetadataStructure(contentMetadata);
utils.expectConformantMetadataStructure(contentMetadata);
expect(Object.keys(contentMetadata)).toHaveLength(0);
}
});
Expand All @@ -94,10 +99,10 @@ const didUrlDereferencingTests = (execution, expectedOutcome) => {
describe('accept', () => {
if (dereferenceOptions.hasOwnProperty('accept')) {
it('The Media Type that the caller prefers for contentStream.', async () => {
expectMediaType(dereferenceOptions['accept']);
expect(dereferenceOptions['accept']).toBeMediaType();
});
it('The Media Type MUST be expressed as an ASCII string.', async () => {
expectAsciiString(dereferenceOptions['accept']);
expect(dereferenceOptions['accept']).toBeAsciiString();
});
}
});
Expand All @@ -106,27 +111,27 @@ const didUrlDereferencingTests = (execution, expectedOutcome) => {
describe('contentType', () => {
if (dereferencingMetadata.hasOwnProperty('contentType')) {
it('The Media Type value MUST be expressed as an ASCII string.', async () => {
expectMediaType(dereferencingMetadata['contentType']);
expectAsciiString(dereferencingMetadata['contentType']);
expect(dereferencingMetadata['contentType']).toBeMediaType();
expect(dereferencingMetadata['contentType']).toBeAsciiString();
});
}
});
describe('error', () => {
it('This property is REQUIRED when there is an error in the dereferencing process.', async () => {
if (isErrorExpectedOutcome(expectedOutcome)) {
if (utils.isErrorExpectedOutcome(expectedOutcome)) {
expect(Object.keys(dereferencingMetadata)).toContain('error');
}
});
if (dereferencingMetadata.hasOwnProperty('error')) {
it('The value of this property MUST be a single keyword ASCII string.', async () => {
expectAsciiString(dereferencingMetadata['error']);
expect(dereferencingMetadata['error']).toBeAsciiString();
expect(dereferencingMetadata['error']).not.toMatch('\\s');
});
}
if (expectedOutcome === 'invalidDidErrorUrlOutcome') {
if (expectedOutcome === 'invalidDidUrlErrorOutcome') {
it('invalidDidUrl - The DID URL supplied to the DID URL dereferencing function does not conform to valid syntax.', async () => {
expect(dereferencingMetadata['error']).toBe('invalidDidUrl');
// TODO: Check if the input didUrl is really invalid.
expect(didUrl).not.toBeValidDidUrl();
});
}
if (expectedOutcome === 'notFoundErrorOutcome') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ if (!suiteConfig) {
suiteConfig = require('./default');
}

const utils = require('./utils');
const utils = require('../resolution-utils');

describe('7.2.x DID URL Dereferencing', () => {
let i = 0;
suiteConfig.dereferencers.forEach((dereferencer) => {
dereferencer.executions.forEach((execution) => {
const expectedOutcome = utils.findExpectedOutcome(dereferencer.expectedOutcomes, i++);
require('./did-url-dereferencing').didUrlDereferencingTests(execution, expectedOutcome);
suiteConfig.dereferencers.forEach((implementation) => {
let implementationName = `7.2.x DID URL Dereferencing - ${implementation.implementation} - ${implementation.implementer}`;

describe(implementationName, () => {
let i = 0;
implementation.executions.forEach((execution) => {
const expectedOutcome = utils.findExpectedOutcome(implementation.expectedOutcomes, i++);
require('./did-url-dereferencing').didUrlDereferencingTests(execution, expectedOutcome, implementation);
});
});
});
Loading