Skip to content

Conversation

@DL6ER
Copy link

@DL6ER DL6ER commented Feb 3, 2021

I'm using openapi-example-validator to check if the values returned by our API meet the specifications. This to ensure we cannot forget to update the documentation and to avoid any breaking changes in API output.

Currently, the code does not support much external interaction, e.g., it expects external examples to be present as files. After this PR, we expose two more functions, that may be used by an external script like (fully working example):

const Validator = require('/home/derigs/openapi-examples-validator/src');
const specsFilepath = "test.yaml";

const examples = [
    {string: "somestring", object: {bool: true}},               // OK
    {string: null, object: {bool: false}},                      // OK
    {object: {bool: false}},                                    // string is missing
    {string: "somestring", object: {bool: 123}},                // invalid type
    {string: "somestring", object: {bool: false, extra: 123}},  // extra property
    {object: {bool: 123, extra: 123}},                          // all errors combined
  ];

async function runTests(openApiSpec) {
  for(e in examples) {
    const schemaJsonpath =
      "$.paths./test.get.responses.200.content.application/json.schema";
    const example = examples[e];
    const result = await Validator.validateExampleInline(
      openApiSpec,
      schemaJsonpath,
      example
    );

    if(result.valid !== true) {
      for(i in result.errors) {
        const error = result.errors[i];
        var errormsg = null;
        if(error.keyword === 'additionalProperties')
          errormsg = `${error.message}: ${error.params.additionalProperty} in ${error.dataPath}`;
        else if(error.keyword === 'type')
          errormsg = `${error.message}: ${error.dataPath}`;
        else if(error.keyword === 'required')
          errormsg = `${error.message} in "${error.dataPath}"`;
        else
          errormsg = JSON.stringify(error);
        console.log(`Example ${e}: ${errormsg}`);
      }
    } else {
      console.log(`Example ${e}: OK`);
    }
  }
}

// First, we prepare the OpenAPI spec, then we run the tests on our examples
Validator.prepareOpenapiSpec(specsFilepath, {
  noAdditionalProperties: true,
}).then((openApiSpec) => runTests(openApiSpec));

Output is:

Example 0: OK
Example 1: OK
Example 2: should have required property 'string' in ""
Example 3: should be boolean: ".object.bool"
Example 4: should NOT have additional properties: extra in ".object"
Example 5: should have required property 'string' in ""
Example 5: should be boolean: ".object.bool"
Example 5: should NOT have additional properties: extra in ".object"

I also added tests for the two new functions.

Please mind that this is my very first attempt at anything node-related. I'm happy to improve something if I missed some things.

@DL6ER DL6ER force-pushed the new/example_input branch from 3a601c8 to d68486a Compare February 3, 2021 10:11
@coveralls
Copy link

coveralls commented Feb 3, 2021

Coverage Status

Coverage increased (+0.08%) to 97.79% when pulling ad92336 on DL6ER:new/example_input into 3795c5e on codekie:master.

@codekie
Copy link
Owner

codekie commented Feb 10, 2021

Hi @DL6ER . Thank you for your contribution. So far, the API of this library was more like a "hidden feature". While I planned to provide an official API at some point, I didn't want to do that before I've done some major refactoring as I wanted the API to be more stable.

Unfortunately, I'm rather busy with my job at the moment, but I'll have a closer look at this PR once I've got a bit more time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants