Skip to content

Commit

Permalink
Refactor several tests with better RSpec practices
Browse files Browse the repository at this point in the history
  • Loading branch information
remi committed Jan 19, 2013
1 parent f6f1fe9 commit 875bd42
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 306 deletions.
19 changes: 18 additions & 1 deletion lib/her/api.rb
Expand Up @@ -11,6 +11,22 @@ def self.setup(attrs={}, &block)
@@default_api.setup(attrs, &block)
end

# Create a new API object. This is useful to create multiple APIs and use them with the `uses_api` method.
# If your application uses only one API, you should use Her::API.setup to configure the default API
#
# @example Setting up a new API
# api = Her::API.new :url => "https://api.example" do |connection|
# connection.use Faraday::Request::UrlEncoded
# connection.use Her::Middleware::DefaultParseJSON
# end
#
# class User
# uses_api api
# end
def initialize(*args, &blk)
self.setup(*args, &blk)
end

# Setup the API connection.
#
# @param [Hash] attrs the Faraday options
Expand Down Expand Up @@ -49,13 +65,14 @@ def self.setup(attrs={}, &block)
# connection.use MyCustomParser
# connection.use Faraday::Adapter::NetHttp
# end
def setup(attrs={})
def setup(attrs={}, &blk)
attrs[:url] = attrs.delete(:base_uri) if attrs.include?(:base_uri) # Support legacy :base_uri option
@base_uri = attrs[:url]
@options = attrs
@connection = Faraday.new(@options) do |connection|
yield connection if block_given?
end
self
end

# Define a custom parsing procedure. The procedure is passed the response object and is
Expand Down
2 changes: 1 addition & 1 deletion lib/her/model/http.rb
Expand Up @@ -56,7 +56,7 @@ def get_raw(path, attrs={}, &block)
end

# Make a GET request and return a collection of resources
def get_collection(path, attrs={})
def get_collection(path=nil, attrs={})
path = "#{build_request_path(attrs)}/#{path}" if path.is_a?(Symbol)
get_raw(path, attrs) do |parsed_data|
new_collection(parsed_data)
Expand Down
153 changes: 77 additions & 76 deletions spec/api_spec.rb
Expand Up @@ -2,6 +2,8 @@
require File.join(File.dirname(__FILE__), "spec_helper.rb")

describe Her::API do
subject { Her::API.new }

context "initialization" do
describe ".setup" do
it "creates a default connection" do
Expand All @@ -11,119 +13,118 @@
end

describe "#setup" do
it "sets a base URI" do
@api = Her::API.new
@api.setup :url => "https://api.example.com"
@api.base_uri.should == "https://api.example.com"
context "when using :url option" do
before { subject.setup :url => "https://api.example.com" }
its(:base_uri) { should == "https://api.example.com" }
end

it "supports the base_uri legacy option" do
@api = Her::API.new
@api.setup :base_uri => "https://api.example.com"
@api.base_uri.should == "https://api.example.com"
context "when using the legacy :base_uri option" do
before { subject.setup :base_uri => "https://api.example.com" }
its(:base_uri) { should == "https://api.example.com" }
end

it "sets custom middleware with #use" do
class Foo; end;
class Bar; end;
context "when setting custom middleware" do
before do
class Foo; end;
class Bar; end;

@api = Her::API.new
@api.setup :url => "https://api.example.com" do |builder|
builder.use Foo
builder.use Bar
subject.setup :url => "https://api.example.com" do |connection|
connection.use Foo
connection.use Bar
end
end
@api.connection.builder.handlers.should == [Foo, Bar]

specify { subject.connection.builder.handlers.should == [Foo, Bar] }
end

it "takes custom options" do
@api = Her::API.new
@api.setup :foo => { :bar => "baz" }, :url => "https://api.example.com"
@api.options.should == { :foo => { :bar => "baz" }, :url => "https://api.example.com" }
context "when setting custom options" do
before { subject.setup :foo => { :bar => "baz" }, :url => "https://api.example.com" }
its(:options) { should == { :foo => { :bar => "baz" }, :url => "https://api.example.com" } }
end
end

describe "#request" do
it "makes HTTP requests" do
before do
class SimpleParser < Faraday::Response::Middleware
def on_complete(env)
env[:body] = { :data => env[:body] }
end
end
end

@api = Her::API.new
@api.setup :url => "https://api.example.com" do |builder|
builder.use SimpleParser
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/foo") { |env| [200, {}, "Foo it is"] }
context "making HTTP requests" do
let(:parsed_data) { subject.request(:_method => :get, :_path => "/foo") }
before do
subject.setup :url => "https://api.example.com" do |builder|
builder.use SimpleParser
builder.adapter(:test) { |stub| stub.get("/foo") { |env| [200, {}, "Foo, it is."] } }
end
end

parsed_data = @api.request(:_method => :get, :_path => "/foo")
parsed_data[:data] == "Foo, it is."
specify { parsed_data[:data].should == "Foo, it is." }
end

it "makes HTTP requests while specifying custom HTTP headers" do
class SimpleParser < Faraday::Response::Middleware
def on_complete(env)
env[:body] = { :data => env[:body] }
end
end
context "making HTTP requests while specifying custom HTTP headers" do
let(:parsed_data) { subject.request(:_method => :get, :_path => "/foo", :_headers => { "X-Page" => 2 }) }

@api = Her::API.new
@api.setup :url => "https://api.example.com" do |builder|
builder.use SimpleParser
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/foo") { |env| [200, {}, "Foo it is #{env[:request_headers]["X-Page"]}"] }
before do
subject.setup :url => "https://api.example.com" do |builder|
builder.use SimpleParser
builder.adapter(:test) { |stub| stub.get("/foo") { |env| [200, {}, "Foo, it is page #{env[:request_headers]["X-Page"]}."] } }
end
end

parsed_data = @api.request(:_method => :get, :_path => "/foo", :_headers => { "X-Page" => 2 })
parsed_data[:data] == "Foo, it is page 2."
specify { parsed_data[:data].should == "Foo, it is page 2." }
end

it "parses a request with the default parser" do
@api = Her::API.new
@api.setup :url => "https://api.example.com" do |builder|
builder.use Her::Middleware::FirstLevelParseJSON
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/users/1") { |env| [200, {}, MultiJson.dump({ :id => 1, :name => "George Michael Bluth", :errors => ["This is a single error"], :metadata => { :page => 1, :per_page => 10 } })] }
context "parsing a request with the default parser" do
let(:parsed_data) { subject.request(:_method => :get, :_path => "users/1") }
before do
subject.setup :url => "https://api.example.com" do |builder|
builder.use Her::Middleware::FirstLevelParseJSON
builder.adapter :test do |stub|
stub.get("/users/1") { |env| [200, {}, MultiJson.dump({ :id => 1, :name => "George Michael Bluth", :errors => ["This is a single error"], :metadata => { :page => 1, :per_page => 10 } })] }
end
end
end
parsed_data = @api.request(:_method => :get, :_path => "users/1")
parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
parsed_data[:errors].should == ["This is a single error"]
parsed_data[:metadata].should == { :page => 1, :per_page => 10 }

specify do
parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
parsed_data[:errors].should == ["This is a single error"]
parsed_data[:metadata].should == { :page => 1, :per_page => 10 }
end
end

it "parses a request with a custom parser" do
class CustomParser < Faraday::Response::Middleware
def on_complete(env)
json = MultiJson.load(env[:body], :symbolize_keys => true)
errors = json.delete(:errors) || []
metadata = json.delete(:metadata) || {}
env[:body] = {
:data => json,
:errors => errors,
:metadata => metadata,
}
context "parsing a request with a custom parser" do
let(:parsed_data) { subject.request(:_method => :get, :_path => "users/1") }
before do
class CustomParser < Faraday::Response::Middleware
def on_complete(env)
json = MultiJson.load(env[:body], :symbolize_keys => true)
errors = json.delete(:errors) || []
metadata = json.delete(:metadata) || {}
env[:body] = {
:data => json,
:errors => errors,
:metadata => metadata,
}
end
end
end

@api = Her::API.new
@api.setup :url => "https://api.example.com" do |builder|
builder.use CustomParser
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/users/1") { |env| [200, {}, MultiJson.dump(:id => 1, :name => "George Michael Bluth")] }
subject.setup :url => "https://api.example.com" do |builder|
builder.use CustomParser
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/users/1") { |env| [200, {}, MultiJson.dump(:id => 1, :name => "George Michael Bluth")] }
end
end
end
parsed_data = @api.request(:_method => :get, :_path => "users/1")
parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
parsed_data[:errors].should == []
parsed_data[:metadata].should == {}

specify do
parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
parsed_data[:errors].should == []
parsed_data[:metadata].should == {}
end
end
end
end
Expand Down
21 changes: 10 additions & 11 deletions spec/collection_spec.rb
Expand Up @@ -2,26 +2,25 @@

describe Her::Collection do

let(:items) { [1,2,3,4] }
let(:metadata) { {:name => 'Testname'} }
let(:errors) { {:name => ['not_present']} }
let(:items) { [1, 2, 3, 4] }
let(:metadata) { { :name => 'Testname' } }
let(:errors) { { :name => ['not_present'] } }

describe "#new" do
context "without parameters" do

subject { Her::Collection.new }

it { should eq([])}
its(:metadata) { should eq({})}
its(:errors) { should eq({})}
it { should eq([]) }
its(:metadata) { should eq({}) }
its(:errors) { should eq({}) }
end

context "with parameters" do
subject { Her::Collection.new(items, metadata, errors)}
subject { Her::Collection.new(items, metadata, errors) }

it { should eq([1,2,3,4])}
its(:metadata) { should eq({:name => 'Testname'})}
its(:errors) { should eq({:name => ['not_present']})}
it { should eq([1,2,3,4]) }
its(:metadata) { should eq({ :name => 'Testname' }) }
its(:errors) { should eq({ :name => ['not_present'] }) }
end
end
end

0 comments on commit 875bd42

Please sign in to comment.