aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/test/cases/base/load_test.rb
blob: 0bbd3ab5f5dd399a32c3959a35f8d6689a7f2256 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
require 'abstract_unit'
require "fixtures/person"
require "fixtures/street_address"
require 'active_support/core_ext/hash/conversions'

module Highrise
  class Note < ActiveResource::Base
    self.site = "http://37s.sunrise.i:3000"
  end

  class Comment < ActiveResource::Base
    self.site = "http://37s.sunrise.i:3000"
  end

  module Deeply
    module Nested
      class Note < ActiveResource::Base
        self.site = "http://37s.sunrise.i:3000"
      end

      class Comment < ActiveResource::Base
        self.site = "http://37s.sunrise.i:3000"
      end

      module TestDifferentLevels
        class Note < ActiveResource::Base
          self.site = "http://37s.sunrise.i:3000"
        end
      end
    end
  end
end


class BaseLoadTest < Test::Unit::TestCase
  def setup
    @matz  = { :id => 1, :name => 'Matz' }

    @first_address = { :address => { :id => 1, :street => '12345 Street' } }
    @addresses = [@first_address, { :address => { :id => 2, :street => '67890 Street' } }]
    @addresses_from_json = { :street_addresses => @addresses }
    @addresses_from_json_single = { :street_addresses => [ @first_address ] }

    @deep  = { :id => 1, :street => {
      :id => 1, :state => { :id => 1, :name => 'Oregon',
        :notable_rivers => [
          { :id => 1, :name => 'Willamette' },
          { :id => 2, :name => 'Columbia', :rafted_by => @matz }],
        :postal_codes => [ 97018, 1234567890 ],
        :dates => [ Time.now ],
        :votes => [ true, false, true ],
        :places => [ "Columbia City", "Unknown" ]}}}


    # List of books formated as [{timestamp_of_publication => name}, ...]
    @books = {:books => [
        {1009839600 => "Ruby in a Nutshell"},
        {1199142000 => "The Ruby Programming Language"}
      ]}

    @books_date = {:books => [
        {Time.at(1009839600) => "Ruby in a Nutshell"},
        {Time.at(1199142000) => "The Ruby Programming Language"}
    ]}
    @person = Person.new
  end

  def test_load_hash_with_integers_as_keys
    assert_nothing_raised{person = @person.load(@books)}
  end

  def test_load_hash_with_dates_as_keys
    assert_nothing_raised{person = @person.load(@books_date)}
  end

  def test_load_expects_hash
    assert_raise(ArgumentError) { @person.load nil }
    assert_raise(ArgumentError) { @person.load '<person id="1"/>' }
  end

  def test_load_simple_hash
    assert_equal Hash.new, @person.attributes
    assert_equal @matz.stringify_keys, @person.load(@matz).attributes
  end

  def test_after_load_attributes_are_accessible
    assert_equal Hash.new, @person.attributes
    assert_equal @matz.stringify_keys, @person.load(@matz).attributes
    assert_equal @matz[:name], @person.attributes['name']
  end

  def test_after_load_attributes_are_accessible_via_indifferent_access
    assert_equal Hash.new, @person.attributes
    assert_equal @matz.stringify_keys, @person.load(@matz).attributes
    assert_equal @matz[:name], @person.attributes['name']
    assert_equal @matz[:name], @person.attributes[:name]
  end

  def test_load_one_with_existing_resource
    address = @person.load(:street_address => @first_address.values.first).street_address
    assert_kind_of StreetAddress, address
    assert_equal @first_address.values.first.stringify_keys, address.attributes
  end

  def test_load_one_with_unknown_resource
    address = silence_warnings { @person.load(@first_address).address }
    assert_kind_of Person::Address, address
    assert_equal @first_address.values.first.stringify_keys, address.attributes
  end

  def test_load_collection_with_existing_resource
    addresses = @person.load(@addresses_from_json).street_addresses
    assert_kind_of Array, addresses
    addresses.each { |address| assert_kind_of StreetAddress, address }
    assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
  end

  def test_load_collection_with_unknown_resource
    Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
    assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
    addresses = silence_warnings { @person.load(:addresses => @addresses).addresses }
    assert Person.const_defined?(:Address), "Address should have been autocreated"
    addresses.each { |address| assert_kind_of Person::Address, address }
    assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
  end

  def test_load_collection_with_single_existing_resource
    addresses = @person.load(@addresses_from_json_single).street_addresses
    assert_kind_of Array, addresses
    addresses.each { |address| assert_kind_of StreetAddress, address }
    assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
  end

  def test_load_collection_with_single_unknown_resource
    Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
    assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
    addresses = silence_warnings { @person.load(:addresses => [ @first_address ]).addresses }
    assert Person.const_defined?(:Address), "Address should have been autocreated"
    addresses.each { |address| assert_kind_of Person::Address, address }
    assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
  end

  def test_recursively_loaded_collections
    person = @person.load(@deep)
    assert_equal @deep[:id], person.id

    street = person.street
    assert_kind_of Person::Street, street
    assert_equal @deep[:street][:id], street.id

    state = street.state
    assert_kind_of Person::Street::State, state
    assert_equal @deep[:street][:state][:id], state.id

    rivers = state.notable_rivers
    assert_kind_of Array, rivers
    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

    dates = state.dates
    assert_kind_of Array, dates
    assert_kind_of Time, dates.first
    assert_equal @deep[:street][:state][:dates].first, dates.first

    votes = state.votes
    assert_kind_of Array, votes
    assert_kind_of TrueClass, votes.first
    assert_equal @deep[:street][:state][:votes].first, votes.first
  end

  def test_nested_collections_within_the_same_namespace
    n = Highrise::Note.new(:comments => [{ :comment => { :name => "1" } }])
    assert_kind_of Highrise::Comment, n.comments.first
  end

  def test_nested_collections_within_deeply_nested_namespace
    n = Highrise::Deeply::Nested::Note.new(:comments => [{ :name => "1" }])
    assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
  end

  def test_nested_collections_in_different_levels_of_namespaces
    n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
    assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
  end
end