a2z 0.1.1 → 0.1.2
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 +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
|
+
[](http://travis-ci.org/mhuggins/a2z)
|
4
|
+
[](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
|
-
|