activeresource_csi 2.3.5.p6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +292 -0
- data/README +165 -0
- data/Rakefile +139 -0
- data/lib/active_resource/base.rb +1157 -0
- data/lib/active_resource/connection.rb +283 -0
- data/lib/active_resource/custom_methods.rb +120 -0
- data/lib/active_resource/exceptions.rb +66 -0
- data/lib/active_resource/formats/json_format.rb +23 -0
- data/lib/active_resource/formats/xml_format.rb +34 -0
- data/lib/active_resource/formats.rb +14 -0
- data/lib/active_resource/http_mock.rb +207 -0
- data/lib/active_resource/validations.rb +290 -0
- data/lib/active_resource/version.rb +9 -0
- data/lib/active_resource.rb +44 -0
- data/lib/activeresource.rb +2 -0
- data/test/abstract_unit.rb +21 -0
- data/test/authorization_test.rb +122 -0
- data/test/base/custom_methods_test.rb +100 -0
- data/test/base/equality_test.rb +52 -0
- data/test/base/load_test.rb +161 -0
- data/test/base_errors_test.rb +85 -0
- data/test/base_test.rb +1038 -0
- data/test/connection_test.rb +238 -0
- data/test/debug.log +5335 -0
- data/test/fixtures/beast.rb +14 -0
- data/test/fixtures/customer.rb +3 -0
- data/test/fixtures/person.rb +3 -0
- data/test/fixtures/proxy.rb +4 -0
- data/test/fixtures/street_address.rb +4 -0
- data/test/format_test.rb +112 -0
- data/test/setter_trap.rb +26 -0
- metadata +119 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
|
3
|
+
class AuthorizationTest < Test::Unit::TestCase
|
4
|
+
Response = Struct.new(:code)
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@conn = ActiveResource::Connection.new('http://localhost')
|
8
|
+
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
9
|
+
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
|
10
|
+
@authenticated_conn = ActiveResource::Connection.new("http://david:test123@localhost")
|
11
|
+
@authorization_request_header = { 'Authorization' => 'Basic ZGF2aWQ6dGVzdDEyMw==' }
|
12
|
+
|
13
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
14
|
+
mock.get "/people/2.xml", @authorization_request_header, @david
|
15
|
+
mock.put "/people/2.xml", @authorization_request_header, nil, 204
|
16
|
+
mock.delete "/people/2.xml", @authorization_request_header, nil, 200
|
17
|
+
mock.post "/people/2/addresses.xml", @authorization_request_header, nil, 201, 'Location' => '/people/1/addresses/5'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_authorization_header
|
22
|
+
authorization_header = @authenticated_conn.__send__(:authorization_header)
|
23
|
+
assert_equal @authorization_request_header['Authorization'], authorization_header['Authorization']
|
24
|
+
authorization = authorization_header["Authorization"].to_s.split
|
25
|
+
|
26
|
+
assert_equal "Basic", authorization[0]
|
27
|
+
assert_equal ["david", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_authorization_header_with_username_but_no_password
|
31
|
+
@conn = ActiveResource::Connection.new("http://david:@localhost")
|
32
|
+
authorization_header = @conn.__send__(:authorization_header)
|
33
|
+
authorization = authorization_header["Authorization"].to_s.split
|
34
|
+
|
35
|
+
assert_equal "Basic", authorization[0]
|
36
|
+
assert_equal ["david"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_authorization_header_with_password_but_no_username
|
40
|
+
@conn = ActiveResource::Connection.new("http://:test123@localhost")
|
41
|
+
authorization_header = @conn.__send__(:authorization_header)
|
42
|
+
authorization = authorization_header["Authorization"].to_s.split
|
43
|
+
|
44
|
+
assert_equal "Basic", authorization[0]
|
45
|
+
assert_equal ["", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_authorization_header_with_decoded_credentials_from_url
|
49
|
+
@conn = ActiveResource::Connection.new("http://my%40email.com:%31%32%33@localhost")
|
50
|
+
authorization_header = @conn.__send__(:authorization_header)
|
51
|
+
authorization = authorization_header["Authorization"].to_s.split
|
52
|
+
|
53
|
+
assert_equal "Basic", authorization[0]
|
54
|
+
assert_equal ["my@email.com", "123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_authorization_header_explicitly_setting_username_and_password
|
58
|
+
@authenticated_conn = ActiveResource::Connection.new("http://@localhost")
|
59
|
+
@authenticated_conn.user = 'david'
|
60
|
+
@authenticated_conn.password = 'test123'
|
61
|
+
authorization_header = @authenticated_conn.__send__(:authorization_header)
|
62
|
+
assert_equal @authorization_request_header['Authorization'], authorization_header['Authorization']
|
63
|
+
authorization = authorization_header["Authorization"].to_s.split
|
64
|
+
|
65
|
+
assert_equal "Basic", authorization[0]
|
66
|
+
assert_equal ["david", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_authorization_header_explicitly_setting_username_but_no_password
|
70
|
+
@conn = ActiveResource::Connection.new("http://@localhost")
|
71
|
+
@conn.user = "david"
|
72
|
+
authorization_header = @conn.__send__(:authorization_header)
|
73
|
+
authorization = authorization_header["Authorization"].to_s.split
|
74
|
+
|
75
|
+
assert_equal "Basic", authorization[0]
|
76
|
+
assert_equal ["david"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_authorization_header_explicitly_setting_password_but_no_username
|
80
|
+
@conn = ActiveResource::Connection.new("http://@localhost")
|
81
|
+
@conn.password = "test123"
|
82
|
+
authorization_header = @conn.__send__(:authorization_header)
|
83
|
+
authorization = authorization_header["Authorization"].to_s.split
|
84
|
+
|
85
|
+
assert_equal "Basic", authorization[0]
|
86
|
+
assert_equal ["", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_get
|
90
|
+
david = @authenticated_conn.get("/people/2.xml")
|
91
|
+
assert_equal "David", david["name"]
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_post
|
95
|
+
response = @authenticated_conn.post("/people/2/addresses.xml")
|
96
|
+
assert_equal "/people/1/addresses/5", response["Location"]
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_put
|
100
|
+
response = @authenticated_conn.put("/people/2.xml")
|
101
|
+
assert_equal 204, response.code
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_delete
|
105
|
+
response = @authenticated_conn.delete("/people/2.xml")
|
106
|
+
assert_equal 200, response.code
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_raises_invalid_request_on_unauthorized_requests
|
110
|
+
assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2.xml") }
|
111
|
+
assert_raise(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.xml") }
|
112
|
+
assert_raise(ActiveResource::InvalidRequestError) { @conn.put("/people/2.xml") }
|
113
|
+
assert_raise(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.xml") }
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
def assert_response_raises(klass, code)
|
118
|
+
assert_raise(klass, "Expected response code #{code} to raise #{klass}") do
|
119
|
+
@conn.__send__(:handle_response, Response.new(code))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/person'
|
3
|
+
require 'fixtures/street_address'
|
4
|
+
|
5
|
+
class CustomMethodsTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
8
|
+
@matz_deep = { :id => 1, :name => 'Matz', :other => 'other' }.to_xml(:root => 'person')
|
9
|
+
@matz_array = [{ :id => 1, :name => 'Matz' }].to_xml(:root => 'people')
|
10
|
+
@ryan = { :name => 'Ryan' }.to_xml(:root => 'person')
|
11
|
+
@addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
|
12
|
+
@addy_deep = { :id => 1, :street => '12345 Street', :zip => "27519" }.to_xml(:root => 'address')
|
13
|
+
|
14
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
15
|
+
mock.get "/people/1.xml", {}, @matz
|
16
|
+
mock.get "/people/1/shallow.xml", {}, @matz
|
17
|
+
mock.get "/people/1/deep.xml", {}, @matz_deep
|
18
|
+
mock.get "/people/retrieve.xml?name=Matz", {}, @matz_array
|
19
|
+
mock.get "/people/managers.xml", {}, @matz_array
|
20
|
+
mock.post "/people/hire.xml?name=Matz", {}, nil, 201
|
21
|
+
mock.put "/people/1/promote.xml?position=Manager", {}, nil, 204
|
22
|
+
mock.put "/people/promote.xml?name=Matz", {}, nil, 204, {}
|
23
|
+
mock.put "/people/sort.xml?by=name", {}, nil, 204
|
24
|
+
mock.delete "/people/deactivate.xml?name=Matz", {}, nil, 200
|
25
|
+
mock.delete "/people/1/deactivate.xml", {}, nil, 200
|
26
|
+
mock.post "/people/new/register.xml", {}, @ryan, 201, 'Location' => '/people/5.xml'
|
27
|
+
mock.post "/people/1/register.xml", {}, @matz, 201
|
28
|
+
mock.get "/people/1/addresses/1.xml", {}, @addy
|
29
|
+
mock.get "/people/1/addresses/1/deep.xml", {}, @addy_deep
|
30
|
+
mock.put "/people/1/addresses/1/normalize_phone.xml?locale=US", {}, nil, 204
|
31
|
+
mock.put "/people/1/addresses/sort.xml?by=name", {}, nil, 204
|
32
|
+
mock.post "/people/1/addresses/new/link.xml", {}, { :street => '12345 Street' }.to_xml(:root => 'address'), 201, 'Location' => '/people/1/addresses/2.xml'
|
33
|
+
end
|
34
|
+
|
35
|
+
Person.user = nil
|
36
|
+
Person.password = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def teardown
|
40
|
+
ActiveResource::HttpMock.reset!
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_custom_collection_method
|
44
|
+
# GET
|
45
|
+
assert_equal([{ "id" => 1, "name" => 'Matz' }], Person.get(:retrieve, :name => 'Matz'))
|
46
|
+
|
47
|
+
# POST
|
48
|
+
assert_equal(ActiveResource::Response.new("", 201, {}), Person.post(:hire, :name => 'Matz'))
|
49
|
+
|
50
|
+
# PUT
|
51
|
+
assert_equal ActiveResource::Response.new("", 204, {}),
|
52
|
+
Person.put(:promote, {:name => 'Matz'}, 'atestbody')
|
53
|
+
assert_equal ActiveResource::Response.new("", 204, {}), Person.put(:sort, :by => 'name')
|
54
|
+
|
55
|
+
# DELETE
|
56
|
+
Person.delete :deactivate, :name => 'Matz'
|
57
|
+
|
58
|
+
# Nested resource
|
59
|
+
assert_equal ActiveResource::Response.new("", 204, {}), StreetAddress.put(:sort, :person_id => 1, :by => 'name')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_custom_element_method
|
63
|
+
# Test GET against an element URL
|
64
|
+
assert_equal Person.find(1).get(:shallow), {"id" => 1, "name" => 'Matz'}
|
65
|
+
assert_equal Person.find(1).get(:deep), {"id" => 1, "name" => 'Matz', "other" => 'other'}
|
66
|
+
|
67
|
+
# Test PUT against an element URL
|
68
|
+
assert_equal ActiveResource::Response.new("", 204, {}), Person.find(1).put(:promote, {:position => 'Manager'}, 'body')
|
69
|
+
|
70
|
+
# Test DELETE against an element URL
|
71
|
+
assert_equal ActiveResource::Response.new("", 200, {}), Person.find(1).delete(:deactivate)
|
72
|
+
|
73
|
+
# With nested resources
|
74
|
+
assert_equal StreetAddress.find(1, :params => { :person_id => 1 }).get(:deep),
|
75
|
+
{ "id" => 1, "street" => '12345 Street', "zip" => "27519" }
|
76
|
+
assert_equal ActiveResource::Response.new("", 204, {}),
|
77
|
+
StreetAddress.find(1, :params => { :person_id => 1 }).put(:normalize_phone, :locale => 'US')
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_custom_new_element_method
|
81
|
+
# Test POST against a new element URL
|
82
|
+
ryan = Person.new(:name => 'Ryan')
|
83
|
+
assert_equal ActiveResource::Response.new(@ryan, 201, {'Location' => '/people/5.xml'}), ryan.post(:register)
|
84
|
+
expected_request = ActiveResource::Request.new(:post, '/people/new/register.xml', @ryan)
|
85
|
+
assert_equal expected_request.body, ActiveResource::HttpMock.requests.first.body
|
86
|
+
|
87
|
+
# Test POST against a nested collection URL
|
88
|
+
addy = StreetAddress.new(:street => '123 Test Dr.', :person_id => 1)
|
89
|
+
assert_equal ActiveResource::Response.new({ :street => '12345 Street' }.to_xml(:root => 'address'),
|
90
|
+
201, {'Location' => '/people/1/addresses/2.xml'}),
|
91
|
+
addy.post(:link)
|
92
|
+
|
93
|
+
matz = Person.new(:id => 1, :name => 'Matz')
|
94
|
+
assert_equal ActiveResource::Response.new(@matz, 201), matz.post(:register)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_find_custom_resources
|
98
|
+
assert_equal 'Matz', Person.find(:all, :from => :managers).first.name
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require "fixtures/person"
|
3
|
+
require "fixtures/street_address"
|
4
|
+
|
5
|
+
class BaseEqualityTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@new = Person.new
|
8
|
+
@one = Person.new(:id => 1)
|
9
|
+
@two = Person.new(:id => 2)
|
10
|
+
@street = StreetAddress.new(:id => 2)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_equal_self
|
14
|
+
assert @new == @new, '@new == @new'
|
15
|
+
assert @one == @one, '@one == @one'
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_shouldnt_equal_new_resource
|
19
|
+
assert @new != @one, '@new != @one'
|
20
|
+
assert @one != @new, '@one != @new'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_shouldnt_equal_different_class
|
24
|
+
assert @two != @street, 'person != street_address with same id'
|
25
|
+
assert @street != @two, 'street_address != person with same id'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_eql_should_alias_equals_operator
|
29
|
+
assert_equal @new == @new, @new.eql?(@new)
|
30
|
+
assert_equal @new == @one, @new.eql?(@one)
|
31
|
+
|
32
|
+
assert_equal @one == @one, @one.eql?(@one)
|
33
|
+
assert_equal @one == @new, @one.eql?(@new)
|
34
|
+
|
35
|
+
assert_equal @one == @street, @one.eql?(@street)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_hash_should_be_id_hash
|
39
|
+
[@new, @one, @two, @street].each do |resource|
|
40
|
+
assert_equal resource.id.hash, resource.hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_with_prefix_options
|
45
|
+
assert_equal @one == @one, @one.eql?(@one)
|
46
|
+
assert_equal @one == @one.dup, @one.eql?(@one.dup)
|
47
|
+
new_one = @one.dup
|
48
|
+
new_one.prefix_options = {:foo => 'bar'}
|
49
|
+
assert_not_equal @one, new_one
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require "fixtures/person"
|
3
|
+
require "fixtures/street_address"
|
4
|
+
|
5
|
+
module Highrise
|
6
|
+
class Note < ActiveResource::Base
|
7
|
+
self.site = "http://37s.sunrise.i:3000"
|
8
|
+
end
|
9
|
+
|
10
|
+
class Comment < ActiveResource::Base
|
11
|
+
self.site = "http://37s.sunrise.i:3000"
|
12
|
+
end
|
13
|
+
|
14
|
+
module Deeply
|
15
|
+
module Nested
|
16
|
+
|
17
|
+
class Note < ActiveResource::Base
|
18
|
+
self.site = "http://37s.sunrise.i:3000"
|
19
|
+
end
|
20
|
+
|
21
|
+
class Comment < ActiveResource::Base
|
22
|
+
self.site = "http://37s.sunrise.i:3000"
|
23
|
+
end
|
24
|
+
|
25
|
+
module TestDifferentLevels
|
26
|
+
|
27
|
+
class Note < ActiveResource::Base
|
28
|
+
self.site = "http://37s.sunrise.i:3000"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class BaseLoadTest < Test::Unit::TestCase
|
40
|
+
def setup
|
41
|
+
@matz = { :id => 1, :name => 'Matz' }
|
42
|
+
|
43
|
+
@first_address = { :id => 1, :street => '12345 Street' }
|
44
|
+
@addresses = [@first_address, { :id => 2, :street => '67890 Street' }]
|
45
|
+
@addresses_from_xml = { :street_addresses => @addresses }
|
46
|
+
@addresses_from_xml_single = { :street_addresses => [ @first_address ] }
|
47
|
+
|
48
|
+
@deep = { :id => 1, :street => {
|
49
|
+
:id => 1, :state => { :id => 1, :name => 'Oregon',
|
50
|
+
:notable_rivers => [
|
51
|
+
{ :id => 1, :name => 'Willamette' },
|
52
|
+
{ :id => 2, :name => 'Columbia', :rafted_by => @matz }],
|
53
|
+
:postal_codes => [ 97018, 1234567890 ],
|
54
|
+
:places => [ "Columbia City", "Unknown" ]}}}
|
55
|
+
|
56
|
+
@person = Person.new
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_load_expects_hash
|
60
|
+
assert_raise(ArgumentError) { @person.load nil }
|
61
|
+
assert_raise(ArgumentError) { @person.load '<person id="1"/>' }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_load_simple_hash
|
65
|
+
assert_equal Hash.new, @person.attributes
|
66
|
+
assert_equal @matz.stringify_keys, @person.load(@matz).attributes
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_load_one_with_existing_resource
|
70
|
+
address = @person.load(:street_address => @first_address).street_address
|
71
|
+
assert_kind_of StreetAddress, address
|
72
|
+
assert_equal @first_address.stringify_keys, address.attributes
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_load_one_with_unknown_resource
|
76
|
+
address = silence_warnings { @person.load(:address => @first_address).address }
|
77
|
+
assert_kind_of Person::Address, address
|
78
|
+
assert_equal @first_address.stringify_keys, address.attributes
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_load_collection_with_existing_resource
|
82
|
+
addresses = @person.load(@addresses_from_xml).street_addresses
|
83
|
+
assert_kind_of Array, addresses
|
84
|
+
addresses.each { |address| assert_kind_of StreetAddress, address }
|
85
|
+
assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_load_collection_with_unknown_resource
|
89
|
+
Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
|
90
|
+
assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
|
91
|
+
addresses = silence_warnings { @person.load(:addresses => @addresses).addresses }
|
92
|
+
assert Person.const_defined?(:Address), "Address should have been autocreated"
|
93
|
+
addresses.each { |address| assert_kind_of Person::Address, address }
|
94
|
+
assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_load_collection_with_single_existing_resource
|
98
|
+
addresses = @person.load(@addresses_from_xml_single).street_addresses
|
99
|
+
assert_kind_of Array, addresses
|
100
|
+
addresses.each { |address| assert_kind_of StreetAddress, address }
|
101
|
+
assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_load_collection_with_single_unknown_resource
|
105
|
+
Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
|
106
|
+
assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
|
107
|
+
addresses = silence_warnings { @person.load(:addresses => [ @first_address ]).addresses }
|
108
|
+
assert Person.const_defined?(:Address), "Address should have been autocreated"
|
109
|
+
addresses.each { |address| assert_kind_of Person::Address, address }
|
110
|
+
assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_recursively_loaded_collections
|
114
|
+
person = @person.load(@deep)
|
115
|
+
assert_equal @deep[:id], person.id
|
116
|
+
|
117
|
+
street = person.street
|
118
|
+
assert_kind_of Person::Street, street
|
119
|
+
assert_equal @deep[:street][:id], street.id
|
120
|
+
|
121
|
+
state = street.state
|
122
|
+
assert_kind_of Person::Street::State, state
|
123
|
+
assert_equal @deep[:street][:state][:id], state.id
|
124
|
+
|
125
|
+
rivers = state.notable_rivers
|
126
|
+
assert_kind_of Array, rivers
|
127
|
+
assert_kind_of Person::Street::State::NotableRiver, rivers.first
|
128
|
+
assert_equal @deep[:street][:state][:notable_rivers].first[:id], rivers.first.id
|
129
|
+
assert_equal @matz[:id], rivers.last.rafted_by.id
|
130
|
+
|
131
|
+
postal_codes = state.postal_codes
|
132
|
+
assert_kind_of Array, postal_codes
|
133
|
+
assert_equal 2, postal_codes.size
|
134
|
+
assert_kind_of Fixnum, postal_codes.first
|
135
|
+
assert_equal @deep[:street][:state][:postal_codes].first, postal_codes.first
|
136
|
+
assert_kind_of Numeric, postal_codes.last
|
137
|
+
assert_equal @deep[:street][:state][:postal_codes].last, postal_codes.last
|
138
|
+
|
139
|
+
places = state.places
|
140
|
+
assert_kind_of Array, places
|
141
|
+
assert_kind_of String, places.first
|
142
|
+
assert_equal @deep[:street][:state][:places].first, places.first
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_nested_collections_within_the_same_namespace
|
146
|
+
n = Highrise::Note.new(:comments => [{ :name => "1" }])
|
147
|
+
assert_kind_of Highrise::Comment, n.comments.first
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_nested_collections_within_deeply_nested_namespace
|
151
|
+
n = Highrise::Deeply::Nested::Note.new(:comments => [{ :name => "1" }])
|
152
|
+
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_nested_collections_in_different_levels_of_namespaces
|
156
|
+
n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
|
157
|
+
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require "fixtures/person"
|
3
|
+
|
4
|
+
class BaseErrorsTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
7
|
+
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; charset=utf-8'}
|
8
|
+
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; charset=utf-8'}
|
9
|
+
end
|
10
|
+
@person = Person.new(:name => '', :age => '')
|
11
|
+
assert_equal @person.save, false
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_should_mark_as_invalid
|
15
|
+
[ :json, :xml ].each do |format|
|
16
|
+
invalid_user_using_format(format) do
|
17
|
+
assert !@person.valid?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_parse_xml_errors
|
23
|
+
[ :json, :xml ].each do |format|
|
24
|
+
invalid_user_using_format(format) do
|
25
|
+
assert_kind_of ActiveResource::Errors, @person.errors
|
26
|
+
assert_equal 4, @person.errors.size
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_parse_errors_to_individual_attributes
|
32
|
+
[ :json, :xml ].each do |format|
|
33
|
+
invalid_user_using_format(format) do
|
34
|
+
assert @person.errors[:name].any?
|
35
|
+
assert_equal "can't be blank", @person.errors[:age]
|
36
|
+
assert_equal ["can't be blank", "must start with a letter"], @person.errors[:name]
|
37
|
+
assert_equal "Person quota full for today.", @person.errors[:base]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_should_iterate_over_errors
|
43
|
+
[ :json, :xml ].each do |format|
|
44
|
+
invalid_user_using_format(format) do
|
45
|
+
errors = []
|
46
|
+
@person.errors.each { |attribute, message| errors << [attribute, message] }
|
47
|
+
assert errors.include?(['name', "can't be blank"])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_should_iterate_over_full_errors
|
53
|
+
[ :json, :xml ].each do |format|
|
54
|
+
invalid_user_using_format(format) do
|
55
|
+
errors = []
|
56
|
+
@person.errors.to_a.each { |message| errors << message }
|
57
|
+
assert errors.include?(["name", "can't be blank"])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_format_full_errors
|
63
|
+
[ :json, :xml ].each do |format|
|
64
|
+
invalid_user_using_format(format) do
|
65
|
+
full = @person.errors.full_messages
|
66
|
+
assert full.include?("Age can't be blank")
|
67
|
+
assert full.include?("Name can't be blank")
|
68
|
+
assert full.include?("Name must start with a letter")
|
69
|
+
assert full.include?("Person quota full for today.")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def invalid_user_using_format(mime_type_reference)
|
76
|
+
previous_format = Person.format
|
77
|
+
Person.format = mime_type_reference
|
78
|
+
@person = Person.new(:name => '', :age => '')
|
79
|
+
assert_equal false, @person.save
|
80
|
+
|
81
|
+
yield
|
82
|
+
ensure
|
83
|
+
Person.format = previous_format
|
84
|
+
end
|
85
|
+
end
|