a2z 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +9 -0
- data/README.md +38 -13
- data/lib/a2z/responses.rb +1 -0
- data/lib/a2z/responses/browse_node.rb +20 -1
- data/lib/a2z/responses/browse_node_lookup.rb +2 -2
- data/lib/a2z/responses/offer_summary.rb +1 -1
- data/lib/a2z/responses/top_item.rb +21 -0
- data/lib/a2z/version.rb +1 -1
- data/spec/a2z/client_spec.rb +91 -9
- data/spec/a2z/requests/browse_node_lookup_spec.rb +26 -2
- data/spec/a2z/requests/item_lookup_spec.rb +138 -2
- data/spec/a2z/requests/item_search_spec.rb +348 -1
- data/spec/a2z/requests/response_group_spec.rb +46 -2
- data/spec/a2z/responses/top_item_spec.rb +13 -0
- metadata +16 -13
- data/.idea/jsLibraryMappings.xml +0 -18
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## A2z 0.1.2 (Unreleased)
|
2
|
+
|
3
|
+
* Add `most_gifted`, `most_wished_for`, `new_releases`, and `top_sellers`
|
4
|
+
accessors on `BrowseNode`, populating them when present in a browse node
|
5
|
+
lookup response. *Matt Huggins*
|
6
|
+
|
7
|
+
* Fix issue with offer summary parsing the wrong node for `lowest_used_price`.
|
8
|
+
*Matt Huggins*
|
9
|
+
|
1
10
|
## A2z 0.1.1 (Jan 3, 2012)
|
2
11
|
|
3
12
|
* Add `offers` and `offer_summary` accessors on `Item`, populating them when
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# A2z
|
2
2
|
|
3
|
+
[![Build Status](https://secure.travis-ci.org/mhuggins/a2z.png)](http://travis-ci.org/mhuggins/a2z)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/mhuggins/a2z.png)](https://codeclimate.com/github/mhuggins/a2z)
|
5
|
+
|
3
6
|
A2z provides a simple Ruby DSL to retrieve product information from the
|
4
7
|
[Amazon Product Advertising API](https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html).
|
5
8
|
|
@@ -82,10 +85,22 @@ example would make the following calls possible.
|
|
82
85
|
child.name # => "Arts & Photography"
|
83
86
|
child.root? # => false
|
84
87
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
By default, Amazon assumes the response group to be "BrowseNodeInfo".
|
89
|
+
Additional response groups "MostGifted", "MostWishedFor", "NewReleases", and
|
90
|
+
"TopSellers" can be requested as well, allowing access to top items per the
|
91
|
+
following example code.
|
92
|
+
|
93
|
+
node = response.node # => #<A2z::Responses::BrowseNode ...>
|
94
|
+
node.most_gifted.size # => 10
|
95
|
+
node.most_gifted.first # => #<A2z::Responses::TopItem ...>
|
96
|
+
node.most_wished_for.first # => #<A2z::Responses::TopItem ...>
|
97
|
+
node.new_releases.first # => #<A2z::Responses::TopItem ...>
|
98
|
+
node.top_sellers.first # => #<A2z::Responses::TopItem ...>
|
99
|
+
|
100
|
+
For more information on interacting with `A2z::Responses::TopItem` and
|
101
|
+
`A2z::Responses::OperationRequest` objects, refer to their respective sections
|
102
|
+
below. With regards to children, only the direct children are included in a
|
103
|
+
response. However, ancestors are nested all the way to the top-most parent.
|
89
104
|
|
90
105
|
The following code demonstrate the full collection of methods provided when
|
91
106
|
performing a browse node lookup.
|
@@ -261,6 +276,21 @@ response.
|
|
261
276
|
Refer to the Image Sets and Images sections below for more information on using
|
262
277
|
these objects.
|
263
278
|
|
279
|
+
### Top Items
|
280
|
+
|
281
|
+
Top items are accessible on browse nodes when performing browse node lookups
|
282
|
+
with a response group of "MostGifted", "MostWishedFor", "NewReleases", and
|
283
|
+
"TopSellers".
|
284
|
+
|
285
|
+
top_item = node.top_sellers.first # => #<A2z::Responses::TopItem ...>
|
286
|
+
top_item.asin # => "B00AQ3K8IU"
|
287
|
+
top_item.title # => "Hopeless"
|
288
|
+
top_item.product_group # => "eBooks"
|
289
|
+
top_item.actor # => nil
|
290
|
+
top_item.artist # => nil
|
291
|
+
top_item.author # => "Hoover, Colleen"
|
292
|
+
top_item.detail_page_url # => "http://www.amazon.com/Hopeless-ebook/dp/B00AQ3K8IU..."
|
293
|
+
|
264
294
|
### Image Sets
|
265
295
|
|
266
296
|
Image sets are accessible on items when the "Images" responses group is
|
@@ -270,15 +300,10 @@ keyed by size.
|
|
270
300
|
|
271
301
|
For example:
|
272
302
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
item_set = response.item.image_sets[:primary] # => #<A2z::Responses::ImageSet ...>
|
279
|
-
item_set.category # => "primary"
|
280
|
-
item_set.images.keys # => [:swatch, :small, :thumbnail, :tiny, :medium, :large]
|
281
|
-
item_set.images[:swatch] # => #<A2z::Responses::Image ...>
|
303
|
+
item_set = item.image_sets[:primary] # => #<A2z::Responses::ImageSet ...>
|
304
|
+
item_set.category # => "primary"
|
305
|
+
item_set.images.keys # => [:swatch, :small, :thumbnail, :tiny, :medium, :large]
|
306
|
+
item_set.images[:swatch] # => #<A2z::Responses::Image ...>
|
282
307
|
|
283
308
|
Refer to the Images section below for more information on using this objects.
|
284
309
|
|
data/lib/a2z/responses.rb
CHANGED
@@ -3,11 +3,16 @@ module A2z
|
|
3
3
|
class BrowseNode
|
4
4
|
include Helpers
|
5
5
|
|
6
|
-
attr_accessor :id, :name, :ancestors, :children
|
6
|
+
attr_accessor :id, :name, :ancestors, :children, :most_gifted,
|
7
|
+
:most_wished_for, :new_releases, :top_sellers
|
7
8
|
|
8
9
|
def initialize
|
9
10
|
@ancestors = []
|
10
11
|
@children = []
|
12
|
+
@most_gifted = []
|
13
|
+
@most_wished_for = []
|
14
|
+
@new_releases = []
|
15
|
+
@top_sellers = []
|
11
16
|
@root = false
|
12
17
|
end
|
13
18
|
|
@@ -39,6 +44,20 @@ module A2z
|
|
39
44
|
ancestors = array_wrap(data['Ancestors']['BrowseNode'])
|
40
45
|
browse_node.ancestors = ancestors.collect { |ancestor| BrowseNode.from_response(ancestor) }
|
41
46
|
end
|
47
|
+
|
48
|
+
if data['TopItemSet']
|
49
|
+
top_item_sets = array_wrap(data['TopItemSet'])
|
50
|
+
top_item_sets.each do |top_item_set|
|
51
|
+
top_items = array_wrap(top_item_set['TopItem']).collect { |top_item| TopItem.from_response(top_item) }
|
52
|
+
|
53
|
+
case top_item_set['Type']
|
54
|
+
when 'MostGifted' then browse_node.most_gifted = top_items
|
55
|
+
when 'MostWishedFor' then browse_node.most_wished_for = top_items
|
56
|
+
when 'NewReleases' then browse_node.new_releases = top_items
|
57
|
+
when 'TopSellers' then browse_node.top_sellers = top_items
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
42
61
|
end
|
43
62
|
|
44
63
|
browse_node.freeze
|
@@ -20,8 +20,8 @@ module A2z
|
|
20
20
|
def self.from_response(data)
|
21
21
|
new.tap do |browse_node_lookup|
|
22
22
|
browse_node_lookup.operation_request = OperationRequest.from_response(data['OperationRequest']) if data['OperationRequest']
|
23
|
-
browse_node_lookup.node
|
24
|
-
browse_node_lookup.valid
|
23
|
+
browse_node_lookup.node = BrowseNode.from_response(data['BrowseNodes']['BrowseNode'])
|
24
|
+
browse_node_lookup.valid = data['BrowseNodes']['Request']['IsValid'] == 'True' rescue false
|
25
25
|
browse_node_lookup.freeze
|
26
26
|
end
|
27
27
|
end
|
@@ -48,7 +48,7 @@ module A2z
|
|
48
48
|
end
|
49
49
|
|
50
50
|
if data['LowestUsedPrice']
|
51
|
-
offer_summary.lowest_used_price = Money.new(data['
|
51
|
+
offer_summary.lowest_used_price = Money.new(data['LowestUsedPrice']['Amount'].to_i, data['LowestUsedPrice']['CurrencyCode'])
|
52
52
|
end
|
53
53
|
|
54
54
|
offer_summary.total_new = data['TotalNew']
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module A2z
|
2
|
+
module Responses
|
3
|
+
class TopItem
|
4
|
+
attr_accessor :asin, :title, :product_group, :actor, :artist, :author,
|
5
|
+
:detail_page_url
|
6
|
+
|
7
|
+
def self.from_response(data)
|
8
|
+
new.tap do |top_item|
|
9
|
+
top_item.asin = data['ASIN']
|
10
|
+
top_item.title = data['Title']
|
11
|
+
top_item.product_group = data['ProductGroup']
|
12
|
+
top_item.actor = data['Actor']
|
13
|
+
top_item.artist = data['Artist']
|
14
|
+
top_item.author = data['Author']
|
15
|
+
top_item.detail_page_url = data['DetailPageURL']
|
16
|
+
top_item.freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/a2z/version.rb
CHANGED
data/spec/a2z/client_spec.rb
CHANGED
@@ -19,31 +19,113 @@ describe A2z::Client do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
describe '#country
|
23
|
-
|
22
|
+
describe '#country' do
|
23
|
+
subject do
|
24
|
+
A2z::Client.new(country: :us)
|
25
|
+
end
|
26
|
+
|
27
|
+
specify { subject.country.should eq :us }
|
24
28
|
end
|
25
29
|
|
26
|
-
describe '#country' do
|
27
|
-
|
30
|
+
describe '#country=' do
|
31
|
+
subject do
|
32
|
+
A2z::Client.new
|
33
|
+
end
|
34
|
+
|
35
|
+
before do
|
36
|
+
subject.country.should_not eq :fr
|
37
|
+
subject.country = :fr
|
38
|
+
end
|
39
|
+
|
40
|
+
specify { subject.country.should eq :fr }
|
28
41
|
end
|
29
42
|
|
30
43
|
describe '#tag' do
|
31
|
-
|
44
|
+
subject do
|
45
|
+
A2z::Client.new(tag: 'MyTag')
|
46
|
+
end
|
47
|
+
|
48
|
+
specify { subject.tag.should eq 'MyTag' }
|
32
49
|
end
|
33
50
|
|
34
51
|
describe '#item_search' do
|
35
52
|
subject do
|
36
|
-
A2z::Client.new
|
53
|
+
A2z::Client.new(key: 'MyKey', secret: 'MySecret', tag: 'MyTag')
|
54
|
+
end
|
55
|
+
|
56
|
+
before do
|
57
|
+
subject.stub(:get).and_return(item_search_response)
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:block) { proc {} }
|
61
|
+
|
62
|
+
it 'forwards through item search request' do
|
63
|
+
A2z::Requests::ItemSearch.should_receive(:new).with(&block).and_call_original
|
64
|
+
subject.item_search(&block)
|
37
65
|
end
|
38
66
|
|
39
|
-
it '
|
67
|
+
it 'parses item search response' do
|
68
|
+
A2z::Responses::ItemSearch.should_receive(:from_response)
|
69
|
+
subject.item_search(&block)
|
70
|
+
end
|
40
71
|
end
|
41
72
|
|
42
73
|
describe '#item_lookup' do
|
43
74
|
subject do
|
44
|
-
A2z::Client.new
|
75
|
+
A2z::Client.new(key: 'MyKey', secret: 'MySecret', tag: 'MyTag')
|
45
76
|
end
|
46
77
|
|
47
|
-
|
78
|
+
before do
|
79
|
+
subject.stub(:get).and_return(item_lookup_response)
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:block) { proc {} }
|
83
|
+
|
84
|
+
it 'forwards through item search request' do
|
85
|
+
A2z::Requests::ItemLookup.should_receive(:new).with(&block).and_call_original
|
86
|
+
subject.item_lookup(&block)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'parses item search response' do
|
90
|
+
A2z::Responses::ItemLookup.should_receive(:from_response)
|
91
|
+
subject.item_lookup(&block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#browse_node_lookup' do
|
96
|
+
subject do
|
97
|
+
A2z::Client.new(key: 'MyKey', secret: 'MySecret', tag: 'MyTag')
|
98
|
+
end
|
99
|
+
|
100
|
+
before do
|
101
|
+
subject.stub(:get).and_return(browse_node_lookup_response)
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:id) { 1 }
|
105
|
+
let(:block) { proc {} }
|
106
|
+
|
107
|
+
it 'forwards through item search request' do
|
108
|
+
A2z::Requests::BrowseNodeLookup.should_receive(:new).with(id, &block).and_call_original
|
109
|
+
subject.browse_node_lookup(id, &block)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'parses item search response' do
|
113
|
+
A2z::Responses::BrowseNodeLookup.should_receive(:from_response)
|
114
|
+
subject.browse_node_lookup(id, &block)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def item_search_response
|
121
|
+
stub(body: '<OperationRequest/><Items/>')
|
122
|
+
end
|
123
|
+
|
124
|
+
def item_lookup_response
|
125
|
+
stub(body: '<OperationRequest/><Items/>')
|
126
|
+
end
|
127
|
+
|
128
|
+
def browse_node_lookup_response
|
129
|
+
stub(body: '<OperationRequest/><BrowseNodes><BrowseNode/></BrowseNodes>')
|
48
130
|
end
|
49
131
|
end
|
@@ -6,9 +6,33 @@ describe A2z::Requests::BrowseNodeLookup do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:id) { 1 }
|
9
|
-
let(:block) {
|
9
|
+
let(:block) { proc { } }
|
10
10
|
|
11
11
|
describe '#params' do
|
12
|
-
|
12
|
+
specify { subject.params.should be_a Hash }
|
13
|
+
|
14
|
+
it 'sets the operation' do
|
15
|
+
subject.params['Operation'].should eq 'BrowseNodeLookup'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'sets the passed node ID' do
|
19
|
+
subject.params['BrowseNodeId'].should eq id
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'when response group is specified' do
|
23
|
+
let(:block) { proc { response_group 'Offers' } }
|
24
|
+
|
25
|
+
it 'sets the response group' do
|
26
|
+
subject.params['ResponseGroup'].should eq 'Offers'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'when nothing is specified' do
|
31
|
+
let(:block) { proc { } }
|
32
|
+
|
33
|
+
it 'does not set response group' do
|
34
|
+
subject.params.should_not have_key 'ResponseGroup'
|
35
|
+
end
|
36
|
+
end
|
13
37
|
end
|
14
38
|
end
|
@@ -5,9 +5,145 @@ describe A2z::Requests::ItemLookup do
|
|
5
5
|
A2z::Requests::ItemLookup.new(&block)
|
6
6
|
end
|
7
7
|
|
8
|
-
let(:block) {
|
8
|
+
let(:block) { proc { } }
|
9
9
|
|
10
10
|
describe '#params' do
|
11
|
-
|
11
|
+
specify { subject.params.should be_a Hash }
|
12
|
+
|
13
|
+
it 'sets the operation' do
|
14
|
+
subject.params['Operation'].should eq 'ItemLookup'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'when id is specified' do
|
18
|
+
describe 'as a string' do
|
19
|
+
let(:block) { proc { id 'ABC123' } }
|
20
|
+
|
21
|
+
it 'sets the item ID' do
|
22
|
+
subject.params['ItemId'].should eq 'ABC123'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'as an array' do
|
27
|
+
let(:block) { proc { id %w(ABC123 DEF456) } }
|
28
|
+
|
29
|
+
it 'sets the comma-delimited item ID' do
|
30
|
+
subject.params['ItemId'].should eq 'ABC123,DEF456'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'when category is specified' do
|
36
|
+
let(:block) { proc { category 'Books' } }
|
37
|
+
|
38
|
+
it 'sets the search index' do
|
39
|
+
subject.params['SearchIndex'].should eq 'Books'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'when response group is specified' do
|
44
|
+
let(:block) { proc { response_group 'Offers' } }
|
45
|
+
|
46
|
+
it 'sets the response group' do
|
47
|
+
subject.params['ResponseGroup'].should eq 'Offers'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'when include reviews summary is specified' do
|
52
|
+
describe 'as true' do
|
53
|
+
let(:block) { proc { include_reviews_summary true } }
|
54
|
+
|
55
|
+
it 'sets include reviews summary' do
|
56
|
+
subject.params['IncludeReviewsSummary'].should eq 'True'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'as false' do
|
61
|
+
let(:block) { proc { include_reviews_summary false } }
|
62
|
+
|
63
|
+
it 'sets include reviews summary' do
|
64
|
+
subject.params['IncludeReviewsSummary'].should eq 'False'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'when condition is specified' do
|
70
|
+
let(:block) { proc { condition 'New' } }
|
71
|
+
|
72
|
+
it 'sets condition' do
|
73
|
+
subject.params['Condition'].should eq 'New'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'when ID type is specified' do
|
78
|
+
let(:block) { proc { id_type 'ASIN' } }
|
79
|
+
|
80
|
+
it 'sets ID type' do
|
81
|
+
subject.params['IdType'].should eq 'ASIN'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'when merchant ID is specified' do
|
86
|
+
let(:block) { proc { merchant_id 'ABC123' } }
|
87
|
+
|
88
|
+
it 'sets merchant ID' do
|
89
|
+
subject.params['MerchantId'].should eq 'ABC123'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'when truncate reviews at is specified' do
|
94
|
+
let(:block) { proc { truncate_reviews_at 10 } }
|
95
|
+
|
96
|
+
it 'sets truncate reviews at' do
|
97
|
+
subject.params['TruncateReviewsAt'].should eq 10
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'when variation page is specified' do
|
102
|
+
let(:block) { proc { variation_page 10 } }
|
103
|
+
|
104
|
+
it 'sets variation page' do
|
105
|
+
subject.params['VariationPage'].should eq 10
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'when nothing is specified' do
|
110
|
+
let(:block) { proc { } }
|
111
|
+
|
112
|
+
it 'does not set the item ID' do
|
113
|
+
subject.params.should_not have_key 'ItemId'
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'does not set the search index' do
|
117
|
+
subject.params.should_not have_key 'SearchIndex'
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'does not set the response group' do
|
121
|
+
subject.params.should_not have_key 'ResponseGroup'
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'does not set include reviews summary' do
|
125
|
+
subject.params.should_not have_key 'IncludeReviewsSummary'
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not set condition' do
|
129
|
+
subject.params.should_not have_key 'Condition'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'does not set ID type' do
|
133
|
+
subject.params.should_not have_key 'IdType'
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'does not set merchant ID' do
|
137
|
+
subject.params.should_not have_key 'MerchantId'
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'does not set truncate reviews at' do
|
141
|
+
subject.params.should_not have_key 'TruncateReviewsAt'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'does not set variation page' do
|
145
|
+
subject.params.should_not have_key 'VariationPage'
|
146
|
+
end
|
147
|
+
end
|
12
148
|
end
|
13
149
|
end
|
@@ -8,6 +8,353 @@ describe A2z::Requests::ItemSearch do
|
|
8
8
|
let(:block) { Proc.new { } }
|
9
9
|
|
10
10
|
describe '#params' do
|
11
|
-
|
11
|
+
specify { subject.params.should be_a Hash }
|
12
|
+
|
13
|
+
it 'sets the operation' do
|
14
|
+
subject.params['Operation'].should eq 'ItemSearch'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'when keywords are specified' do
|
18
|
+
describe 'as a string' do
|
19
|
+
let(:block) { proc { keywords 'Harry Potter' } }
|
20
|
+
|
21
|
+
it 'sets the keywords' do
|
22
|
+
subject.params['Keywords'].should eq 'Harry Potter'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'as an array' do
|
27
|
+
let(:block) { proc { keywords %w(Harry Potter) } }
|
28
|
+
|
29
|
+
it 'sets the space-delimited keywords' do
|
30
|
+
subject.params['Keywords'].should eq 'Harry Potter'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'when category is specified' do
|
36
|
+
let(:block) { proc { category 'Books' } }
|
37
|
+
|
38
|
+
it 'sets the search index' do
|
39
|
+
subject.params['SearchIndex'].should eq 'Books'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'when response group is specified' do
|
44
|
+
let(:block) { proc { response_group 'Offers' } }
|
45
|
+
|
46
|
+
it 'sets the response group' do
|
47
|
+
subject.params['ResponseGroup'].should eq 'Offers'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'when include reviews summary is specified' do
|
52
|
+
describe 'as true' do
|
53
|
+
let(:block) { proc { include_reviews_summary true } }
|
54
|
+
|
55
|
+
it 'sets include reviews summary' do
|
56
|
+
subject.params['IncludeReviewsSummary'].should eq 'True'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'as false' do
|
61
|
+
let(:block) { proc { include_reviews_summary false } }
|
62
|
+
|
63
|
+
it 'sets include reviews summary' do
|
64
|
+
subject.params['IncludeReviewsSummary'].should eq 'False'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'when actor is specified' do
|
70
|
+
let(:block) { proc { actor 'Matt Damon' } }
|
71
|
+
|
72
|
+
it 'sets the actor' do
|
73
|
+
subject.params['Actor'].should eq 'Matt Damon'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'when artist is specified' do
|
78
|
+
let(:block) { proc { artist 'Grouplove' } }
|
79
|
+
|
80
|
+
it 'sets the artist' do
|
81
|
+
subject.params['Artist'].should eq 'Grouplove'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'when audience rating is specified' do
|
86
|
+
let(:block) { proc { audience_rating 'PG' } }
|
87
|
+
|
88
|
+
it 'sets the audience rating' do
|
89
|
+
subject.params['AudienceRating'].should eq 'PG'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'when author is specified' do
|
94
|
+
let(:block) { proc { author 'J.K. Rowling' } }
|
95
|
+
|
96
|
+
it 'sets the author' do
|
97
|
+
subject.params['Author'].should eq 'J.K. Rowling'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'when brand is specified' do
|
102
|
+
let(:block) { proc { brand 'Timex' } }
|
103
|
+
|
104
|
+
it 'sets the brand' do
|
105
|
+
subject.params['Brand'].should eq 'Timex'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'when browse node is specified' do
|
110
|
+
let(:block) { proc { browse_node 100 } }
|
111
|
+
|
112
|
+
it 'sets the browse node' do
|
113
|
+
subject.params['BrowseNode'].should eq 100
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'when composer is specified' do
|
118
|
+
let(:block) { proc { composer 'Bach' } }
|
119
|
+
|
120
|
+
it 'sets the composer' do
|
121
|
+
subject.params['Composer'].should eq 'Bach'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe 'when conductor is specified' do
|
126
|
+
let(:block) { proc { conductor 'Gustav Mahler' } }
|
127
|
+
|
128
|
+
it 'sets the conductor' do
|
129
|
+
subject.params['Conductor'].should eq 'Gustav Mahler'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'when condition is specified' do
|
134
|
+
let(:block) { proc { condition 'New' } }
|
135
|
+
|
136
|
+
it 'sets the condition' do
|
137
|
+
subject.params['Condition'].should eq 'New'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'when director is specified' do
|
142
|
+
let(:block) { proc { director 'Judd Apatow' } }
|
143
|
+
|
144
|
+
it 'sets the director' do
|
145
|
+
subject.params['Director'].should eq 'Judd Apatow'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'when item page is specified' do
|
150
|
+
let(:block) { proc { item_page 8 } }
|
151
|
+
|
152
|
+
it 'sets the item page' do
|
153
|
+
subject.params['ItemPage'].should eq 8
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'when manufacturer is specified' do
|
158
|
+
let(:block) { proc { manufacturer 'Dr Pepper' } }
|
159
|
+
it 'sets the manufacturer' do
|
160
|
+
subject.params['Manufacturer'].should eq 'Dr Pepper'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'when maximum price is specified' do
|
165
|
+
let(:block) { proc { maximum_price 10.99 } }
|
166
|
+
|
167
|
+
it 'sets the maximum price' do
|
168
|
+
subject.params['MaximumPrice'].should eq 10.99
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'when merchant ID is specified' do
|
173
|
+
let(:block) { proc { merchant_id 'ABC123' } }
|
174
|
+
|
175
|
+
it 'sets the merchant ID' do
|
176
|
+
subject.params['MerchantId'].should eq 'ABC123'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe 'when minimum percentage off is specified' do
|
181
|
+
let(:block) { proc { min_percentage_off 20 } }
|
182
|
+
|
183
|
+
it 'sets the minimum percentage off' do
|
184
|
+
subject.params['MinPercentageOff'].should eq 20
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe 'when orchestra is specified' do
|
189
|
+
let(:block) { proc { orchestra 'Antonio Vivaldi' } }
|
190
|
+
|
191
|
+
it 'sets the orchestra' do
|
192
|
+
subject.params['Orchestra'].should eq 'Antonio Vivaldi'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe 'when power search is specified' do
|
197
|
+
let(:block) { proc { power 'subject:history and (spain or mexico) and not military and language:spanish' } }
|
198
|
+
|
199
|
+
it 'sets the power' do
|
200
|
+
subject.params['Power'].should eq 'subject:history and (spain or mexico) and not military and language:spanish'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe 'when publisher is specified' do
|
205
|
+
let(:block) { proc { publisher 'EMI' } }
|
206
|
+
|
207
|
+
it 'sets the publisher' do
|
208
|
+
subject.params['Publisher'].should eq 'EMI'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe 'when sort is specified' do
|
213
|
+
let(:block) { proc { sort 'inverse-pricerank' } }
|
214
|
+
|
215
|
+
it 'sets the sort' do
|
216
|
+
subject.params['Sort'].should eq 'inverse-pricerank'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe 'when title is specified' do
|
221
|
+
let(:block) { proc { title 'The Wheel of Time' } }
|
222
|
+
|
223
|
+
it 'sets the title' do
|
224
|
+
subject.params['Title'].should eq 'The Wheel of Time'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe 'when variation page is specified' do
|
229
|
+
let(:block) { proc { variation_page 2 } }
|
230
|
+
|
231
|
+
it 'sets the variation page' do
|
232
|
+
subject.params['VariationPage'].should eq 2
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'when truncate reviews at is specified' do
|
237
|
+
let(:block) { proc { truncate_reviews_at 5 } }
|
238
|
+
|
239
|
+
it 'sets the truncate reviews at' do
|
240
|
+
subject.params['TruncateReviewsAt'].should eq 5
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'when nothing is specified' do
|
245
|
+
let(:block) { proc { } }
|
246
|
+
|
247
|
+
it 'does not set the keywords' do
|
248
|
+
subject.params.should_not have_key 'Keywords'
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'does not set the search index' do
|
252
|
+
subject.params.should_not have_key 'SearchIndex'
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'does not set the response group' do
|
256
|
+
subject.params.should_not have_key 'ResponseGroup'
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'does not set include reviews summary' do
|
260
|
+
subject.params.should_not have_key 'IncludeReviewsSummary'
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'does not set actor' do
|
264
|
+
subject.params.should_not have_key 'Actor'
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'does not set artist' do
|
268
|
+
subject.params.should_not have_key 'Artist'
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'does not set audience rating' do
|
272
|
+
subject.params.should_not have_key 'AudienceRating'
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'does not set author' do
|
276
|
+
subject.params.should_not have_key 'Author'
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'does not set brand' do
|
280
|
+
subject.params.should_not have_key 'Brand'
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'does not set browse node' do
|
284
|
+
subject.params.should_not have_key 'BrowseNode'
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'does not set composer' do
|
288
|
+
subject.params.should_not have_key 'Composer'
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'does not set conductor' do
|
292
|
+
subject.params.should_not have_key 'Conductor'
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'does not set condition' do
|
296
|
+
subject.params.should_not have_key 'Condition'
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'does not set director' do
|
300
|
+
subject.params.should_not have_key 'Director'
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'does not set item page' do
|
304
|
+
subject.params.should_not have_key 'ItemPage'
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'does not set manufacturer' do
|
308
|
+
subject.params.should_not have_key 'Manufacturer'
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'does not set maximum price' do
|
312
|
+
subject.params.should_not have_key 'MaximumPrice'
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'does not set merchant ID' do
|
316
|
+
subject.params.should_not have_key 'MerchantId'
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'does not set minimum price' do
|
320
|
+
subject.params.should_not have_key 'MinimumPrice'
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'does not set minimum percentage off' do
|
324
|
+
subject.params.should_not have_key 'MinPercentageOff'
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'does not set music label' do
|
328
|
+
subject.params.should_not have_key 'MusicLabel'
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'does not set orchestra' do
|
332
|
+
subject.params.should_not have_key 'Orchestra'
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'does not set power' do
|
336
|
+
subject.params.should_not have_key 'Power'
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'does not set publisher' do
|
340
|
+
subject.params.should_not have_key 'Publisher'
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'does not set sort' do
|
344
|
+
subject.params.should_not have_key 'Sort'
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'does not set title' do
|
348
|
+
subject.params.should_not have_key 'Title'
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'does not set truncate reviews at' do
|
352
|
+
subject.params.should_not have_key 'TruncateReviewsAt'
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'does not set variation page' do
|
356
|
+
subject.params.should_not have_key 'VariationPage'
|
357
|
+
end
|
358
|
+
end
|
12
359
|
end
|
13
360
|
end
|
@@ -6,9 +6,53 @@ describe A2z::Requests::ResponseGroup do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:value) { nil }
|
9
|
-
let(:block) {
|
9
|
+
let(:block) { proc { } }
|
10
10
|
|
11
11
|
describe '#params' do
|
12
|
-
|
12
|
+
specify { subject.params.should be_a Hash }
|
13
|
+
|
14
|
+
describe 'when value is a string' do
|
15
|
+
let(:value) { 'OfferSummary' }
|
16
|
+
|
17
|
+
it 'sets the response group' do
|
18
|
+
subject.params['ResponseGroup'].should eq 'OfferSummary'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'when value is an array' do
|
23
|
+
let(:value) { %w(OfferSummary Images) }
|
24
|
+
|
25
|
+
it 'sets the comma-delimited response group' do
|
26
|
+
subject.params['ResponseGroup'].should eq 'OfferSummary,Images'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'when the related item page is specified' do
|
31
|
+
let(:block) { proc { related_item_page 2 } }
|
32
|
+
|
33
|
+
it 'sets the related item page' do
|
34
|
+
subject.params['RelatedItemPage'].should eq 2
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'when the relationship type is specified' do
|
39
|
+
let(:block) { proc { relationship_type 'Episode' } }
|
40
|
+
|
41
|
+
it 'sets the relationship type' do
|
42
|
+
subject.params['RelationshipType'].should eq 'Episode'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'when nothing is specified' do
|
47
|
+
let(:block) { proc { } }
|
48
|
+
|
49
|
+
it 'does not set the related item page' do
|
50
|
+
subject.params.should_not have_key 'RelatedItemPage'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'does not set the relationship type' do
|
54
|
+
subject.params.should_not have_key 'RelationshipType'
|
55
|
+
end
|
56
|
+
end
|
13
57
|
end
|
14
58
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe A2z::Responses::TopItem do
|
4
|
+
subject do
|
5
|
+
A2z::Responses::TopItem.from_response(top_item_hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:top_item_hash) { Hash.new }
|
9
|
+
|
10
|
+
describe '.from_response' do
|
11
|
+
it 'should return a top item object'
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: a2z
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01
|
12
|
+
date: 2013-07-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: crack
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153748040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153748040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jeff
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153747620 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153747620
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: money
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153747200 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153747200
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153746780 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153746780
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &2153746360 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2153746360
|
69
69
|
description: Ruby DSL for Amazon Product Advertising API
|
70
70
|
email: matt.huggins@gmail.com
|
71
71
|
executables: []
|
@@ -73,7 +73,7 @@ extensions: []
|
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
75
|
- .gitignore
|
76
|
-
- .
|
76
|
+
- .travis.yml
|
77
77
|
- CHANGELOG.md
|
78
78
|
- Gemfile
|
79
79
|
- LICENSE
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- lib/a2z/responses/offer.rb
|
103
103
|
- lib/a2z/responses/offer_summary.rb
|
104
104
|
- lib/a2z/responses/operation_request.rb
|
105
|
+
- lib/a2z/responses/top_item.rb
|
105
106
|
- lib/a2z/version.rb
|
106
107
|
- spec/a2z/client_spec.rb
|
107
108
|
- spec/a2z/requests/browse_node_lookup_spec.rb
|
@@ -119,6 +120,7 @@ files:
|
|
119
120
|
- spec/a2z/responses/item_spec.rb
|
120
121
|
- spec/a2z/responses/offer_spec.rb
|
121
122
|
- spec/a2z/responses/offer_summary_spec.rb
|
123
|
+
- spec/a2z/responses/top_item_spec.rb
|
122
124
|
- spec/a2z/version_spec.rb
|
123
125
|
- spec/spec_helper.rb
|
124
126
|
- tasks/debug.rake
|
@@ -164,5 +166,6 @@ test_files:
|
|
164
166
|
- spec/a2z/responses/item_spec.rb
|
165
167
|
- spec/a2z/responses/offer_spec.rb
|
166
168
|
- spec/a2z/responses/offer_summary_spec.rb
|
169
|
+
- spec/a2z/responses/top_item_spec.rb
|
167
170
|
- spec/a2z/version_spec.rb
|
168
171
|
- spec/spec_helper.rb
|
data/.idea/jsLibraryMappings.xml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<project version="4">
|
3
|
-
<component name="JavaScriptLibraryMappings">
|
4
|
-
<excludedPredefinedLibrary name="AJAX" />
|
5
|
-
<excludedPredefinedLibrary name="DHTML" />
|
6
|
-
<excludedPredefinedLibrary name="DOM Core" />
|
7
|
-
<excludedPredefinedLibrary name="DOM Events" />
|
8
|
-
<excludedPredefinedLibrary name="DOM Traversal And Range" />
|
9
|
-
<excludedPredefinedLibrary name="DOM XPath" />
|
10
|
-
<excludedPredefinedLibrary name="EcmaScript" />
|
11
|
-
<excludedPredefinedLibrary name="EcmaScript Additional" />
|
12
|
-
<excludedPredefinedLibrary name="EcmaScript L5" />
|
13
|
-
<excludedPredefinedLibrary name="EcmaScript for XML" />
|
14
|
-
<excludedPredefinedLibrary name="HTML 5" />
|
15
|
-
<excludedPredefinedLibrary name="WebGL" />
|
16
|
-
</component>
|
17
|
-
</project>
|
18
|
-
|