DEV: Updates to api docs schema validation (#11801)

- Read in schemas from actual json files instead of a ruby hash. This is
helpful because we will be automatically generating .json schema files
from json responses and don't want to manually write ruby hash schema
files.

- Create a helper method for rspec schema validation tests to dry up code
This commit is contained in:
Blake Erickson 2021-01-21 18:23:23 -07:00 committed by GitHub
parent 7434116933
commit c889b676f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 95 deletions

View File

@ -0,0 +1,12 @@
{
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
}

View File

@ -0,0 +1,51 @@
{
"type": "object",
"additionalProperties": false,
"properties": {
"tag_group": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"tag_names": {
"type": "array",
"items": [
]
},
"parent_tag_name": {
"type": "array",
"items": [
]
},
"one_per_topic": {
"type": "boolean"
},
"permissions": {
"type": "object",
"properties": {
"everyone": {
"type": "integer"
}
}
}
},
"required": [
"id",
"name",
"tag_names",
"parent_tag_name",
"one_per_topic",
"permissions"
]
}
},
"required": [
"tag_group"
]
}

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'json'
module SpecSchemas
class SpecLoader
def initialize(filename)
@filename = filename
end
def load
JSON.parse(File.read(File.join(__dir__, "json", "#{@filename}.json")))
end
end
end

View File

@ -1,77 +0,0 @@
# frozen_string_literal: true
module SpecSchemas
class TagGroupCreateRequest
def schemer
schema = {
'type' => 'object',
'additionalProperties' => false,
'properties' => {
'name' => {
'type' => 'string',
}
},
'required' => ['name']
}
end
end
class TagGroupResponse
def schemer
schema = {
'type' => 'object',
'additionalProperties' => false,
'properties' => {
'tag_group' => {
'type' => 'object',
'properties' => {
'id' => {
'type' => 'integer',
},
'name' => {
'type' => 'string',
},
'tag_names' => {
'type' => 'array',
'items' => {
'type' => 'string'
}
},
'parent_tag_name' => {
'type' => 'array',
'items' => {
'type' => 'string'
}
},
'one_per_topic' => {
'type' => 'boolean',
},
'permissions' => {
'type' => 'object',
'properties' => {
'everyone' => {
'type' => 'integer',
'example' => 1
}
}
}
},
'required' => [
'id',
'name',
'tag_names',
'parent_tag_name',
'one_per_topic',
'permissions'
]
}
},
'required' => [
'tag_group'
]
}
end
end
end

View File

@ -5,6 +5,16 @@ RSpec.shared_examples "a JSON endpoint" do |expected_response_status|
submit_request(example.metadata)
end
def expect_schema_valid(schemer, params)
valid = schemer.valid?(params)
unless valid # for debugging
puts
puts "RESPONSE: #{params}"
puts "VALIDATION DETAILS: #{schemer.validate(params).to_a[0]["details"]}"
end
expect(valid).to eq(true)
end
describe "response status" do
it "returns expected response status" do
expect(response.status).to eq(expected_response_status)
@ -13,13 +23,8 @@ RSpec.shared_examples "a JSON endpoint" do |expected_response_status|
describe "request body" do
it "matches the documented request schema" do |example|
schemer = JSONSchemer.schema(expected_request_schema.schemer)
valid = schemer.valid?(params)
unless valid # for debugging
puts params
puts schemer.validate(params).to_a[0]["details"]
end
expect(valid).to eq(true)
schemer = JSONSchemer.schema(expected_request_schema)
expect_schema_valid(schemer, params)
end
end
@ -28,14 +33,9 @@ RSpec.shared_examples "a JSON endpoint" do |expected_response_status|
it "matches the documented response schema" do |example|
schemer = JSONSchemer.schema(
expected_response_schema.schemer,
expected_response_schema,
)
valid = schemer.valid?(json_response)
unless valid # for debugging
puts json_response
puts schemer.validate(json_response).to_a[0]["details"]
end
expect(valid).to eq(true)
expect_schema_valid(schemer, json_response)
end
end
end

View File

@ -60,17 +60,17 @@ describe 'tags' do
post 'Creates a tag group' do
tags 'Tags'
consumes 'application/json'
expected_request_schema = SpecSchemas::TagGroupCreateRequest.new
expected_request_schema = SpecSchemas::SpecLoader.new('tag_group_create_request').load
parameter name: :params, in: :body, schema: expected_request_schema.schemer
parameter name: :params, in: :body, schema: expected_request_schema
produces 'application/json'
response '200', 'tag group created' do
expected_response_schema = SpecSchemas::TagGroupResponse.new
expected_response_schema = SpecSchemas::SpecLoader.new('tag_group_create_response').load
let(:params) { { 'name' => 'todo' } }
schema(expected_response_schema.schemer)
schema(expected_response_schema)
it_behaves_like "a JSON endpoint", 200 do
let(:expected_response_schema) { expected_response_schema }