amazon-associates 0.6.3
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/.gitignore +3 -0
- data/CHANGELOG +29 -0
- data/LICENSE +21 -0
- data/README.rdoc +84 -0
- data/Rakefile +62 -0
- data/VERSION.yml +5 -0
- data/amazon-associates.gemspec +118 -0
- data/lib/amazon-associates.rb +90 -0
- data/lib/amazon-associates/caching/filesystem_cache.rb +121 -0
- data/lib/amazon-associates/errors.rb +23 -0
- data/lib/amazon-associates/extensions/core.rb +31 -0
- data/lib/amazon-associates/extensions/hpricot.rb +115 -0
- data/lib/amazon-associates/request.rb +143 -0
- data/lib/amazon-associates/requests/browse_node.rb +10 -0
- data/lib/amazon-associates/requests/cart.rb +81 -0
- data/lib/amazon-associates/requests/item.rb +13 -0
- data/lib/amazon-associates/responses/browse_node_lookup_response.rb +10 -0
- data/lib/amazon-associates/responses/cart_responses.rb +26 -0
- data/lib/amazon-associates/responses/item_lookup_response.rb +16 -0
- data/lib/amazon-associates/responses/item_search_response.rb +20 -0
- data/lib/amazon-associates/responses/response.rb +27 -0
- data/lib/amazon-associates/responses/similarity_lookup_response.rb +9 -0
- data/lib/amazon-associates/types/api_result.rb +8 -0
- data/lib/amazon-associates/types/browse_node.rb +48 -0
- data/lib/amazon-associates/types/cart.rb +87 -0
- data/lib/amazon-associates/types/customer_review.rb +15 -0
- data/lib/amazon-associates/types/editorial_review.rb +8 -0
- data/lib/amazon-associates/types/error.rb +8 -0
- data/lib/amazon-associates/types/image.rb +37 -0
- data/lib/amazon-associates/types/image_set.rb +11 -0
- data/lib/amazon-associates/types/item.rb +156 -0
- data/lib/amazon-associates/types/listmania_list.rb +9 -0
- data/lib/amazon-associates/types/measurement.rb +47 -0
- data/lib/amazon-associates/types/offer.rb +10 -0
- data/lib/amazon-associates/types/ordinal.rb +24 -0
- data/lib/amazon-associates/types/price.rb +29 -0
- data/lib/amazon-associates/types/requests.rb +50 -0
- data/spec/requests/browse_node_lookup_spec.rb +41 -0
- data/spec/requests/item_search_spec.rb +27 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/types/cart_spec.rb +294 -0
- data/spec/types/item_spec.rb +55 -0
- data/spec/types/measurement_spec.rb +43 -0
- data/test/amazon/browse_node_test.rb +34 -0
- data/test/amazon/cache_test.rb +33 -0
- data/test/amazon/caching/filesystem_cache_test.rb +198 -0
- data/test/amazon/item_test.rb +397 -0
- data/test/test_helper.rb +9 -0
- data/test/utilities/filesystem_test_helper.rb +35 -0
- metadata +216 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Amazon
|
4
|
+
module Associates
|
5
|
+
describe Item do
|
6
|
+
before(:all) do
|
7
|
+
@item = Amazon::Associates::item_lookup("0545010225").item
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should equal anything with the same #asin" do
|
11
|
+
asin = @item.asin
|
12
|
+
@item.should == Struct.new(:asin).new(asin)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "query for items", :shared => true do
|
16
|
+
it "should return a list of items" do
|
17
|
+
@result.should have_at_least(10).items
|
18
|
+
@result.each {|item| item.should be_an_instance_of(Item) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "query for related items", :shared => true do
|
23
|
+
it_should_behave_like "query for items"
|
24
|
+
it "should not include the item related to the result" do
|
25
|
+
@result.should_not include(@item)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".similar" do
|
30
|
+
before(:all) do
|
31
|
+
@result = Item.similar(@item.asin)
|
32
|
+
end
|
33
|
+
it_should_behave_like "query for related items"
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".all" do
|
37
|
+
before(:all) do
|
38
|
+
@result = Item.all("search_index"=>"Blended", "keywords"=>"potter")
|
39
|
+
end
|
40
|
+
it_should_behave_like "query for items"
|
41
|
+
|
42
|
+
it "should handle hashes with indifferent access" do
|
43
|
+
Item.all(HashWithIndifferentAccess.new("search_index"=>"Blended", "keywords"=>"hello")).should_not == nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#similar" do
|
48
|
+
before(:all) do
|
49
|
+
@result = @item.similar
|
50
|
+
end
|
51
|
+
it_should_behave_like "query for related items"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "measurement object", :shared => true do
|
4
|
+
it "should take a quantity and units" do
|
5
|
+
m = measurement_with(:value => 11.3, :units => 'inches')
|
6
|
+
m.value.should == 11.3
|
7
|
+
m.units.should == 'inches'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should default units to 'pixels', as we use it mostly for images" do
|
11
|
+
m = measurement_with(:value => 22.19)
|
12
|
+
m.value.should == 22.19
|
13
|
+
m.units.should == 'pixels'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should translate 'hundredths-' units to standard quantities" do
|
17
|
+
m = measurement_with(:value => 1130, :units => 'hundredths-inches')
|
18
|
+
m.value.should == 11.3
|
19
|
+
m.units.should == 'inches'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Amazon::Associates::Measurement do
|
24
|
+
describe "#initialize" do
|
25
|
+
def measurement_with(opts)
|
26
|
+
Amazon::Associates::Measurement.new(*opts.values_at(:value, :units).compact)
|
27
|
+
end
|
28
|
+
|
29
|
+
it_should_behave_like "measurement object"
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#from_xml" do
|
33
|
+
def measurement_with(opts)
|
34
|
+
doc = ROXML::XML::Document.new
|
35
|
+
doc.root = ROXML::XML::Node.new('width', doc)
|
36
|
+
doc.root.add_child( Nokogiri::XML::Text.new(opts[:value].to_s, doc))
|
37
|
+
doc.root['Units'] = opts[:units] unless opts[:units].blank?
|
38
|
+
Amazon::Associates::Measurement.from_xml(doc.root)
|
39
|
+
end
|
40
|
+
|
41
|
+
it_should_behave_like "measurement object"
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../test_helper"
|
2
|
+
|
3
|
+
class Amazon::Associates::BrowseNodeLookupTest < Test::Unit::TestCase
|
4
|
+
include FilesystemTestHelper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
set_valid_caching_options
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_browse_node_lookup_with_invalid_request
|
11
|
+
assert_raise(Amazon::Associates::RequiredParameterMissing) do
|
12
|
+
Amazon::Associates.browse_node_lookup(nil)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_browse_node_lookup_with_no_result
|
17
|
+
assert_raise(Amazon::Associates::InvalidParameterValue) do
|
18
|
+
Amazon::Associates.browse_node_lookup("abc")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_items_have_browsenodes
|
23
|
+
item = Amazon::Associates.item_lookup('B000ROI682', :response_group => 'BrowseNodes').items.first
|
24
|
+
assert item.browse_nodes.size > 1
|
25
|
+
item.browse_nodes.each do |browsenode|
|
26
|
+
assert_kind_of Amazon::Associates::BrowseNode, browsenode
|
27
|
+
assert !browsenode.to_s.include?('&'), browsenode.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_browse_nodes_have_top_sellers
|
32
|
+
assert !Amazon::Associates.browse_node_lookup(:response_group => 'TopSellers', :browse_node_id => 493964).browse_nodes.first.top_sellers.empty?
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../test_helper"
|
2
|
+
|
3
|
+
module Amazon
|
4
|
+
module Associates
|
5
|
+
class CacheTest < Test::Unit::TestCase
|
6
|
+
include FilesystemTestHelper
|
7
|
+
context "caching get" do
|
8
|
+
setup do
|
9
|
+
set_valid_caching_options(CACHE_TEST_PATH)
|
10
|
+
end
|
11
|
+
|
12
|
+
teardown do
|
13
|
+
reset_cache
|
14
|
+
end
|
15
|
+
|
16
|
+
should "optionally allow for a caching strategy in configuration" do
|
17
|
+
assert_nothing_raised do
|
18
|
+
set_valid_caching_options(CACHE_TEST_PATH)
|
19
|
+
end
|
20
|
+
assert Amazon::Associates.caching_enabled?
|
21
|
+
end
|
22
|
+
|
23
|
+
should "raise an exception if a caching strategy is specified that is not found" do
|
24
|
+
assert_raise Amazon::Associates::ConfigurationError do
|
25
|
+
Amazon::Associates.configure do |options|
|
26
|
+
options[:caching_strategy] = "foo"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../../test_helper"
|
2
|
+
|
3
|
+
module Amazon
|
4
|
+
module Associates
|
5
|
+
class FilesystemCacheTest < Test::Unit::TestCase
|
6
|
+
include FilesystemTestHelper
|
7
|
+
context "setting up filesystem caching" do
|
8
|
+
teardown do
|
9
|
+
Amazon::Associates.configure do |options|
|
10
|
+
options[:caching_strategy] = nil
|
11
|
+
options[:caching_options] = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
should "require a caching options hash with a cache_path key" do
|
16
|
+
assert_raise Amazon::Associates::ConfigurationError do
|
17
|
+
Amazon::Associates.configure do |options|
|
18
|
+
options[:caching_strategy] = :filesystem
|
19
|
+
options[:caching_options] = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
should "raise an exception when a cache_path is specified that doesn't exist" do
|
25
|
+
assert_raise Amazon::Associates::ConfigurationError do
|
26
|
+
Amazon::Associates.configure do |options|
|
27
|
+
options[:caching_strategy] = :filesystem
|
28
|
+
options[:caching_options] = {:cache_path => "foo123"}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
should "set default values for disk_quota and sweep_frequency" do
|
34
|
+
Amazon::Associates.configure do |options|
|
35
|
+
options[:caching_strategy] = :filesystem
|
36
|
+
options[:caching_options] = {:cache_path => "."}
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_equal Amazon::Associates::FilesystemCache.disk_quota, Amazon::Associates::FilesystemCache.disk_quota
|
40
|
+
assert_equal Amazon::Associates::FilesystemCache.sweep_frequency, Amazon::Associates::FilesystemCache.sweep_frequency
|
41
|
+
end
|
42
|
+
|
43
|
+
should "override the default value for disk quota if I specify one" do
|
44
|
+
quota = 400
|
45
|
+
Amazon::Associates.configure do |options|
|
46
|
+
options[:caching_strategy] = :filesystem
|
47
|
+
options[:caching_options] = {:cache_path => ".", :disk_quota => quota}
|
48
|
+
end
|
49
|
+
|
50
|
+
assert_equal quota, Amazon::Associates::FilesystemCache.disk_quota
|
51
|
+
end
|
52
|
+
|
53
|
+
should "override the default value for cache_frequency if I specify one" do
|
54
|
+
frequency = 4
|
55
|
+
Amazon::Associates.configure do |options|
|
56
|
+
options[:caching_strategy] = :filesystem
|
57
|
+
options[:caching_options] = {:cache_path => ".", :sweep_frequency => frequency}
|
58
|
+
end
|
59
|
+
|
60
|
+
assert_equal frequency, Amazon::Associates::FilesystemCache.sweep_frequency
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "caching a request" do
|
65
|
+
|
66
|
+
setup do
|
67
|
+
set_valid_caching_options(CACHE_TEST_PATH)
|
68
|
+
@resp = Amazon::Associates.item_lookup("0974514055")
|
69
|
+
@filename = Digest::SHA1.hexdigest(@resp.url)
|
70
|
+
end
|
71
|
+
|
72
|
+
teardown do
|
73
|
+
reset_cache
|
74
|
+
end
|
75
|
+
|
76
|
+
should "create a folder in the cache path with the first three letters of the digested filename" do
|
77
|
+
assert FileTest.exists?(File.join(CACHE_TEST_PATH, @filename[0..2]))
|
78
|
+
end
|
79
|
+
|
80
|
+
should "create a file in the cache path with a digested version of the url " do
|
81
|
+
assert FileTest.exists?(File.join(CACHE_TEST_PATH, @filename[0..2], @filename))
|
82
|
+
end
|
83
|
+
|
84
|
+
should "create a file in the cache path with the response inside it" do
|
85
|
+
open(File.join(CACHE_TEST_PATH + @filename[0..2], @filename)) do |f|
|
86
|
+
response = Marshal.load(f)
|
87
|
+
equivalent = eval(ROXML::XML::Parser.parse(response.body).root.name).from_xml(response.body, @resp.url)
|
88
|
+
|
89
|
+
assert_equal @resp, equivalent
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
should "not attemt to cache cart requests" do
|
94
|
+
Amazon::Associates::FilesystemCache.expects(:cache).never
|
95
|
+
|
96
|
+
resp = Amazon::Associates.cart_create(:items => {"0974514055" => 2})
|
97
|
+
filename = Digest::SHA1.hexdigest(resp.url)
|
98
|
+
assert !FileTest.exists?(File.join(CACHE_TEST_PATH, filename[0..2], filename))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "getting a cached request" do
|
103
|
+
setup do
|
104
|
+
set_valid_caching_options(CACHE_TEST_PATH)
|
105
|
+
do_request
|
106
|
+
end
|
107
|
+
|
108
|
+
teardown do
|
109
|
+
reset_cache
|
110
|
+
end
|
111
|
+
|
112
|
+
should "not do an http request the second time the lookup is performed due a cached copy" do
|
113
|
+
Net::HTTP.expects(:get_response).never
|
114
|
+
do_request
|
115
|
+
end
|
116
|
+
|
117
|
+
should "return the same response as the original request" do
|
118
|
+
original = @resp
|
119
|
+
do_request
|
120
|
+
assert_equal(original, @resp)
|
121
|
+
end
|
122
|
+
|
123
|
+
should "not include cache parameters in the response" do
|
124
|
+
assert_no_match(/CachingOptions/, @resp.url)
|
125
|
+
assert_no_match(/caching_options/, @resp.url)
|
126
|
+
assert_no_match(/cache_path/, @resp.url)
|
127
|
+
assert_no_match(/disk_quota/, @resp.url)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "sweeping cached requests" do
|
132
|
+
setup do
|
133
|
+
set_valid_caching_options(CACHE_TEST_PATH)
|
134
|
+
do_request
|
135
|
+
end
|
136
|
+
|
137
|
+
teardown do
|
138
|
+
reset_cache
|
139
|
+
end
|
140
|
+
|
141
|
+
should "not perform the sweep if the timestamp is within the range of the sweep frequency and quota is not exceeded" do
|
142
|
+
Amazon::Associates::FilesystemCache.expects(:sweep_time_expired?).returns(false)
|
143
|
+
Amazon::Associates::FilesystemCache.expects(:disk_quota_exceeded?).returns(false)
|
144
|
+
|
145
|
+
Amazon::Associates::FilesystemCache.expects(:perform_sweep).never
|
146
|
+
|
147
|
+
do_request
|
148
|
+
end
|
149
|
+
|
150
|
+
should "perform a sweep if the quota is exceeded" do
|
151
|
+
Amazon::Associates::FilesystemCache.stubs(:sweep_time_expired?).returns(false)
|
152
|
+
Amazon::Associates::FilesystemCache.expects(:disk_quota_exceeded?).once.returns(true)
|
153
|
+
|
154
|
+
Amazon::Associates::FilesystemCache.expects(:perform_sweep).once
|
155
|
+
|
156
|
+
do_request
|
157
|
+
end
|
158
|
+
|
159
|
+
should "perform a sweep if the sweep time is expired" do
|
160
|
+
Amazon::Associates::FilesystemCache.expects(:sweep_time_expired?).once.returns(true)
|
161
|
+
Amazon::Associates::FilesystemCache.stubs(:disk_quota_exceeded?).returns(false)
|
162
|
+
Amazon::Associates::FilesystemCache.expects(:perform_sweep).once
|
163
|
+
|
164
|
+
do_request
|
165
|
+
end
|
166
|
+
|
167
|
+
should "create a timestamp file after performing a sweep" do
|
168
|
+
Amazon::Associates::FilesystemCache.expects(:sweep_time_expired?).once.returns(true)
|
169
|
+
|
170
|
+
do_request
|
171
|
+
assert FileTest.exists?(File.join(CACHE_TEST_PATH, ".amz_timestamp"))
|
172
|
+
end
|
173
|
+
|
174
|
+
should "purge the cache when performing a sweep" do
|
175
|
+
(0..9).each do |n|
|
176
|
+
test = File.open(File.join(CACHE_TEST_PATH, "test_file_#{n}"), "w")
|
177
|
+
test.puts Time.now
|
178
|
+
test.close
|
179
|
+
end
|
180
|
+
|
181
|
+
Amazon::Associates::FilesystemCache.expects(:sweep_time_expired?).once.returns(true)
|
182
|
+
do_request
|
183
|
+
|
184
|
+
(0..9).each do |n|
|
185
|
+
assert !FileTest.exists?(File.join(CACHE_TEST_PATH, "test_file_#{n}"))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
def do_request
|
193
|
+
@resp = Amazon::Associates.item_lookup("0974514055")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,397 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
module Amazon
|
4
|
+
module Associates
|
5
|
+
class ItemTest < Test::Unit::TestCase
|
6
|
+
include FilesystemTestHelper
|
7
|
+
|
8
|
+
## Test item_search
|
9
|
+
def setup
|
10
|
+
set_valid_caching_options
|
11
|
+
@ruby_search = Amazon::Associates.item_search('ruby')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_item_search
|
15
|
+
assert @ruby_search.request.valid?
|
16
|
+
assert @ruby_search.total_results >= 3600
|
17
|
+
assert @ruby_search.total_pages >= 360
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_page_should_be_one_for_first_page
|
21
|
+
assert_equal 1, @ruby_search.current_page
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_item_search_response_type
|
25
|
+
assert_equal ItemSearchResponse, @ruby_search.class
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_argument_hash
|
29
|
+
assert_equal Hash, @ruby_search.operation_request.arguments.class
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_item_search_with_paging
|
33
|
+
resp = Amazon::Associates.item_search('ruby', :item_page => 2)
|
34
|
+
assert resp.request.valid?
|
35
|
+
assert 2, resp.current_page
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_item_search_with_response_group_array
|
39
|
+
resp = Amazon::Associates.item_search('ruby', :response_group => %w{Small ItemAttributes Images})
|
40
|
+
assert resp.request.valid?
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_item_search_with_invalid_request
|
44
|
+
assert_raise Amazon::Associates::RequiredParameterMissing do
|
45
|
+
Amazon::Associates.item_search(nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_item_search_with_no_result
|
50
|
+
assert_raise Amazon::Associates::ItemNotFound, ' We did not find any matches for your request.' do
|
51
|
+
Amazon::Associates.item_search('afdsafds')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_item_search_uk
|
56
|
+
resp = Amazon::Associates.item_search('ruby', :country => 'uk')
|
57
|
+
assert resp.request.valid?
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_item_search_not_keywords
|
61
|
+
resp = Amazon::Associates.item_search(:author => 'rowling')
|
62
|
+
assert resp.request.valid?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_item_search_by_author
|
66
|
+
resp = Amazon::Associates.item_search('dave', :type => :author)
|
67
|
+
assert resp.request.valid?
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_text_at
|
71
|
+
item = Amazon::Associates.item_search("0974514055", :response_group => 'Large').items.first
|
72
|
+
|
73
|
+
# one item
|
74
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
75
|
+
item.attributes['Title']
|
76
|
+
|
77
|
+
# multiple items
|
78
|
+
assert_equal ['Dave Thomas', 'Chad Fowler', 'Andy Hunt'],
|
79
|
+
item.authors
|
80
|
+
|
81
|
+
#ordinals
|
82
|
+
assert_equal Amazon::Associates::Ordinal.new(2), item.edition
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_item_search_should_handle_string_argument_keys_as_well_as_symbols
|
86
|
+
Amazon::Associates.item_search('potter', 'search_index' => 'Books')
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_hash_at_handles_specific_types
|
90
|
+
item = Amazon::Associates.item_search('ipod', :search_index => 'All', :response_group => 'Small,Offers,ItemAttributes,VariationSummary,Images,BrowseNodes').items.first
|
91
|
+
|
92
|
+
# Measurements & Image
|
93
|
+
assert_equal(Amazon::Associates::Image.new("http://ecx.images-amazon.com/images/I/41zt-RXYhfL._SL75_.jpg",
|
94
|
+
Amazon::Associates::Measurement.new(56, 'pixels'),
|
95
|
+
Amazon::Associates::Measurement.new(75, 'pixels')),
|
96
|
+
item.small_image)
|
97
|
+
|
98
|
+
# bools
|
99
|
+
assert !item.offers.empty?
|
100
|
+
assert_equal true, item.offers.first.is_eligible_for_super_saver_shipping?
|
101
|
+
assert_equal false, item.batteries_included?
|
102
|
+
|
103
|
+
# price
|
104
|
+
assert_equal Amazon::Associates::Price.new('$249.99', 24999, 'USD'), item.list_price
|
105
|
+
|
106
|
+
# integers
|
107
|
+
assert_instance_of Fixnum, item.total_new_offers
|
108
|
+
assert_instance_of Fixnum, item.total_offers
|
109
|
+
|
110
|
+
# attributes
|
111
|
+
assert item.image_sets['primary'], item.image_sets.inspect
|
112
|
+
assert_equal "Mary GrandPré", Amazon::Associates.item_lookup('0545010225').item.creators['Illustrator']
|
113
|
+
|
114
|
+
# browsenodes
|
115
|
+
nodes = item.browse_nodes.detect {|n| n.name == 'MP3 Players' }
|
116
|
+
assert_equal 'MP3 Players', nodes.name
|
117
|
+
assert_equal 'Audio & Video', nodes.parent.name
|
118
|
+
assert_equal 'Apple', nodes.parent.parent.name
|
119
|
+
assert_equal 'Custom Brands', nodes.parent.parent.parent.name
|
120
|
+
|
121
|
+
# ordinals
|
122
|
+
# in test_text_at, above
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_price_should_handle_price_too_low_to_display
|
126
|
+
assert_equal 'Too low to display', Amazon::Associates.item_lookup('B000W79GQA', :response_group => 'Offers').item.lowest_new_price.to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_hash_at_handles_string_editions
|
130
|
+
Amazon::Associates.item_search("potter", :item_page => 3, :response_group => 'Small,Offers,ItemAttributes,VariationSummary,Images').items.each do |item|
|
131
|
+
assert item
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_hash_at_makes_arrays_from_lists
|
136
|
+
item = Amazon::Associates.item_search("0974514055", :response_group => 'Large').items.first
|
137
|
+
|
138
|
+
# when <listmanialists> contains a bunch of <listmanialist>s, return an array
|
139
|
+
assert_equal(["R35BVGTHX7WEKZ", "R195F9SN6I3YQH", "R14L8RHCLAYQMY", "RCWKKCCVL5FGL", "R2IJ2M3X3ITVAR",
|
140
|
+
"R3MGYO2P65FC8J", "R2VY37TQWQM0VJ", "R3DB3MYO22PHZ6", "R192F79G3UXHJ5", "R1L6QNM215M7FB"],
|
141
|
+
item.listmania_lists.map(&:id))
|
142
|
+
|
143
|
+
review = item.editorial_reviews.first
|
144
|
+
# when there's a single child, make sure it's parsed rather than returned as a string
|
145
|
+
assert_equal "Product Description", review.source
|
146
|
+
assert review.content.is_a?(String)
|
147
|
+
assert review.content.size > 100
|
148
|
+
assert review.content.starts_with?("Ruby is an increasingly popular, fully object-oriented d")
|
149
|
+
end
|
150
|
+
|
151
|
+
## Test item_lookup
|
152
|
+
def test_item_lookup
|
153
|
+
resp = Amazon::Associates.item_lookup('0974514055')
|
154
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
155
|
+
resp.item.attributes['Title']
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_item_lookup_with_invalid_request
|
159
|
+
assert_raise Amazon::Associates::RequiredParameterMissing, 'Your request is missing required parameters. Required parameters include ItemId.' do
|
160
|
+
Amazon::Associates.item_lookup(nil)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_item_lookup_with_no_result
|
165
|
+
assert_raise Amazon::Associates::InvalidParameterValue, 'ABC is not a valid value for ItemId. Please change this value and retry your request.' do
|
166
|
+
resp = Amazon::Associates.item_lookup('abc')
|
167
|
+
raise resp.inspect
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_hpricot_extensions
|
172
|
+
item = Amazon::Associates.item_lookup('0974514055').item
|
173
|
+
|
174
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition", item.attributes['Title']
|
175
|
+
assert item.authors.is_a?(Array)
|
176
|
+
assert 3, item.authors.size
|
177
|
+
assert_equal "Dave Thomas", item.authors.first
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class Amazon::Associates::ItemTestsBroughtInFromAssociateGem < Test::Unit::TestCase
|
182
|
+
include FilesystemTestHelper
|
183
|
+
|
184
|
+
def setup
|
185
|
+
set_valid_caching_options
|
186
|
+
Amazon::Associates.options.merge!(:response_group => "Large")
|
187
|
+
end
|
188
|
+
|
189
|
+
## Test item_search
|
190
|
+
def test_item_search
|
191
|
+
resp = Amazon::Associates.item_search("ruby")
|
192
|
+
assert(resp.request.valid?, resp.inspect)
|
193
|
+
assert(resp.total_results >= 3600)
|
194
|
+
assert(resp.total_pages >= 360)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_item_search_with_paging
|
198
|
+
resp = Amazon::Associates.item_search("ruby", :item_page => 2)
|
199
|
+
assert resp.request.valid?, resp.inspect
|
200
|
+
assert 2, resp.current_page
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_item_search_with_no_result
|
204
|
+
assert_raise(Amazon::Associates::ItemNotFound) do
|
205
|
+
Amazon::Associates.item_search("afdsafds")
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_item_search_uk
|
210
|
+
resp = Amazon::Associates.item_search("ruby", :country => :uk)
|
211
|
+
assert resp.request.valid?
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_item_search_by_author
|
215
|
+
resp = Amazon::Associates.item_search("dave", :type => :author)
|
216
|
+
assert resp.request.valid?
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_item_get
|
220
|
+
resp = Amazon::Associates.item_search("0974514055")
|
221
|
+
item = resp.items.first
|
222
|
+
|
223
|
+
# test get
|
224
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
225
|
+
item.attributes['Title']
|
226
|
+
|
227
|
+
# test get_array
|
228
|
+
assert_equal ['Dave Thomas', 'Chad Fowler', 'Andy Hunt'], item.authors
|
229
|
+
|
230
|
+
# test get_hash
|
231
|
+
small_image = item.image_sets.values.first.small
|
232
|
+
|
233
|
+
assert small_image.url != nil
|
234
|
+
assert_equal 75, small_image.height.value
|
235
|
+
assert_equal 59, small_image.width.value
|
236
|
+
end
|
237
|
+
|
238
|
+
## Test item_lookup
|
239
|
+
def test_item_lookup
|
240
|
+
resp = Amazon::Associates.item_lookup("0974514055")
|
241
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
242
|
+
resp.items.first.attributes['Title']
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_item_lookup_with_invalid_request
|
246
|
+
assert_raise(Amazon::Associates::RequiredParameterMissing) do
|
247
|
+
Amazon::Associates.item_lookup(nil)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_item_lookup_with_no_result
|
252
|
+
assert_raise(Amazon::Associates::InvalidParameterValue) do
|
253
|
+
resp = Amazon::Associates.item_lookup("abc")
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_search_and_convert
|
258
|
+
resp = Amazon::Associates.item_lookup("0974514055")
|
259
|
+
title = resp.items.first.attributes['Title']
|
260
|
+
authors = resp.items.first.authors
|
261
|
+
|
262
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition", title
|
263
|
+
assert authors.is_a?(Array)
|
264
|
+
assert 3, authors.size
|
265
|
+
assert_equal "Dave Thomas", authors.first
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class ItemTestBroughtIn < Test::Unit::TestCase
|
270
|
+
include FilesystemTestHelper
|
271
|
+
|
272
|
+
def setup
|
273
|
+
set_valid_caching_options
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_find_all_should_return_items
|
277
|
+
item = Item.find(:all, :keywords => 'upside').first
|
278
|
+
assert item
|
279
|
+
assert_kind_of Item, item
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_find_all_and_find_first_should_yield_same_first
|
283
|
+
params = {:keywords => 'jelly'}
|
284
|
+
assert_equal Item.find(:all, params).first, Item.find(:first, params)
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_find_second_page_returns_different_items_than_first
|
288
|
+
params = {:keywords => 'potter'}
|
289
|
+
assert_not_equal Item.find(:first, params.merge(:page => 1)),
|
290
|
+
Item.find(:first, params.merge(:page => 2))
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_item_creator_should_be_unpacked
|
294
|
+
p "Pending: we're losing info from attributes..."
|
295
|
+
# asin = '0545010225'
|
296
|
+
# item = Item.find(asin)
|
297
|
+
# assert_equal("Mary GrandPré",
|
298
|
+
# Amazon::Associates.item_lookup(asin).items.first.attributes["Creator"])
|
299
|
+
end
|
300
|
+
|
301
|
+
def test_item_list_price_present
|
302
|
+
assert Item.find('0545010225').list_price
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_item_performers_unpacked_to_array
|
306
|
+
assert_equal(["Robert Downey Jr.", "Gwyneth Paltrow", "Terrence Howard", "Jeff Bridges", "Leslie Bibb"],
|
307
|
+
Item.find('B00005JPS8').attributes['Actor'])
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_image_sets_should_be_unpacked
|
311
|
+
item = Item.find(:first, :keywords => 'potter')
|
312
|
+
assert !item.image_sets.empty?
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_missing_item_should_throw
|
316
|
+
assert_raise Amazon::Associates::InvalidParameterValue do
|
317
|
+
Item.find('abc')
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_find_no_page_returns_same_items_as_first
|
322
|
+
params = {:keywords => 'potter'}
|
323
|
+
assert_equal Item.find(:first, params),
|
324
|
+
Item.find(:first, params.merge(:page => 1))
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_find_with_different_sort_returns_different
|
328
|
+
params = {:keywords => 'potter'}
|
329
|
+
assert_not_equal Item.find(:first, params.merge(:sort => Amazon::Associates::SORT_TYPES['Books'][3])),
|
330
|
+
Item.find(:first, params.merge(:sort => Amazon::Associates::SORT_TYPES['Books'][7]))
|
331
|
+
assert_equal Item.find(:first, params.merge(:sort => Amazon::Associates::SORT_TYPES['Books'][3])),
|
332
|
+
Item.find(:first, params.merge(:sort => Amazon::Associates::SORT_TYPES['Books'][3]))
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_find_too_far_a_page_is_error
|
336
|
+
assert_raise Amazon::Associates::ParameterOutOfRange do
|
337
|
+
Item.find(:first, :keywords => 'potter', :page => 9999)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_none_found_is_error
|
342
|
+
assert_raise Amazon::Associates::ItemNotFound do
|
343
|
+
Item.find(:first, :keywords => 'zjvalk', :page => 400)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def test_pagination_basics
|
348
|
+
results = Item.find(:all, :keywords => 'potter', :search_index => 'All')
|
349
|
+
assert_equal 4000, results.total_entries
|
350
|
+
assert_equal 1, results.current_page
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_pagination_sets_current_page
|
354
|
+
[3, 7].each do |page|
|
355
|
+
assert_equal page, Item.find(:all, :keywords => 'potter', :page => page).current_page
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_should_reject_unknown_args
|
360
|
+
assert_raise ArgumentError do
|
361
|
+
Item.find(:first, :keywords => 'potter', :itempage => 12)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def test_find_should_work_for_blended_merchants_and_all
|
366
|
+
assert Item.find(:first, :keywords => 'blackberry', :search_index => 'Blended')
|
367
|
+
assert Item.find(:first, :keywords => 'blackberry', :search_index => 'All')
|
368
|
+
assert Item.find(:first, :keywords => 'blackberry', :search_index => 'Merchants')
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_find_top_sellers_should_return_items
|
372
|
+
assert !Item.find(:top_sellers, :browse_node_id => 520432).empty?
|
373
|
+
end
|
374
|
+
|
375
|
+
def test_should_find_one
|
376
|
+
item_asin = '0545010225'
|
377
|
+
item = Item.find(item_asin)
|
378
|
+
assert item
|
379
|
+
assert item.is_a?(Item)
|
380
|
+
assert_equal item_asin, item.asin
|
381
|
+
end
|
382
|
+
|
383
|
+
def test_find_one_and_first_should_be_equivalent
|
384
|
+
# TODO: or maybe a subset?
|
385
|
+
item1 = Item.find(:first, :keywords => 'potter')
|
386
|
+
item2 = Item.find(item1.asin)
|
387
|
+
assert_equal item1, item2
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_should_raise_on_bad_request
|
391
|
+
assert_raise ArgumentError do
|
392
|
+
Item.find(20)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|