Skip to content

Instantly share code, notes, and snippets.

@flyingzumwalt
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flyingzumwalt/4e101eb91b6d2551c182 to your computer and use it in GitHub Desktop.
Save flyingzumwalt/4e101eb91b6d2551c182 to your computer and use it in GitHub Desktop.
Spec Matchers for API Responses
# spec/support/matchers/api_responses.rb
#
# RSpec matchers for API default JSON responses.
# Creates a matcher like respond_forbidden or respond_not_found corresponding to each of the Api::V1.default_responses
# Accepts optional overrides to the expected response body.
# @example Override the description expected in the JSON body of a :forbidden response
# expect(response).to respond_forbidden(description:"You can't create for that identity")
::Api::V1.default_responses.each_pair do |response_type,default_response_body|
RSpec::Matchers.define "respond_#{response_type.to_s}".to_sym do |expectation_options|
match do |response|
@expected_response_body = expectation_options.nil? ? default_response_body : default_response_body.merge(expectation_options)
json = JSON.parse(response.body)
expect(response.code).to eq(@expected_response_body[:code].to_s)
@expected_response_body.each_pair do |key,value|
expect(json[key.to_s]).to eq(value)
end
end
failure_message do |actual|
"expected #{default_response_body[:code]} status code. Got #{actual.code} status code.\nexpected an Authentication Required response like this:\n #{@expected_response_body.to_json} \ngot\n #{actual.body}\nTo override expectations about the response body, provide a Hash of overrides in your call to :respond_#{response_type} "
end
end
end
module Api
module V1
def self.generate_response_body(response_type,options={})
self.default_responses[response_type].merge(options)
end
def self.default_responses
{
success: {
code: 200,
message: "Request Succeeded",
description: I18n.t('success.default')
},
deleted: {
code: 200,
message: I18n.t('deleted.default')
},
accepted: {
code: 202,
message: "Accepted",
description: I18n.t('accepted.default')
},
bad_request: {
code: 400,
message: "Bad Request",
description: I18n.t('bad_request.default')
},
unauthorized: {
code: 401,
message: "Authentication Required",
description: I18n.t('unauthorized.default')
},
forbidden: {
code: 403,
message: "Not Authorized",
description: I18n.t('unauthorized.default')
},
not_found: {
code: 404,
message: "Resource not found",
description: I18n.t('not_found.default')
},
unprocessable_entity: {
code: 422,
message: "Unprocessable Entity",
description: I18n.t('unprocessable_entity.default'),
errors: []
}
}
end
end
end
describe "when not signed in" do
describe "index" do
it "should not be successful" do
get :index, :exhibit_id=>@exhibit.id, :q=>'bazaar', :pool_id=>@pool
expect(response).to respond_unauthorized
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment