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

feat: validator should check for mandatory swagger or openapi field #137

Merged
merged 4 commits into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`'
);
});
});