thoughtbot / json_matchers

Validate your JSON APIs
MIT License
385 stars 40 forks source link

Test for embedded definitions (using single Swagger/OpenAPI file) #80

Open Ajaxy opened 6 years ago

Ajaxy commented 6 years ago

I have a JSON file with embedded schemas in the definitions object. Is it possible to test for those schemas straight with match_json_schema()?

Neither match_json_schema('openapi#/definitions/SomeSchema') or match_json_schema('openapi.json#/definitions/SomeSchema') are seem to work, so now I have to manually create separate files for each schema of my definitions before I run tests.

seanpdoyle commented 6 years ago

@Ajaxy could you share your schema definitions and the JSON you're trying to validate against them?

Ajaxy commented 6 years ago

It's just a regular swagger.json file:

{
  "swagger": "2.0",
  "info": {
    "title": "My API 1.0",
    "description": "...",
    "version": "0.0.1"
  },
  "host": "...",
  "basePath": "/v1",
  "schemes": [
    "https"
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    /* ... */
  },
  "tags": [
    /* ... */
  ],
  "definitions": {
    "Clinic": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "address": {
          "type": "string"
        },
        "latitude": {
          "type": "number"
        },
        "longitude": {
          "type": "number"
        }
      },
      "required": [
        "name",
        "address",
        "latitude",
        "longitude"
      ]
    },
    /* ... */
  }
}

So I'm to trying to check it like this:

expect(result[:clinics][0]).to match_json_schema('swagger.json#/Clinic')
barnaclebarnes commented 6 years ago

I would love to be able to use my OpenAPI schema as the base file for validations. @seanpdoyle Any update on if this is possible? For example for the attached file I want to match the response from the /api/frontend_v2/collections endpoint to the following schema in the document:

paths/"/api/frontend_v2/collections"/get/responses/200/content/"application/json"/schema

write_api.json.txt

Ajaxy commented 6 years ago

@barnaclebarnes I was able to do this with this code:

require 'json'
require 'json_matchers/rspec'

JsonMatchers.schema_root = 'spec/schemas'

file = File.read 'spec/schemas/swagger.json'
swagger = JSON.parse(file, symbolize_names: true)

# Fix for json_matchers single-file restriction
swagger[:definitions].keys.each do |key|
  File.open("spec/schemas/#{key}.json", 'w') do |f|
    f.write(JSON.pretty_generate({
      '$ref': "swagger.json#/definitions/#{key}"
    }))
  end
end