aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/test
diff options
context:
space:
mode:
Diffstat (limited to 'activeresource/test')
-rw-r--r--activeresource/test/base/load_test.rb17
-rw-r--r--activeresource/test/base_errors_test.rb77
-rw-r--r--activeresource/test/base_test.rb147
-rw-r--r--activeresource/test/connection_test.rb42
-rw-r--r--activeresource/test/fixtures/proxy.rb4
5 files changed, 265 insertions, 22 deletions
diff --git a/activeresource/test/base/load_test.rb b/activeresource/test/base/load_test.rb
index 035bd965c2..5f5a580445 100644
--- a/activeresource/test/base/load_test.rb
+++ b/activeresource/test/base/load_test.rb
@@ -51,7 +51,9 @@ class BaseLoadTest < Test::Unit::TestCase
:id => 1, :state => { :id => 1, :name => 'Oregon',
:notable_rivers => [
{ :id => 1, :name => 'Willamette' },
- { :id => 2, :name => 'Columbia', :rafted_by => @matz }] }}}
+ { :id => 2, :name => 'Columbia', :rafted_by => @matz }],
+ :postal_codes => [97018,1234567890],
+ :places => ["Columbia City", "Unknown"]}}}
@person = Person.new
end
@@ -127,6 +129,19 @@ class BaseLoadTest < Test::Unit::TestCase
assert_kind_of Person::Street::State::NotableRiver, rivers.first
assert_equal @deep[:street][:state][:notable_rivers].first[:id], rivers.first.id
assert_equal @matz[:id], rivers.last.rafted_by.id
+
+ postal_codes = state.postal_codes
+ assert_kind_of Array, postal_codes
+ assert_equal 2, postal_codes.size
+ assert_kind_of Fixnum, postal_codes.first
+ assert_equal @deep[:street][:state][:postal_codes].first, postal_codes.first
+ assert_kind_of Bignum, postal_codes.last
+ assert_equal @deep[:street][:state][:postal_codes].last, postal_codes.last
+
+ places = state.places
+ assert_kind_of Array, places
+ assert_kind_of String, places.first
+ assert_equal @deep[:street][:state][:places].first, places.first
end
def test_nested_collections_within_the_same_namespace
diff --git a/activeresource/test/base_errors_test.rb b/activeresource/test/base_errors_test.rb
index 28813821df..eca00e9ca8 100644
--- a/activeresource/test/base_errors_test.rb
+++ b/activeresource/test/base_errors_test.rb
@@ -4,45 +4,80 @@ require "fixtures/person"
class BaseErrorsTest < Test::Unit::TestCase
def setup
ActiveResource::HttpMock.respond_to do |mock|
- mock.post "/people.xml", {}, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><errors><error>Age can't be blank</error><error>Name can't be blank</error><error>Name must start with a letter</error><error>Person quota full for today.</error></errors>", 422
+ mock.post "/people.xml", {}, %q(<?xml version="1.0" encoding="UTF-8"?><errors><error>Age can't be blank</error><error>Name can't be blank</error><error>Name must start with a letter</error><error>Person quota full for today.</error></errors>), 422, {'Content-Type' => 'application/xml'}
+ mock.post "/people.json", {}, %q({"errors":["Age can't be blank","Name can't be blank","Name must start with a letter","Person quota full for today."]}), 422, {'Content-Type' => 'application/json'}
end
- @person = Person.new(:name => '', :age => '')
- assert_equal @person.save, false
end
def test_should_mark_as_invalid
- assert !@person.valid?
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ assert !@person.valid?
+ end
+ end
end
def test_should_parse_xml_errors
- assert_kind_of ActiveResource::Errors, @person.errors
- assert_equal 4, @person.errors.size
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ assert_kind_of ActiveResource::Errors, @person.errors
+ assert_equal 4, @person.errors.size
+ end
+ end
end
def test_should_parse_errors_to_individual_attributes
- assert @person.errors[:name].any?
- assert_equal ["can't be blank"], @person.errors[:age]
- assert_equal ["can't be blank", "must start with a letter"], @person.errors[:name]
- assert_equal ["Person quota full for today."], @person.errors[:base]
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ assert @person.errors[:name].any?
+ assert_equal ["can't be blank"], @person.errors[:age]
+ assert_equal ["can't be blank", "must start with a letter"], @person.errors[:name]
+ assert_equal ["Person quota full for today."], @person.errors[:base]
+ end
+ end
end
def test_should_iterate_over_errors
- errors = []
- @person.errors.each { |attribute, message| errors << [attribute.to_s, message] }
- assert errors.include?(["name", "can't be blank"])
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ errors = []
+ @person.errors.each { |attribute, message| errors << [attribute, message] }
+ assert errors.include?([:name, "can't be blank"])
+ end
+ end
end
def test_should_iterate_over_full_errors
- errors = []
- @person.errors.to_a.each { |message| errors << message }
- assert errors.include?("Name can't be blank")
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ errors = []
+ @person.errors.to_a.each { |message| errors << message }
+ assert errors.include?("Name can't be blank")
+ end
+ end
end
def test_should_format_full_errors
- full = @person.errors.full_messages
- assert full.include?("Age can't be blank")
- assert full.include?("Name can't be blank")
- assert full.include?("Name must start with a letter")
- assert full.include?("Person quota full for today.")
+ [ :json, :xml ].each do |format|
+ invalid_user_using_format(format) do
+ full = @person.errors.full_messages
+ assert full.include?("Age can't be blank")
+ assert full.include?("Name can't be blank")
+ assert full.include?("Name must start with a letter")
+ assert full.include?("Person quota full for today.")
+ end
+ end
+ end
+
+ private
+ def invalid_user_using_format(mime_type_reference)
+ previous_format = Person.format
+ Person.format = mime_type_reference
+ @person = Person.new(:name => '', :age => '')
+ assert_equal false, @person.save
+
+ yield
+ ensure
+ Person.format = previous_format
end
end
diff --git a/activeresource/test/base_test.rb b/activeresource/test/base_test.rb
index 82d3b2ae96..9c236bc893 100644
--- a/activeresource/test/base_test.rb
+++ b/activeresource/test/base_test.rb
@@ -3,6 +3,7 @@ require "fixtures/person"
require "fixtures/customer"
require "fixtures/street_address"
require "fixtures/beast"
+require "fixtures/proxy"
require 'active_support/core_ext/hash/conversions'
class BaseTest < Test::Unit::TestCase
@@ -125,6 +126,28 @@ class BaseTest < Test::Unit::TestCase
assert_nil actor.site
end
+ def test_proxy_accessor_accepts_uri_or_string_argument
+ proxy = URI.parse('http://localhost')
+
+ assert_nothing_raised { Person.proxy = 'http://localhost' }
+ assert_equal proxy, Person.proxy
+
+ assert_nothing_raised { Person.proxy = proxy }
+ assert_equal proxy, Person.proxy
+ end
+
+ def test_should_use_proxy_prefix_and_credentials
+ assert_equal 'http://user:password@proxy.local:3000', ProxyResource.proxy.to_s
+ end
+
+ def test_proxy_variable_can_be_reset
+ actor = Class.new(ActiveResource::Base)
+ assert_nil actor.site
+ actor.proxy = 'http://localhost:31337'
+ actor.proxy = nil
+ assert_nil actor.site
+ end
+
def test_should_accept_setting_user
Forum.user = 'david'
assert_equal('david', Forum.user)
@@ -143,6 +166,13 @@ class BaseTest < Test::Unit::TestCase
assert_equal(5, Forum.connection.timeout)
end
+ def test_should_accept_setting_ssl_options
+ expected = {:verify => 1}
+ Forum.ssl_options= expected
+ assert_equal(expected, Forum.ssl_options)
+ assert_equal(expected, Forum.connection.ssl_options)
+ end
+
def test_user_variable_can_be_reset
actor = Class.new(ActiveResource::Base)
actor.site = 'http://cinema'
@@ -173,6 +203,16 @@ class BaseTest < Test::Unit::TestCase
assert_nil actor.connection.timeout
end
+ def test_ssl_options_hash_can_be_reset
+ actor = Class.new(ActiveResource::Base)
+ actor.site = 'https://cinema'
+ assert_nil actor.ssl_options
+ actor.ssl_options = {:foo => 5}
+ actor.ssl_options = nil
+ assert_nil actor.ssl_options
+ assert_nil actor.connection.ssl_options
+ end
+
def test_credentials_from_site_are_decoded
actor = Class.new(ActiveResource::Base)
actor.site = 'http://my%40email.com:%31%32%33@cinema'
@@ -221,6 +261,47 @@ class BaseTest < Test::Unit::TestCase
assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
end
+ def test_proxy_reader_uses_superclass_site_until_written
+ # Superclass is Object so returns nil.
+ assert_nil ActiveResource::Base.proxy
+ assert_nil Class.new(ActiveResource::Base).proxy
+
+ # Subclass uses superclass proxy.
+ actor = Class.new(Person)
+ assert_equal Person.proxy, actor.proxy
+
+ # Subclass returns frozen superclass copy.
+ assert !Person.proxy.frozen?
+ assert actor.proxy.frozen?
+
+ # Changing subclass proxy doesn't change superclass site.
+ actor.proxy = 'http://localhost:31337'
+ assert_not_equal Person.proxy, actor.proxy
+
+ # Changed subclass proxy is not frozen.
+ assert !actor.proxy.frozen?
+
+ # Changing superclass proxy doesn't overwrite subclass site.
+ Person.proxy = 'http://somewhere.else'
+ assert_not_equal Person.proxy, actor.proxy
+
+ # Changing superclass proxy after subclassing changes subclass site.
+ jester = Class.new(actor)
+ actor.proxy = 'http://nomad'
+ assert_equal actor.proxy, jester.proxy
+ assert jester.proxy.frozen?
+
+ # Subclasses are always equal to superclass proxy when not overridden
+ fruit = Class.new(ActiveResource::Base)
+ apple = Class.new(fruit)
+
+ fruit.proxy = 'http://market'
+ assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
+
+ fruit.proxy = 'http://supermarket'
+ assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
+ end
+
def test_user_reader_uses_superclass_user_until_written
# Superclass is Object so returns nil.
assert_nil ActiveResource::Base.user
@@ -331,6 +412,40 @@ class BaseTest < Test::Unit::TestCase
assert_equal fruit.timeout, apple.timeout, 'subclass did not adopt changes from parent class'
end
+ def test_ssl_options_reader_uses_superclass_ssl_options_until_written
+ # Superclass is Object so returns nil.
+ assert_nil ActiveResource::Base.ssl_options
+ assert_nil Class.new(ActiveResource::Base).ssl_options
+ Person.ssl_options = {:foo => 'bar'}
+
+ # Subclass uses superclass ssl_options.
+ actor = Class.new(Person)
+ assert_equal Person.ssl_options, actor.ssl_options
+
+ # Changing subclass ssl_options doesn't change superclass ssl_options.
+ actor.ssl_options = {:baz => ''}
+ assert_not_equal Person.ssl_options, actor.ssl_options
+
+ # Changing superclass ssl_options doesn't overwrite subclass ssl_options.
+ Person.ssl_options = {:color => 'blue'}
+ assert_not_equal Person.ssl_options, actor.ssl_options
+
+ # Changing superclass ssl_options after subclassing changes subclass ssl_options.
+ jester = Class.new(actor)
+ actor.ssl_options = {:color => 'red'}
+ assert_equal actor.ssl_options, jester.ssl_options
+
+ # Subclasses are always equal to superclass ssl_options when not overridden.
+ fruit = Class.new(ActiveResource::Base)
+ apple = Class.new(fruit)
+
+ fruit.ssl_options = {:alpha => 'betas'}
+ assert_equal fruit.ssl_options, apple.ssl_options, 'subclass did not adopt changes from parent class'
+
+ fruit.ssl_options = {:omega => 'moos'}
+ assert_equal fruit.ssl_options, apple.ssl_options, 'subclass did not adopt changes from parent class'
+ end
+
def test_updating_baseclass_site_object_wipes_descendent_cached_connection_objects
# Subclasses are always equal to superclass site when not overridden
fruit = Class.new(ActiveResource::Base)
@@ -784,6 +899,14 @@ class BaseTest < Test::Unit::TestCase
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end
+ def test_destroy_with_410_gone
+ assert Person.find(1).destroy
+ ActiveResource::HttpMock.respond_to do |mock|
+ mock.get "/people/1.xml", {}, nil, 410
+ end
+ assert_raise(ActiveResource::ResourceGone) { Person.find(1).destroy }
+ end
+
def test_delete
assert Person.delete(1)
ActiveResource::HttpMock.respond_to do |mock|
@@ -799,6 +922,14 @@ class BaseTest < Test::Unit::TestCase
end
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end
+
+ def test_delete_with_410_gone
+ assert Person.delete(1)
+ ActiveResource::HttpMock.respond_to do |mock|
+ mock.get "/people/1.xml", {}, nil, 410
+ end
+ assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
+ end
def test_exists
# Class method.
@@ -851,6 +982,22 @@ class BaseTest < Test::Unit::TestCase
end
end
+ def test_exists_without_http_mock
+ http = Net::HTTP.new(Person.site.host, Person.site.port)
+ ActiveResource::Connection.any_instance.expects(:http).returns(http)
+ http.expects(:request).returns(ActiveResource::Response.new(""))
+
+ assert Person.exists?('not-mocked')
+ end
+
+ def test_exists_with_410_gone
+ ActiveResource::HttpMock.respond_to do |mock|
+ mock.head "/people/1.xml", {}, nil, 410
+ end
+
+ assert !Person.exists?(1)
+ end
+
def test_to_xml
matz = Person.find(1)
xml = matz.encode
diff --git a/activeresource/test/connection_test.rb b/activeresource/test/connection_test.rb
index 831fbc4003..d7466c65b4 100644
--- a/activeresource/test/connection_test.rb
+++ b/activeresource/test/connection_test.rb
@@ -56,6 +56,9 @@ class ConnectionTest < Test::Unit::TestCase
# 409 is an optimistic locking error
assert_response_raises ActiveResource::ResourceConflict, 409
+ # 410 is a removed resource
+ assert_response_raises ActiveResource::ResourceGone, 410
+
# 422 is a validation error
assert_response_raises ActiveResource::ResourceInvalid, 422
@@ -101,6 +104,16 @@ class ConnectionTest < Test::Unit::TestCase
assert_equal site, @conn.site
end
+ def test_proxy_accessor_accepts_uri_or_string_argument
+ proxy = URI.parse("http://proxy_user:proxy_password@proxy.local:4242")
+
+ assert_nothing_raised { @conn.proxy = "http://proxy_user:proxy_password@proxy.local:4242" }
+ assert_equal proxy, @conn.proxy
+
+ assert_nothing_raised { @conn.proxy = proxy }
+ assert_equal proxy, @conn.proxy
+ end
+
def test_timeout_accessor
@conn.timeout = 5
assert_equal 5, @conn.timeout
@@ -175,6 +188,17 @@ class ConnectionTest < Test::Unit::TestCase
assert_raise(ActiveResource::TimeoutError) { @conn.get('/people_timeout.xml') }
end
+ def test_setting_timeout
+ http = Net::HTTP.new('')
+
+ [10, 20].each do |timeout|
+ @conn.timeout = timeout
+ @conn.send(:configure_http, http)
+ assert_equal timeout, http.open_timeout
+ assert_equal timeout, http.read_timeout
+ end
+ end
+
def test_accept_http_header
@http = mock('new Net::HTTP')
@conn.expects(:http).returns(@http)
@@ -183,6 +207,24 @@ class ConnectionTest < Test::Unit::TestCase
assert_nothing_raised(Mocha::ExpectationError) { @conn.get(path, {'Accept' => 'application/xhtml+xml'}) }
end
+ def test_ssl_options_get_applied_to_http
+ http = Net::HTTP.new('')
+ @conn.site="https://secure"
+ @conn.ssl_options={:verify_mode => OpenSSL::SSL::VERIFY_PEER}
+ @conn.timeout = 10 # prevent warning about uninitialized.
+ @conn.send(:configure_http, http)
+
+ assert http.use_ssl?
+ assert_equal http.verify_mode, OpenSSL::SSL::VERIFY_PEER
+ end
+
+ def test_ssl_error
+ http = Net::HTTP.new('')
+ @conn.expects(:http).returns(http)
+ http.expects(:get).raises(OpenSSL::SSL::SSLError, 'Expired certificate')
+ assert_raise(ActiveResource::SSLError) { @conn.get('/people/1.xml') }
+ end
+
protected
def assert_response_raises(klass, code)
assert_raise(klass, "Expected response code #{code} to raise #{klass}") do
diff --git a/activeresource/test/fixtures/proxy.rb b/activeresource/test/fixtures/proxy.rb
new file mode 100644
index 0000000000..bb8e015df0
--- /dev/null
+++ b/activeresource/test/fixtures/proxy.rb
@@ -0,0 +1,4 @@
+class ProxyResource < ActiveResource::Base
+ self.site = "http://localhost"
+ self.proxy = "http://user:password@proxy.local:3000"
+end \ No newline at end of file