diff options
Diffstat (limited to 'activeresource/test')
13 files changed, 522 insertions, 125 deletions
diff --git a/activeresource/test/base_errors_test.rb b/activeresource/test/base_errors_test.rb deleted file mode 100644 index 28813821df..0000000000 --- a/activeresource/test/base_errors_test.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'abstract_unit' -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 - end - @person = Person.new(:name => '', :age => '') - assert_equal @person.save, false - end - - def test_should_mark_as_invalid - assert !@person.valid? - end - - def test_should_parse_xml_errors - assert_kind_of ActiveResource::Errors, @person.errors - assert_equal 4, @person.errors.size - 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] - 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"]) - 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") - 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.") - end -end diff --git a/activeresource/test/authorization_test.rb b/activeresource/test/cases/authorization_test.rb index ca25f437e3..ca25f437e3 100644 --- a/activeresource/test/authorization_test.rb +++ b/activeresource/test/cases/authorization_test.rb diff --git a/activeresource/test/base/custom_methods_test.rb b/activeresource/test/cases/base/custom_methods_test.rb index 2d81549a65..2d81549a65 100644 --- a/activeresource/test/base/custom_methods_test.rb +++ b/activeresource/test/cases/base/custom_methods_test.rb diff --git a/activeresource/test/base/equality_test.rb b/activeresource/test/cases/base/equality_test.rb index 84f1a7b998..84f1a7b998 100644 --- a/activeresource/test/base/equality_test.rb +++ b/activeresource/test/cases/base/equality_test.rb diff --git a/activeresource/test/base/load_test.rb b/activeresource/test/cases/base/load_test.rb index 035bd965c2..1952f5b5f0 100644 --- a/activeresource/test/base/load_test.rb +++ b/activeresource/test/cases/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 Numeric, 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/cases/base_errors_test.rb b/activeresource/test/cases/base_errors_test.rb new file mode 100644 index 0000000000..eca00e9ca8 --- /dev/null +++ b/activeresource/test/cases/base_errors_test.rb @@ -0,0 +1,83 @@ +require 'abstract_unit' +require "fixtures/person" + +class BaseErrorsTest < Test::Unit::TestCase + def setup + ActiveResource::HttpMock.respond_to do |mock| + 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 + end + + def test_should_mark_as_invalid + [ :json, :xml ].each do |format| + invalid_user_using_format(format) do + assert !@person.valid? + end + end + end + + def test_should_parse_xml_errors + [ :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 + [ :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 + [ :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 + [ :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 + [ :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/cases/base_test.rb index e68d562d97..8c0217aad6 100644 --- a/activeresource/test/base_test.rb +++ b/activeresource/test/cases/base_test.rb @@ -166,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' @@ -196,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' @@ -395,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) @@ -586,13 +637,6 @@ class BaseTest < Test::Unit::TestCase assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters) end - def test_find_by_id - matz = Person.find(1) - assert_kind_of Person, matz - assert_equal "Matz", matz.name - assert matz.name? - end - def test_respond_to matz = Person.find(1) assert matz.respond_to?(:name) @@ -601,32 +645,6 @@ class BaseTest < Test::Unit::TestCase assert !matz.respond_to?(:super_scalable_stuff) end - def test_find_by_id_with_custom_prefix - addy = StreetAddress.find(1, :params => { :person_id => 1 }) - assert_kind_of StreetAddress, addy - assert_equal '12345 Street', addy.street - end - - def test_find_all - all = Person.find(:all) - assert_equal 2, all.size - assert_kind_of Person, all.first - assert_equal "Matz", all.first.name - assert_equal "David", all.last.name - end - - def test_find_first - matz = Person.find(:first) - assert_kind_of Person, matz - assert_equal "Matz", matz.name - end - - def test_find_last - david = Person.find(:last) - assert_kind_of Person, david - assert_equal 'David', david.name - end - def test_custom_header Person.headers['key'] = 'value' assert_raise(ActiveResource::ResourceNotFound) { Person.find(4) } @@ -634,52 +652,15 @@ class BaseTest < Test::Unit::TestCase Person.headers.delete('key') end - def test_find_by_id_not_found - assert_raise(ActiveResource::ResourceNotFound) { Person.find(99) } - assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1) } - end - - def test_find_all_by_from - ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david } - - people = Person.find(:all, :from => "/companies/1/people.xml") - assert_equal 1, people.size - assert_equal "David", people.first.name - end - - def test_find_all_by_from_with_options - ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david } - - people = Person.find(:all, :from => "/companies/1/people.xml") - assert_equal 1, people.size - assert_equal "David", people.first.name - end - - def test_find_all_by_symbol_from - ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, @people_david } - - people = Person.find(:all, :from => :managers) - assert_equal 1, people.size - assert_equal "David", people.first.name - end - - def test_find_single_by_from - ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david } - - david = Person.find(:one, :from => "/companies/1/manager.xml") - assert_equal "David", david.name - end - - def test_find_single_by_symbol_from - ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david } - - david = Person.find(:one, :from => :leader) - assert_equal "David", david.name + def test_save + rick = Person.new + assert rick.save + assert_equal '5', rick.id end - def test_save + def test_save! rick = Person.new - assert_equal true, rick.save + assert rick.save! assert_equal '5', rick.id end @@ -848,6 +829,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| @@ -863,6 +852,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. @@ -915,6 +912,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/cases/finder_test.rb b/activeresource/test/cases/finder_test.rb new file mode 100644 index 0000000000..535b6f4198 --- /dev/null +++ b/activeresource/test/cases/finder_test.rb @@ -0,0 +1,233 @@ +require 'abstract_unit' +require "fixtures/person" +require "fixtures/customer" +require "fixtures/street_address" +require "fixtures/beast" +require "fixtures/proxy" +require 'active_support/core_ext/hash/conversions' + +class FinderTest < Test::Unit::TestCase + def setup + # TODO: refactor/DRY this setup - it's a copy of the BaseTest setup. + # We can probably put this into abstract_unit + @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person') + @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person') + @greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person') + @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address') + @default_request_headers = { 'Content-Type' => 'application/xml' } + @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person") + @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people') + @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people') + @addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses') + + # - deep nested resource - + # - Luis (Customer) + # - JK (Customer::Friend) + # - Mateo (Customer::Friend::Brother) + # - Edith (Customer::Friend::Brother::Child) + # - Martha (Customer::Friend::Brother::Child) + # - Felipe (Customer::Friend::Brother) + # - Bryan (Customer::Friend::Brother::Child) + # - Luke (Customer::Friend::Brother::Child) + # - Eduardo (Customer::Friend) + # - Sebas (Customer::Friend::Brother) + # - Andres (Customer::Friend::Brother::Child) + # - Jorge (Customer::Friend::Brother::Child) + # - Elsa (Customer::Friend::Brother) + # - Natacha (Customer::Friend::Brother::Child) + # - Milena (Customer::Friend::Brother) + # + @luis = {:id => 1, :name => 'Luis', + :friends => [{:name => 'JK', + :brothers => [{:name => 'Mateo', + :children => [{:name => 'Edith'},{:name => 'Martha'}]}, + {:name => 'Felipe', + :children => [{:name => 'Bryan'},{:name => 'Luke'}]}]}, + {:name => 'Eduardo', + :brothers => [{:name => 'Sebas', + :children => [{:name => 'Andres'},{:name => 'Jorge'}]}, + {:name => 'Elsa', + :children => [{:name => 'Natacha'}]}, + {:name => 'Milena', + :children => []}]}]}.to_xml(:root => 'customer') + # - resource with yaml array of strings; for ActiveRecords using serialize :bar, Array + @marty = <<-eof.strip + <?xml version=\"1.0\" encoding=\"UTF-8\"?> + <person> + <id type=\"integer\">5</id> + <name>Marty</name> + <colors type=\"yaml\">--- + - \"red\" + - \"green\" + - \"blue\" + </colors> + </person> + eof + + ActiveResource::HttpMock.respond_to do |mock| + mock.get "/people/1.xml", {}, @matz + mock.get "/people/2.xml", {}, @david + mock.get "/people/5.xml", {}, @marty + mock.get "/people/Greg.xml", {}, @greg + mock.get "/people/4.xml", {'key' => 'value'}, nil, 404 + mock.put "/people/1.xml", {}, nil, 204 + mock.delete "/people/1.xml", {}, nil, 200 + mock.delete "/people/2.xml", {}, nil, 400 + mock.get "/people/99.xml", {}, nil, 404 + mock.post "/people.xml", {}, @rick, 201, 'Location' => '/people/5.xml' + mock.get "/people.xml", {}, @people + mock.get "/people/1/addresses.xml", {}, @addresses + mock.get "/people/1/addresses/1.xml", {}, @addy + mock.get "/people/1/addresses/2.xml", {}, nil, 404 + mock.get "/people/2/addresses.xml", {}, nil, 404 + mock.get "/people/2/addresses/1.xml", {}, nil, 404 + mock.get "/people/Greg/addresses/1.xml", {}, @addy + mock.put "/people/1/addresses/1.xml", {}, nil, 204 + mock.delete "/people/1/addresses/1.xml", {}, nil, 200 + mock.post "/people/1/addresses.xml", {}, nil, 201, 'Location' => '/people/1/addresses/5' + mock.get "/people//addresses.xml", {}, nil, 404 + mock.get "/people//addresses/1.xml", {}, nil, 404 + mock.put "/people//addresses/1.xml", {}, nil, 404 + mock.delete "/people//addresses/1.xml", {}, nil, 404 + mock.post "/people//addresses.xml", {}, nil, 404 + mock.head "/people/1.xml", {}, nil, 200 + mock.head "/people/Greg.xml", {}, nil, 200 + mock.head "/people/99.xml", {}, nil, 404 + mock.head "/people/1/addresses/1.xml", {}, nil, 200 + mock.head "/people/1/addresses/2.xml", {}, nil, 404 + mock.head "/people/2/addresses/1.xml", {}, nil, 404 + mock.head "/people/Greg/addresses/1.xml", {}, nil, 200 + # customer + mock.get "/customers/1.xml", {}, @luis + end + + Person.user = nil + Person.password = nil + end + + def test_find_by_id + matz = Person.find(1) + assert_kind_of Person, matz + assert_equal "Matz", matz.name + assert matz.name? + end + + def test_find_by_id_with_custom_prefix + addy = StreetAddress.find(1, :params => { :person_id => 1 }) + assert_kind_of StreetAddress, addy + assert_equal '12345 Street', addy.street + end + + def test_find_all + all = Person.find(:all) + assert_equal 2, all.size + assert_kind_of Person, all.first + assert_equal "Matz", all.first.name + assert_equal "David", all.last.name + end + + def test_all + all = Person.all + assert_equal 2, all.size + assert_kind_of Person, all.first + assert_equal "Matz", all.first.name + assert_equal "David", all.last.name + end + + def test_all_with_params + all = StreetAddress.all(:params => { :person_id => 1 }) + assert_equal 1, all.size + assert_kind_of StreetAddress, all.first + end + + def test_find_first + matz = Person.find(:first) + assert_kind_of Person, matz + assert_equal "Matz", matz.name + end + + def test_first + matz = Person.first + assert_kind_of Person, matz + assert_equal "Matz", matz.name + end + + def test_first_with_params + addy = StreetAddress.first(:params => { :person_id => 1 }) + assert_kind_of StreetAddress, addy + assert_equal '12345 Street', addy.street + end + + def test_find_last + david = Person.find(:last) + assert_kind_of Person, david + assert_equal 'David', david.name + end + + def test_last + david = Person.last + assert_kind_of Person, david + assert_equal 'David', david.name + end + + def test_last_with_params + addy = StreetAddress.last(:params => { :person_id => 1 }) + assert_kind_of StreetAddress, addy + assert_equal '12345 Street', addy.street + end + + def test_find_by_id_not_found + assert_raise(ActiveResource::ResourceNotFound) { Person.find(99) } + assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1) } + end + + def test_find_all_sub_objects + all = StreetAddress.find(:all, :params => { :person_id => 1 }) + assert_equal 1, all.size + assert_kind_of StreetAddress, all.first + end + + def test_find_all_sub_objects_not_found + assert_nothing_raised do + addys = StreetAddress.find(:all, :params => { :person_id => 2 }) + end + end + + def test_find_all_by_from + ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david } + + people = Person.find(:all, :from => "/companies/1/people.xml") + assert_equal 1, people.size + assert_equal "David", people.first.name + end + + def test_find_all_by_from_with_options + ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david } + + people = Person.find(:all, :from => "/companies/1/people.xml") + assert_equal 1, people.size + assert_equal "David", people.first.name + end + + def test_find_all_by_symbol_from + ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, @people_david } + + people = Person.find(:all, :from => :managers) + assert_equal 1, people.size + assert_equal "David", people.first.name + end + + def test_find_single_by_from + ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david } + + david = Person.find(:one, :from => "/companies/1/manager.xml") + assert_equal "David", david.name + end + + def test_find_single_by_symbol_from + ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david } + + david = Person.find(:one, :from => :leader) + assert_equal "David", david.name + end +end diff --git a/activeresource/test/format_test.rb b/activeresource/test/cases/format_test.rb index c3733e13d8..c3733e13d8 100644 --- a/activeresource/test/format_test.rb +++ b/activeresource/test/cases/format_test.rb diff --git a/activeresource/test/observing_test.rb b/activeresource/test/cases/observing_test.rb index 334b256772..334b256772 100644 --- a/activeresource/test/observing_test.rb +++ b/activeresource/test/cases/observing_test.rb diff --git a/activeresource/test/cases/validations_test.rb b/activeresource/test/cases/validations_test.rb new file mode 100644 index 0000000000..a8ab7d64e7 --- /dev/null +++ b/activeresource/test/cases/validations_test.rb @@ -0,0 +1,55 @@ +require 'abstract_unit' +require "fixtures/project" + +# The validations are tested thoroughly under ActiveModel::Validations +# This test case simply makes sur that they are all accessible by +# Active Resource objects. +class ValidationsTest < ActiveModel::TestCase + VALID_PROJECT_HASH = { :name => "My Project", :description => "A project" } + def setup + @my_proj = VALID_PROJECT_HASH.to_xml(:root => "person") + ActiveResource::HttpMock.respond_to do |mock| + mock.post "/projects.xml", {}, @my_proj, 201, 'Location' => '/projects/5.xml' + end + end + + def test_validates_presence_of + p = new_project(:name => nil) + assert !p.valid?, "should not be a valid record without name" + assert !p.save, "should not have saved an invalid record" + assert_equal ["can't be blank"], p.errors[:name], "should have an error on name" + + p.name = "something" + + assert p.save, "should have saved after fixing the validation, but had: #{p.errors.inspect}" + end + + def test_fails_save! + p = new_project(:name => nil) + assert_raise(ActiveResource::ResourceInvalid) { p.save! } + end + + + def test_validate_callback + # we have a callback ensuring the description is longer than three letters + p = new_project(:description => 'a') + assert !p.valid?, "should not be a valid record when it fails a validation callback" + assert !p.save, "should not have saved an invalid record" + assert_equal ["must be greater than three letters long"], p.errors[:description], "should be an error on description" + + # should now allow this description + p.description = 'abcd' + assert p.save, "should have saved after fixing the validation, but had: #{p.errors.inspect}" + end + + protected + + # quickie helper to create a new project with all the required + # attributes. + # Pass in any params you specifically want to override + def new_project(opts = {}) + Project.new(VALID_PROJECT_HASH.merge(opts)) + end + +end + diff --git a/activeresource/test/connection_test.rb b/activeresource/test/connection_test.rb index 12e8058b0c..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 @@ -204,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/project.rb b/activeresource/test/fixtures/project.rb new file mode 100644 index 0000000000..e15fa6f620 --- /dev/null +++ b/activeresource/test/fixtures/project.rb @@ -0,0 +1,25 @@ +# used to test validations +class Project < ActiveResource::Base + self.site = "http://37s.sunrise.i:3000" + + validates_presence_of :name + validate :description_greater_than_three_letters + + # to test the validate *callback* works + def description_greater_than_three_letters + errors.add :description, 'must be greater than three letters long' if description.length < 3 unless description.blank? + end + + + # stop-gap accessor to default this attribute to nil + # Otherwise the validations fail saying that the method does not exist. + # In future, method_missing will be updated to not explode on a known + # attribute. + def name + attributes['name'] || nil + end + def description + attributes['description'] || nil + end +end + |