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

Commit

Permalink
test: aligns test suites for gavel-spec v2
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-zakharchenko committed Jun 4, 2019
1 parent cbb91d3 commit 71a02bc
Show file tree
Hide file tree
Showing 17 changed files with 320 additions and 189 deletions.
243 changes: 150 additions & 93 deletions lib/next/test/integration/validateMessage.test.js

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions lib/next/test/unit/units/validateBody.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ describe('validateBody', () => {

describe('produces validation error', () => {
it('exactly one error', () => {
assert.lengthOf(result.results, 1);
assert.lengthOf(result.errors, 1);
});

it('has "error" severity', () => {
assert.propertyVal(result.results[0], 'severity', 'error');
assert.propertyVal(result.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.propertyVal(
result.results[0],
result.errors[0],
'message',
`Can't validate real media type 'application/json' against expected media type 'text/plain'.`
);
Expand Down Expand Up @@ -88,7 +88,7 @@ describe('validateBody', () => {
});

it('has no errors', () => {
assert.lengthOf(res.results, 0);
assert.lengthOf(res.errors, 0);
});
});

Expand All @@ -115,12 +115,12 @@ describe('validateBody', () => {

describe('produces content-type error', () => {
it('has "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.match(
res.results[0].message,
res.errors[0].message,
/^Can't validate: real body 'Content-Type' header is 'application\/json' but body is not a parseable JSON:/
);
});
Expand Down Expand Up @@ -155,7 +155,7 @@ describe('validateBody', () => {
});

it('has no errors', () => {
assert.lengthOf(res.results, 0);
assert.lengthOf(res.errors, 0);
});
});

Expand Down Expand Up @@ -186,12 +186,12 @@ describe('validateBody', () => {

describe('produces error', () => {
it('has "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.match(
res.results[0].message,
res.errors[0].message,
/^Can't validate: real body 'Content-Type' header is 'application\/hal\+json' but body is not a parseable JSON:/
);
});
Expand All @@ -218,7 +218,7 @@ describe('validateBody', () => {
});

it('has no errors', () => {
assert.lengthOf(res.results, 0);
assert.lengthOf(res.errors, 0);
});
});

Expand All @@ -239,17 +239,17 @@ describe('validateBody', () => {

describe('produces validation error', () => {
it('exactly one error', () => {
assert.lengthOf(res.results, 1);
assert.lengthOf(res.errors, 1);
});

it('with "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('with explanatory message', () => {
assert.hasAnyKeys(res.results[0], 'message');
assert.hasAnyKeys(res.errors[0], 'message');
assert.propertyVal(
res.results[0],
res.errors[0],
'message',
'Real and expected data does not match.'
);
Expand Down Expand Up @@ -278,7 +278,7 @@ describe('validateBody', () => {
});

it('has no errors', () => {
assert.lengthOf(res.results, 0);
assert.lengthOf(res.errors, 0);
});
});

Expand All @@ -302,16 +302,16 @@ describe('validateBody', () => {

describe('produces validation errors', () => {
it('exactly one error', () => {
assert.lengthOf(res.results, 1);
assert.lengthOf(res.errors, 1);
});

it('has "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.propertyVal(
res.results[0],
res.errors[0],
'message',
`At '/bar' Missing required property: bar`
);
Expand Down Expand Up @@ -344,7 +344,7 @@ describe('validateBody', () => {
});

it('has no errors', () => {
assert.lengthOf(res.results, 0);
assert.lengthOf(res.errors, 0);
});
});

Expand Down Expand Up @@ -372,16 +372,16 @@ describe('validateBody', () => {

describe('produces an error', () => {
it('exactly one error', () => {
assert.lengthOf(res.results, 1);
assert.lengthOf(res.errors, 1);
});

it('has "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.propertyVal(
res.results[0],
res.errors[0],
'message',
`At '/doe' Missing required property: doe`
);
Expand Down
16 changes: 8 additions & 8 deletions lib/next/test/unit/units/validateHeaders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('validateHeaders', () => {
});

it('has no errors', () => {
assert.deepPropertyVal(res, 'results', []);
assert.deepPropertyVal(res, 'errors', []);
});
});

Expand Down Expand Up @@ -83,27 +83,27 @@ describe('validateHeaders', () => {
const missingHeaders = ['accept-language', 'content-type'];

it('for two missing headers', () => {
assert.lengthOf(res.results, missingHeaders.length);
assert.lengthOf(res.errors, missingHeaders.length);
});

describe('for each missing header', () => {
missingHeaders.forEach((headerName, index) => {
describe(headerName, () => {
it('has "error" severity', () => {
assert.propertyVal(res.results[index], 'severity', 'error');
assert.propertyVal(res.errors[index], 'severity', 'error');
});

it('has pointer to header name', () => {
assert.propertyVal(
res.results[index],
res.errors[index],
'pointer',
`/${headerName}`
);
});

it('has explanatory message', () => {
assert.propertyVal(
res.results[index],
res.errors[index],
'message',
`At '/${headerName}' Missing required property: ${headerName}`
);
Expand Down Expand Up @@ -138,16 +138,16 @@ describe('validateHeaders', () => {

describe('produces an error', () => {
it('has one error', () => {
assert.lengthOf(res.results, 1);
assert.lengthOf(res.errors, 1);
});

it('has "error" severity', () => {
assert.propertyVal(res.results[0], 'severity', 'error');
assert.propertyVal(res.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.propertyVal(
res.results[0],
res.errors[0],
'message',
`No validator found for real data media type
"null"
Expand Down
8 changes: 4 additions & 4 deletions lib/next/test/unit/units/validateStatusCode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('validateStatusCode', () => {
});

it('has no errors', () => {
assert.deepPropertyVal(result, 'results', []);
assert.deepPropertyVal(result, 'errors', []);
});
});

Expand Down Expand Up @@ -53,16 +53,16 @@ describe('validateStatusCode', () => {

describe('produces error', () => {
it('exactly one error', () => {
assert.lengthOf(result.results, 1);
assert.lengthOf(result.errors, 1);
});

it('has "error" severity', () => {
assert.propertyVal(result.results[0], 'severity', 'error');
assert.propertyVal(result.errors[0], 'severity', 'error');
});

it('has explanatory message', () => {
assert.propertyVal(
result.results[0],
result.errors[0],
'message',
`Status code is '200' instead of '400'`
);
Expand Down
11 changes: 7 additions & 4 deletions lib/next/units/isValid.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
function isValidComponent(errors) {
return errors.every((error) => error.severity !== 'error');
}

// Returns a boolean indicating whether a given validation result
// concludes two HTTP messages as valid (matching).
// Separated into its own util only to be used in both next and legacy API.
// TODO Move to "validateMessage" after legacy "gavel.validate()" removal.
function isValid(validationResult) {
return Object.values(validationResult).every((resultGroup) => {
return resultGroup.results.every((result) => result.severity !== 'error');
return Object.values(validationResult.field).every((resultGroup) => {
return isValidComponent(resultGroup.errors);
});
}

module.exports = { isValid };
module.exports = { isValid, isValidComponent };
18 changes: 10 additions & 8 deletions lib/next/units/validateBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const contentTypeUtils = require('content-type');
const { TextDiff } = require('../../../lib/validators/text-diff');
const { JsonExample } = require('../../../lib/validators/json-example');
const { JsonSchema } = require('../../../lib/validators/json-schema');
const { isValidComponent } = require('./isValid');

function isPlainText(mediaType) {
return mediaType.type === 'text' && mediaType.subtype === 'plain';
Expand Down Expand Up @@ -157,7 +158,7 @@ function getBodyValidator(realType, expectedType) {
* @param {Object} expected
*/
function validateBody(real, expected) {
const results = [];
const errors = [];
const bodyType = typeof real.body;

if (bodyType !== 'string') {
Expand All @@ -178,20 +179,20 @@ function validateBody(real, expected) {
);

if (realTypeError) {
results.push({
errors.push({
message: realTypeError,
severity: 'error'
});
}

if (expectedTypeError) {
results.push({
errors.push({
message: expectedTypeError,
severity: 'error'
});
}

const hasErrors = results.some((result) =>
const hasErrors = errors.some((result) =>
['error'].includes(result.severity)
);

Expand All @@ -202,7 +203,7 @@ function validateBody(real, expected) {
: getBodyValidator(realType, expectedType);

if (validatorError) {
results.push({
errors.push({
message: validatorError,
severity: 'error'
});
Expand All @@ -216,15 +217,16 @@ function validateBody(real, expected) {
usesJsonSchema ? expected.bodySchema : expected.body
);
const rawData = validator && validator.validate();
const validatorResults = validator ? validator.evaluateOutputToResults() : [];
results.push(...validatorResults);
const validationErrors = validator ? validator.evaluateOutputToResults() : [];
errors.push(...validationErrors);

return {
isValid: isValidComponent(errors),
validator: ValidatorClass && ValidatorClass.name,
realType: mediaTyper.format(realType),
expectedType: mediaTyper.format(expectedType),
rawData,
results
errors
};
}

Expand Down
10 changes: 6 additions & 4 deletions lib/next/units/validateHeaders.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { HeadersJsonExample } = require('../../validators/headers-json-example');
const { isValidComponent } = require('./isValid');

const APIARY_JSON_HEADER_TYPE = 'application/vnd.apiary.http-headers+json';

Expand All @@ -16,7 +17,7 @@ function getHeadersType(headers) {
function validateHeaders(real, expected) {
const realType = getHeadersType(real.headers);
const expectedType = getHeadersType(expected.headers);
const results = [];
const errors = [];

const hasJsonHeaders =
realType === APIARY_JSON_HEADER_TYPE &&
Expand All @@ -28,9 +29,9 @@ function validateHeaders(real, expected) {
const rawData = validator && validator.validate();

if (validator) {
results.push(...validator.evaluateOutputToResults());
errors.push(...validator.evaluateOutputToResults());
} else {
results.push({
errors.push({
message: `\
No validator found for real data media type
"${realType}"
Expand All @@ -42,11 +43,12 @@ and expected data media type
}

return {
isValid: isValidComponent(errors),
validator: validator && 'HeadersJsonExample',
realType,
expectedType,
rawData,
results
errors
};
}

Expand Down
Loading

0 comments on commit 71a02bc

Please sign in to comment.