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

Allow more external interaction #124

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
48 changes: 47 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ module.exports = {
'default': validateExamples,
validateFile,
validateExample,
validateExamplesByMap
validateExamplesByMap,
prepareOpenapiSpec,
validateExampleInline
};

// IMPLEMENTATION DETAILS
Expand Down Expand Up @@ -220,6 +222,50 @@ async function validateExample(filePathSchema, pathSchema, filePathExample, { no
);
}

/**
* Validates a single example given as argument
* @param {object} openapiSpec OpenAPI-spec as prepared object
* @param {String} pathSchema JSON-path to the schema
* @param {object} example External example as JSON-object
* @returns {ValidationResponse}
*/
async function validateExampleInline(openapiSpec, pathSchema, example) {
let schema = null;
const filePathExample = 'inline';
try {
schema = _extractSchema(pathSchema, openapiSpec);
} catch (err) {
return createValidationResponse({ errors: [ApplicationError.create(err)] });
}
return _validate(
statistics => _validateExample({
createValidator: _initValidatorFactory(openapiSpec),
schema,
example,
statistics,
filePathExample
})
);
}

/**
* Prepares and returns an OpenAPI specs file as reusable object
* @param {String} filePathSchema File-path to the OpenAPI-spec
* @param {boolean} [noAdditionalProperties=false] Don't allow properties that are not described in the schema
* @returns {object}
*/
async function prepareOpenapiSpec(filePathSchema, { noAdditionalProperties } = {}) {
let openapiSpec = null;
try {
openapiSpec = await _parseSpec(filePathSchema);
openapiSpec = Determiner.getImplementation(openapiSpec)
.prepare(openapiSpec, { noAdditionalProperties });
} catch (err) {
return createValidationResponse({ errors: [ApplicationError.create(err)] });
}
return openapiSpec;
}

// Private

/**
Expand Down
131 changes: 130 additions & 1 deletion test/specs/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// IMPORTS

const path = require('path'),
{ validateFile, validateExample, 'default': validateExamples, validateExamplesByMap } = require('../../src'),
{
validateFile,
validateExample,
'default': validateExamples,
validateExamplesByMap,
prepareOpenapiSpec,
validateExampleInline
} = require('../../src'),
{
loadTestData,
getPathOfTestData
Expand Down Expand Up @@ -119,4 +126,126 @@ describe('Main API', function() {
});
});
});
describe('prepareOpenapiSpec', function() {
describe('be able to load v2.0 file', () => {
it('without errors', async() => {
(await prepareOpenapiSpec(getPathOfTestData('v2/valid-single-example'))).swagger
.should.deep.equal("2.0");
});
});
describe('be able to load v3.0 file', () => {
it('without errors', async() => {
(await prepareOpenapiSpec(getPathOfTestData('v3/simple-api-with-example'))).openapi
.should.deep.equal("3.0.0");
});
});
describe('should throw errors, when the files can\'t be found:', function() {
it('The schema-file', async() => {
const result = await prepareOpenapiSpec(FILE_PATH__NOT_EXISTS);
result.valid.should.equal(false);
result.errors.should.deep.equal([
new ApplicationError(ErrorType.jsENOENT, {
message: `ENOENT: no such file or directory, open '${ FILE_PATH__NOT_EXISTS }'`,
params: {
path: FILE_PATH__NOT_EXISTS
}
})
]);
});
});
});
describe('validateExampleInline', function() {
const example1 = {
"versions": [{
"status": "CURRENT",
"updated": "2016-01-21T11:33:21Z",
"id": "v1.0",
"links": [{
"href": "http://127.0.0.1:8774/v1/",
"rel": "self"
}]
}]
};
const example2 = {
"versions": [{
"status": "CURRENT",
"updated": "2016-01-21T11:33:21Z",
"id": 1.0,
"links": [{
"href": "http://127.0.0.1:8774/v1/",
"rel": "self"
}]
}]
};
it('be able to validate example without errors', async() => {
const openApiSpec = await prepareOpenapiSpec(getPathOfTestData('v2/valid-single-example'));
const pathSchema = "$.paths./.get.responses.200.schema";
const result = await validateExampleInline(
openApiSpec,
pathSchema,
example1);
result.valid.should.equal(true);
});
it('when the response-schema cannot be found', async() => {
const openApiSpec = await prepareOpenapiSpec(getPathOfTestData('v2/valid-single-example'));
const pathSchema = "$.paths./.get.responses.401.schema";
const result = await validateExampleInline(
openApiSpec,
pathSchema,
example1);
result.valid.should.equal(false);
result.errors.should.deep.equal([
new ApplicationError(ErrorType.jsonPathNotFound, {
message: `Path to schema can't be found: '${pathSchema}'`,
params: {
path: pathSchema
},
type: 'JsonPathNotFound'
})
]);
});
it('throw error on example missing required property', async() => {
const openApiSpec = await prepareOpenapiSpec(getPathOfTestData('v2/valid-single-example'));
const pathSchema = "$.paths./.get.responses.200.schema";
const result = await validateExampleInline(
openApiSpec,
pathSchema,
example2);
result.valid.should.equal(false);
result.errors.should.deep.equal([new ApplicationError(ErrorType.validation, {
dataPath: '.versions[0].id',
keyword: 'type',
message: 'should be string',
params: {
type: 'string'
},
schemaPath: '#/properties/versions/items/properties/id/type',
exampleFilePath: 'inline'
})]);
});
it('handle multipe examples on the same openApiSpec object', async() => {
const openApiSpec = await prepareOpenapiSpec(getPathOfTestData('v2/valid-single-example'));
const pathSchema = "$.paths./.get.responses.200.schema";
const result1 = await validateExampleInline(
openApiSpec,
pathSchema,
example1);
result1.valid.should.equal(true);
const result2 = await validateExampleInline(
openApiSpec,
pathSchema,
example2);
result2.valid.should.equal(false);
result2.errors.should.deep.equal([new ApplicationError(ErrorType.validation, {
dataPath: '.versions[0].id',
keyword: 'type',
message: 'should be string',
params: {
type: 'string'
},
schemaPath: '#/properties/versions/items/properties/id/type',
exampleFilePath: 'inline'
})]);
});
});
});