Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

Commit

Permalink
feat: uses ["path", "array"] structure for "location.property" value
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-zakharchenko committed Dec 2, 2019
1 parent 860746d commit 5bc782e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 30 deletions.
31 changes: 31 additions & 0 deletions lib/utils/to-gavel-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const jsonPointer = require('json-pointer');

function splitProperty(property) {
return property.split(/\.|\[|\]/).filter(Boolean);
}

function reduceProperties(acc, property) {
return acc.concat(splitProperty(property));
}

/**
* Converts legacy (Amanda/TV4) error messages
* to the Gavel-compliant structure.
*/
function toGavelResult(legacyErrors) {
return Array.from({ length: legacyErrors.length }, (_, index) => {
const item = legacyErrors[index];
const propertyPath = item.property.reduce(reduceProperties, []);
const pointer = jsonPointer.compile(propertyPath);

return {
message: item.message,
location: {
pointer,
property: propertyPath
}
};
});
}

module.exports = toGavelResult;
35 changes: 5 additions & 30 deletions lib/validators/json-schema-legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const jsonPointer = require('json-pointer');

const { JsonSchemaValidator, META_SCHEMA } = require('./json-schema-next');
const { ValidationErrors } = require('./validation-errors');
const toGavelResult = require('../utils/to-gavel-result');

/**
* Returns a proper article for a given string.
Expand Down Expand Up @@ -103,20 +104,20 @@ class JsonSchemaLegacy extends JsonSchemaValidator {
errors = new ValidationErrors(error);
}
});
} catch (error) {
} catch (internalError) {
errors = new ValidationErrors({
'0': {
property: [],
attributeValue: true,
message: `Validator internal error: ${error.message}`,
message: `Validator internal error: ${internalError.message}`,
validatorName: 'error'
},
length: 1,
errorMessages: {}
});
}

return this.toGavelResult(errors);
return toGavelResult(errors);
}

validateUsingTV4(data) {
Expand Down Expand Up @@ -154,33 +155,7 @@ class JsonSchemaLegacy extends JsonSchemaValidator {
}

const errors = new ValidationErrors(amandaCompatibleError);
return this.toGavelResult(errors);
}

/**
* Converts Amanda-like validation result to the
* unified Gavel public validation result.
*/
toGavelResult(amandaLikeResult) {
const results = Array.from(
{ length: amandaLikeResult.length },
(_, index) => {
const item = amandaLikeResult[index];
const { property, message } = item;
const pathArray = [].concat(property).filter(Boolean);
const pointer = jsonPointer.compile(pathArray);

return {
message,
location: {
pointer,
property
}
};
}
);

return results;
return toGavelResult(errors);
}
}

Expand Down
87 changes: 87 additions & 0 deletions test/unit/utils/to-gavel-result.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const { expect } = require('chai');
const toGavelResult = require('../../../lib/utils/to-gavel-result');

describe('toGavelResult', () => {
// Currently TV4 output is coerced to Amanda format.
// Then Amanda format is coerced to Gavel public API.
describe('given Amanda errors', () => {
let coercedErrors;

before(() => {
coercedErrors = toGavelResult({
length: 2,
0: {
property: ['users', 'username'],
propertyValue: 123,
attributeName: 'type',
attributeValue: 'string',
message: 'Amanda error message'
},
1: {
property: ['friends[2]', 'online'],
propertyValue: false,
attributeName: 'type',
attributeValue: 'boolean',
message: 'Arbitrary error message about "online"'
}
});
});

describe('given coerced to Gavel-compliant error', () => {
it('should return 2 errors', () => {
expect(coercedErrors).to.have.lengthOf(2);
});

describe('given in-object error', () => {
it('should preserve the original error message', () => {
expect(coercedErrors[0]).to.have.property(
'message',
'Amanda error message'
);
});

describe('should produce "location" property', () => {
it('should have "pointer"', () => {
expect(coercedErrors[0]).to.have.nested.property(
'location.pointer',
'/users/username'
);
});

it('should have "property"', () => {
expect(coercedErrors[0].location.property).to.deep.equal([
'users',
'username'
]);
});
});
});

describe('given in-array error', () => {
it('should preserve the original error message', () => {
expect(coercedErrors[1]).to.have.property(
'message',
'Arbitrary error message about "online"'
);
});

describe('should produce "location" property', () => {
it('should have "pointer"', () => {
expect(coercedErrors[1]).to.have.nested.property(
'location.pointer',
'/friends/2/online'
);
});

it('should have "property"', () => {
expect(coercedErrors[1].location.property).to.deep.equal([
'friends',
'2',
'online'
]);
});
});
});
});
});
});

0 comments on commit 5bc782e

Please sign in to comment.