openapi-library / OpenAPIValidators

Use Jest or Chai to assert that HTTP responses satisfy an OpenAPI spec
MIT License
191 stars 35 forks source link

Add support for $ref to external schema from api.json #216

Open ahenket opened 3 years ago

ahenket commented 3 years ago

OpenAPI version 3.0.3

Is your feature request related to a problem? Please describe. I have 197kb worth of schema that I keep separate from the api specification itself. This in turn means that path parameters, responses and requestBody use $ref to a different file to get those. This is currently not supported and that leaves me without option to use satisfyApiSpec in my tests. Example fragment of my api definition:

  "200": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "api-schema.json#/definitions/DatasetList"
        }     
      }
    }
  }

Describe the solution you'd like I would like support for external JSON Schema to be able to test against my api specification.

Describe alternatives you've considered Manual validation of a couple key fields.

Additional context The actual type of error I get with my api definition running tests with mochajs/chai:

     AssertionError: expected res to satisfy API spec 

expected res to satisfy the '200' response defined for endpoint 'GET /dataset' in your API spec 
res did not satisfy it because: response can't resolve reference ./api-schema.json#/definitions/DatasetList 

res contained: { body: { artifact: 'DS', current: '0', total: '0', all: '0' } } 

The '200' response defined for endpoint 'GET /dataset' in API spec: {
  '200': {
    description: 'List of dataset objects in the project',
    content: {
      'application/json': {
        schema: { '$ref': './api-schema.json#/definitions/DatasetList' },
        examples: {
          'example-1': {
            '$ref': '#components/examples/dataset-list-get-output-example-1'
          }
        }
      },
      'application/xml': {
        schema: { '$ref': './api-schema.json#/definitions/DatasetList' }
      }
    }
  }
}
      at Context.<anonymous> (test/paths.test.js:235:28)
      at processImmediate (internal/timers.js:456:21)

Are you going to resolve the issue? No I don't have the knowledge for that

rwalle61 commented 3 years ago

Hi @ahenket, thanks for this enhancement suggestion! Looks pretty valid. I don't have much time to implement it myself right now, but can support anyone who wants to do it.

Also, if other people would like this enhancement, please upvote, and we'll prioritise it.

npfitz commented 3 years ago

@ahenket If this is still causing you issues, I was able to work around this by using the SwaggerParser package to read the spec and give me an object to pass to jestOpenAPI. In my code:

const jestOpenAPI = require('jest-openapi');
const resolve = require('path').resolve;
const SwaggerParser = require("@apidevtools/swagger-parser");

const api = await SwaggerParser.validate(resolve('./api-spec-root.json'));
jestOpenAPI(api);