Skip to content

Commit

Permalink
Create assert_response_schema test helper
Browse files Browse the repository at this point in the history
It is a common pattern to use JSON Schema to validate a API response[1], [2]
and [3].

This patch creates the `assert_response_schema` test helper that helps people do
this kind of validation easily on the controller tests.

[1]: https://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher
[2]: https://github.com/sharethrough/json-schema-rspec
[3]: #1011 (comment)
  • Loading branch information
maurogeorge committed Oct 14, 2015
1 parent da7e6dc commit 58cf46a
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 0 deletions.
2 changes: 2 additions & 0 deletions active_model_serializers.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Gem::Specification.new do |spec|
# 'minitest'
# 'thread_safe'

spec.add_runtime_dependency 'json-schema'

# Soft dependency for pagination
spec.add_development_dependency 'kaminari', ' ~> 0.16.3'
spec.add_development_dependency 'will_paginate', '~> 3.0', '>= 3.0.7'
Expand Down
16 changes: 16 additions & 0 deletions lib/active_model/serializer/assertions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'json-schema'

module ActiveModel
class Serializer
module Assertions
def assert_response_schema(schema_path = nil)
controller_path = response.request.filtered_parameters[:controller]
action = response.request.filtered_parameters[:action]
schema_directory = ActiveModel::Serializer.config.schema_path
schema_path ||= "#{controller_path}/#{action}.json"
schema_full_path = "#{schema_directory}/#{schema_path}"
JSON::Validator.validate!(schema_full_path, response.body, strict: true)
end
end
end
end
1 change: 1 addition & 0 deletions lib/active_model/serializer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Configuration
base.config.array_serializer = ActiveModel::Serializer::ArraySerializer
base.config.adapter = :attributes
base.config.jsonapi_resource_type = :plural
base.config.schema_path = 'test/support/schemas'
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/active_model_serializers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ def silence_warnings
require 'active_model/serializer'
require 'active_model/serializable_resource'
require 'active_model/serializer/version'
require 'active_model/serializer/assertions'

require 'action_controller/serialization'
ActiveSupport.on_load(:action_controller) do
include ::ActionController::Serialization
ActionDispatch::Reloader.to_prepare do
ActiveModel::Serializer.serializers_cache.clear
end
ActionController::TestCase.send(:include, ActiveModel::Serializer::Assertions)
end

require 'active_model/serializer/railtie'
46 changes: 46 additions & 0 deletions test/assertions_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'test_helper'

module ActiveModel
class Serializer
class AssertionsTest < ActionController::TestCase
class MyController < ActionController::Base
def index
render json: Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
end

def show
index
end
end

tests MyController

def test_that_assert_with_a_valid_schema
get :index
assert_response_schema
end

def test_that_raises_a_json_schema_with_a_invalid_schema
get :show
assert_raises JSON::Schema::ValidationError do
assert_response_schema
end
end

def test_that_assert_with_a_custom_schema
get :show
assert_response_schema('custom/show.json')
end

def test_that_assert_with_a_custom_schema_directory
original_schema_path = ActiveModel::Serializer.config.schema_path
ActiveModel::Serializer.config.schema_path = 'test/support/custom_schemas'

get :index
assert_response_schema

ActiveModel::Serializer.config.schema_path = original_schema_path
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"properties": {
"name" : { "type" : "string" },
"description" : { "type" : "string" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"properties": {
"name" : { "type" : "string" },
"description" : { "type" : "string" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"properties": {
"name" : { "type" : "string" }
}
}
6 changes: 6 additions & 0 deletions test/support/schemas/custom/show.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"properties": {
"name" : { "type" : "string" },
"description" : { "type" : "string" }
}
}

0 comments on commit 58cf46a

Please sign in to comment.