Skip to content

Commit

Permalink
feat(ref-imp): add array support for serviceEndpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
nikolockenvitz committed Sep 20, 2022
1 parent df2a5bd commit 9075aa4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 17 deletions.
34 changes: 19 additions & 15 deletions lib/core/versions/latest/DocumentComposer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,22 +345,26 @@ export default class DocumentComposer {
}

// `serviceEndpoint` validations.
const serviceEndpoint = service.serviceEndpoint;
if (typeof serviceEndpoint === 'string') {
const uri = URI.parse(service.serviceEndpoint);
if (uri.error !== undefined) {
throw new SidetreeError(
ErrorCode.DocumentComposerPatchServiceEndpointStringNotValidUri,
`Service endpoint string '${serviceEndpoint}' is not a valid URI.`
);
}
} else if (typeof serviceEndpoint === 'object') {
// Allow `object` type only if it is not an array.
if (Array.isArray(serviceEndpoint)) {
throw new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointCannotBeAnArray);
// transform URI strings and JSON objects into array so that we can run validations more easily
const serviceEndpointValueAsArray = Array.isArray(service.serviceEndpoint) ? service.serviceEndpoint : [service.serviceEndpoint];
for (const serviceEndpoint of serviceEndpointValueAsArray) {
// serviceEndpoint itself must be URI string or non-array object
if (typeof serviceEndpoint === 'string') {
const uri = URI.parse(serviceEndpoint);
if (uri.error !== undefined) {
throw new SidetreeError(
ErrorCode.DocumentComposerPatchServiceEndpointStringNotValidUri,
`Service endpoint string '${serviceEndpoint}' is not a valid URI.`
);
}
} else if (typeof serviceEndpoint === 'object') {
// Allow `object` type only if it is not an array.
if (Array.isArray(serviceEndpoint)) {
throw new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointCannotBeAnArray);
}
} else {
throw new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointMustBeStringOrNonArrayObject);
}
} else {
throw new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointMustBeStringOrNonArrayObject);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/core/versions/latest/models/ServiceModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
export default interface ServiceModel {
id: string;
type: string;
serviceEndpoint: string | object;
serviceEndpoint: string | object | Array<string | object>;
}
45 changes: 44 additions & 1 deletion tests/core/DocumentComposer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ describe('DocumentComposer', async () => {
DocumentComposer['validateAddServicesPatch'](patch);
});

it('should throw error if `serviceEndpoint` is an array.', () => {
it('should allow an array as `serviceEndpoint`.', () => {
const patch = {
action: PatchAction.AddServices,
services: [{
Expand All @@ -478,6 +478,20 @@ describe('DocumentComposer', async () => {
serviceEndpoint: []
}]
};

// Expecting this call to succeed without errors.
DocumentComposer['validateAddServicesPatch'](patch);
});

it('should throw error if `serviceEndpoint` is an array that includes an array.', () => {
const patch = {
action: PatchAction.AddServices,
services: [{
id: 'someId',
type: 'someType',
serviceEndpoint: [[]] // array must contain URI strings or objects but not arrays
}]
};
const expectedError = new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointCannotBeAnArray);
expect(() => { DocumentComposer['validateAddServicesPatch'](patch); }).toThrow(expectedError);
});
Expand All @@ -495,6 +509,19 @@ describe('DocumentComposer', async () => {
expect(() => { DocumentComposer['validateAddServicesPatch'](patch); }).toThrow(expectedError);
});

it('should throw error if `serviceEndpoint` has an invalid type (inside an array).', () => {
const patch = {
action: PatchAction.AddServices,
services: [{
id: 'someId',
type: 'someType',
serviceEndpoint: [123] // Invalid serviceEndpoint type.
}]
};
const expectedError = new SidetreeError(ErrorCode.DocumentComposerPatchServiceEndpointMustBeStringOrNonArrayObject);
expect(() => { DocumentComposer['validateAddServicesPatch'](patch); }).toThrow(expectedError);
});

it('Should throw if `serviceEndpoint` is not valid URI.', () => {
const patch = {
action: PatchAction.AddServices,
Expand All @@ -510,6 +537,22 @@ describe('DocumentComposer', async () => {
ErrorCode.DocumentComposerPatchServiceEndpointStringNotValidUri
);
});

it('Should throw if `serviceEndpoint` is not valid URI (inside an array).', () => {
const patch = {
action: PatchAction.AddServices,
services: [{
id: 'someId',
type: 'someType',
serviceEndpoint: ['http://'] // Invalid URI.
}]
};

JasmineSidetreeErrorValidator.expectSidetreeErrorToBeThrown(
() => DocumentComposer['validateAddServicesPatch'](patch),
ErrorCode.DocumentComposerPatchServiceEndpointStringNotValidUri
);
});
});

describe('validateDocumentPatches()', async () => {
Expand Down

0 comments on commit 9075aa4

Please sign in to comment.