class Strelka::Testing::HaveJSONBodyMatcher
RSpec matcher for matching Strelka::HTTPResponse
body
Expect that the response consists of JSON of some sort:
expect( response ).to have_json_body
Expect that it's a JSON body that deserializes as an Object:
expect( response ).to have_json_body( Object ) # -or- expect( response ).to have_json_body( Hash )
Expect that it's a JSON body that deserializes as an Array:
expect( response ).to have_json_body( Array )
Expect that it's a JSON body that deserializes as an Object that has expected keys:
expect( response ).to have_json_body( Object ). that_includes( :id, :first_name, :last_name )
Expect that it's a JSON body that deserializes as an Object that has expected keys and values:
expect( response ).to have_json_body( Object ). that_includes( id: 118, first_name: 'Princess', last_name: 'Buttercup' )
Expect that it's a JSON body that has other expected stuff:
expect( response ).to have_json_body( Object ). that_includes( last_name: a_string_matching(/humperdink/i), profile: a_hash_including(:age, :eyecolor, :tracking_ability) )
Expect a JSON Array with objects that all match the criteria:
expect( response ).to have_json_body( Array ). of_lenth( 20 ). and( all( be_an(Integer) ) )
Attributes
Public Class Methods
Create a new matcher that expects a response with a JSON body. If expected_type
is not specified, any JSON body will be sufficient for a match.
# File lib/strelka/testing.rb, line 248 def initialize( expected_type=nil ) @expected_type = expected_type @additional_expectations = [] @response = nil @failure_description = nil end
Public Instance Methods
Add the specified matchers
as expectations of the Hash or Array that's parsed from the JSON body.
# File lib/strelka/testing.rb, line 337 def and( *matchers ) @additional_expectations.concat( matchers ) return self end
RSpec matcher API – return a message describing an expectation failure.
# File lib/strelka/testing.rb, line 276 def failure_message return "\n---\n%s\n---\n\nReason: %s\n" % [ self.pretty_print_response, self.failure_description ] end
RSpec matcher API – return a message describing an expectation being met when the matcher was used in a negated context.
# File lib/strelka/testing.rb, line 286 def failure_message_when_negated msg = "expected response not to have a %s" % [ self.describe_type_expectation ] msg << " and " << self.describe_additional_expectations.join( ', ' ) unless self.additional_expectations.emtpy? msg << ", but it did." return "\n---\n%s\n---\n\nReason: %s\n" % [ self.pretty_print_response, msg ] end
RSpec matcher API – returns true
if all expectations of the specified response
are met.
# File lib/strelka/testing.rb, line 264 def matches?( response ) @response = response return self.correct_content_type? && self.correct_json_type? && self.matches_additional_expectations? rescue Yajl::ParseError => err return self.fail_with "Response has invalid JSON body: %s" % [ err.message ] end
Add an additional expectation that the JSON body contain the specified number
of members.
# File lib/strelka/testing.rb, line 328 def of_length( number ) @additional_expectations << have_attributes( length: number ) return self end
Return the response's body parsed as JSON.
# File lib/strelka/testing.rb, line 300 def parsed_response_body return @parsed_response_body ||= Yajl::Parser.parse( self.response.body, check_utf8: true, symbolize_keys: true ) end
Add an additional expectation that the JSON body does not contain the specified members
.
# File lib/strelka/testing.rb, line 320 def that_excludes( *memberset ) @additional_expectations << exclude( *memberset ) return self end
Add an additional expectation that the JSON body contains the specified members
.
# File lib/strelka/testing.rb, line 311 def that_includes( *memberset ) @additional_expectations << include( *memberset ) return self end
Protected Instance Methods
Returns true
if the response has a JSON content-type header.
# File lib/strelka/testing.rb, line 362 def correct_content_type? content_type = self.response.headers[:content_type] or return self.fail_with "response doesn't have a Content-type header" return fail_with "response's Content-type is %p" % [ content_type ] unless content_type.start_with?( 'application/json' ) || content_type.match?( %r|\Aapplication/(vnd\.)?\w+\+json\b| ) return true end
Check that the JSON body of the response has the correct type, if a type was specified.
# File lib/strelka/testing.rb, line 391 def correct_json_type? return self.parsed_response_body unless self.expected_type if self.expected_type == Array return self.fail_with( "response body isn't a JSON Array" ) unless self.parsed_response_body.is_a?( Array ) elsif self.expected_type == Object || self.expected_type == Hash return self.fail_with( "response body isn't a JSON Object" ) unless self.parsed_response_body.is_a?( Hash ) else warn "A valid JSON response can't be a %p!" % [ self.expected_type ] end return true end
Return an Array of descriptions of the members that were expected to be included in the response body, if any were specified. If none were specified, returns an empty Array.
# File lib/strelka/testing.rb, line 411 def describe_additional_expectations return self.additional_expectations.map( &:description ) end
Return an Array of text describing the expectation that the body be an Object or an Array, if a type was expected. If no type was expected, returns an empty Array.
# File lib/strelka/testing.rb, line 377 def describe_type_expectation return case self.expected_type when Object, Hash "a JSON Object/Hash body" when Array "a JSON Array body" else "a JSON body" end end
Return false
after setting the failure message to message
.
# File lib/strelka/testing.rb, line 354 def fail_with( message ) @failure_description = message self.log.error "Failing with: %s" % [ message ] return false end
Check that any additional matchers registered via the `.and` mutator also match the parsed response body.
# File lib/strelka/testing.rb, line 418 def matches_additional_expectations? return self.additional_expectations.all? do |matcher| matcher.matches?( self.parsed_response_body ) or fail_with( matcher.failure_message ) end end
Return a String that contains a pretty-printed version of the response object.
# File lib/strelka/testing.rb, line 348 def pretty_print_response return self.response.to_s end