Skip to content

Commit

Permalink
feat: validator should check for mandatory swagger or openapi field (#…
Browse files Browse the repository at this point in the history
…137)

* feat: validator should check for mandatory swagger or openapi field

* fix: invalid regular expression. Added more test coverage increase code coverage
  • Loading branch information
SaltedCaramelCoffee authored Feb 17, 2020
1 parent 7a05a41 commit b4275d3
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ module.exports.validate = function({ resolvedSpec }) {
// If PATCH operation doesn't exist for path, POST operationId should start with "update"
if (
!allPathOperations.includes('patch') &&
!operationId.match(/^(update[a-zA-Z0-9_]+/m)
!operationId.match(/^update[a-zA-Z0-9_]+/m)
) {
checkPassed = false;
verbs.push('update');
Expand Down
41 changes: 41 additions & 0 deletions src/plugins/validation/oas3/semantic-validators/openapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Assertation 1:
// check if openapi field exist

// Assertation 2:
// make sure the field is of type string

// Assertation 3:
// make sure the string follows semantic versioning 2.0.0

module.exports.validate = function({ jsSpec }) {
const errors = [];
const warnings = [];

// Regex taken from Semantic Versioning 2.0.0 documentation to check if string follows Semantic Versioning
// https://semver.org/
// Regex from: https://regex101.com/r/vkijKf/1/

const semverRegex = new RegExp(
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/gm
);

const openapi = jsSpec.openapi;

if (!openapi) {
errors.push({
path: ['openapi'],
message: 'API definition must have an `openapi` field'
});
} else if (typeof openapi !== 'string') {
errors.push({
path: ['openapi'],
message: 'API definition must have an `openapi` field as type string'
});
} else if (!openapi.match(semverRegex)) {
errors.push({
path: ['openapi'],
message: '`openapi` string must follow Semantic Versioning 2.0.0'
});
}
return { errors, warnings };
};
33 changes: 33 additions & 0 deletions src/plugins/validation/swagger2/semantic-validators/swagger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Assertation 1:
// check if swagger field exist

// Assertation 2:
// make sure the swagger field is of type string

// Assertation 3:
// make sure the value of swagger field must be "2.0"

module.exports.validate = function({ jsSpec }) {
const errors = [];
const warnings = [];

const swagger = jsSpec.swagger;

if (!swagger) {
errors.push({
path: ['swagger'],
message: 'API definition must have an `swagger` field'
});
} else if (typeof swagger !== 'string') {
errors.push({
path: ['swagger'],
message: 'API definition must have an `swagger` field as type string'
});
} else if (swagger !== '2.0') {
errors.push({
path: ['swagger'],
message: '`swagger` string must have the value `2.0`'
});
}
return { errors, warnings };
};
5 changes: 1 addition & 4 deletions test/plugins/validation/2and3/operation-ids.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe('validation plugin - semantic - operation-ids', function() {
},
'/coffee': {
get: {
operationId: 'get books'
operationId: 'get_books'
},
post: {
operationId: 'change_books'
Expand Down Expand Up @@ -158,9 +158,6 @@ describe('validation plugin - semantic - operation-ids', function() {
},
put: {
operationId: 'changeCoffee2'
},
patch: {
operationId: 'changeCoffee3'
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions test/plugins/validation/oas3/openapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const expect = require('expect');
const {
validate
} = require('../../../../src/plugins/validation/oas3/semantic-validators/openapi');

describe('validation plugin - semantic - openapi', () => {
//this is for openapi object
it('should return an error when an API definition does not have openapi field', () => {
const spec = {
Openapi: '3.0.0'
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['openapi']);
expect(res.errors[0].message).toEqual(
'API definition must have an `openapi` field'
);
});

it('should return an error when an openapi field is not a string', () => {
const spec = {
openapi: 123
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['openapi']);
expect(res.errors[0].message).toEqual(
'API definition must have an `openapi` field as type string'
);
});

it('should return an error when an openapi does not conform to semantic versioning 2.0.0', () => {
const spec = {
openapi: 'v1.0.10'
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['openapi']);
expect(res.errors[0].message).toEqual(
'`openapi` string must follow Semantic Versioning 2.0.0'
);
});
});
46 changes: 46 additions & 0 deletions test/plugins/validation/swagger2/swagger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const expect = require('expect');
const {
validate
} = require('../../../../src/plugins/validation/swagger2/semantic-validators/swagger');

describe('validation plugin - semantic - swagger', () => {
//this is for openapi object
it('should return an error when an API definition does not have swagger field', () => {
const spec = {
Swagger: '2.0'
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['swagger']);
expect(res.errors[0].message).toEqual(
'API definition must have an `swagger` field'
);
});

it('should return an error when an swagger field is not a string', () => {
const spec = {
swagger: 123
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['swagger']);
expect(res.errors[0].message).toEqual(
'API definition must have an `swagger` field as type string'
);
});

it('should return an error when an swagger field does not have value `2.0`', () => {
const spec = {
swagger: '2.0.0'
};

const res = validate({ jsSpec: spec });
expect(res.errors.length).toEqual(1);
expect(res.errors[0].path).toEqual(['swagger']);
expect(res.errors[0].message).toEqual(
'`swagger` string must have the value `2.0`'
);
});
});

0 comments on commit b4275d3

Please sign in to comment.