Skip to content

Commit

Permalink
Make sure all responses from the API are hashes or arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
remi committed Apr 2, 2013
1 parent ffa39ce commit 30584da
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 13 deletions.
1 change: 1 addition & 0 deletions lib/her/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ module Her
module Errors
class PathError < StandardError; end;
class AssociationUnknownError < StandardError; end;
class ParseError < StandardError; end;
end
end
2 changes: 2 additions & 0 deletions lib/her/middleware/first_level_parse_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class FirstLevelParseJSON < Faraday::Response::Middleware
# @return [Mixed] the parsed response
def parse(body)
json = MultiJson.load(body, :symbolize_keys => true)
raise Her::Errors::ParseError, "Response from the API must behave like a Hash or an Array (last was: #{json.inspect})" unless json.is_a?(Hash) or json.is_a?(Array)

errors = json.delete(:errors) || {}
metadata = json.delete(:metadata) || []
{
Expand Down
2 changes: 2 additions & 0 deletions lib/her/middleware/second_level_parse_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class SecondLevelParseJSON < Faraday::Response::Middleware
# @return [Mixed] the parsed response
def parse(body)
json = MultiJson.load(body, :symbolize_keys => true)
raise Her::Errors::ParseError, "Response from the API must behave like a Hash or an Array (last was: #{json.inspect})" unless json.is_a?(Hash) or json.is_a?(Array)

{
:data => json[:data],
:errors => json[:errors],
Expand Down
5 changes: 5 additions & 0 deletions spec/middleware/first_level_parse_json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
let(:body_without_errors) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"metadata\": 3}" }
let(:body_with_errors) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"errors\": { \"name\": [ \"not_valid\", \"should_be_present\" ] }, \"metadata\": 3}" }
let(:body_with_malformed_json) { "wut." }
let(:body_with_invalid_json) { "true" }

it "parses body as json" do
subject.parse(body_without_errors).tap do |json|
Expand Down Expand Up @@ -35,6 +36,10 @@
expect { subject.parse(body_with_malformed_json) }.to raise_error(MultiJson::LoadError)
end

it 'ensures that invalid JSON throws an exception' do
expect { subject.parse(body_with_invalid_json) }.to raise_error(Her::Errors::ParseError, "Response from the API must behave like a Hash or an Array (last was: true)")
end

context 'with status code 204' do
it 'returns an empty body' do
env = { :status => 204 }
Expand Down
36 changes: 23 additions & 13 deletions spec/middleware/second_level_parse_json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,33 @@

describe Her::Middleware::SecondLevelParseJSON do
subject { described_class.new }
let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }

it "parses body as json" do
subject.parse(body).tap do |json|
json[:data].should == 1
json[:errors].should == 2
json[:metadata].should == 3
context "with valid JSON body" do
let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }
it "parses body as json" do
subject.parse(body).tap do |json|
json[:data].should == 1
json[:errors].should == 2
json[:metadata].should == 3
end
end

it "parses :body key as json in the env hash" do
env = { :body => body }
subject.on_complete(env)
env[:body].tap do |json|
json[:data].should == 1
json[:errors].should == 2
json[:metadata].should == 3
end
end
end

it "parses :body key as json in the env hash" do
env = { :body => body }
subject.on_complete(env)
env[:body].tap do |json|
json[:data].should == 1
json[:errors].should == 2
json[:metadata].should == 3
context "with invalid JSON body" do
let(:body) { '"foo"' }
it 'ensures that invalid JSON throws an exception' do
expect { subject.parse(body) }.to raise_error(Her::Errors::ParseError, "Response from the API must behave like a Hash or an Array (last was: \"foo\")")
end
end

end

0 comments on commit 30584da

Please sign in to comment.