vacuum 3.1.0 → 4.0.0
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +36 -28
- data/lib/vacuum/locale.rb +3 -1
- data/lib/vacuum/matcher.rb +18 -0
- data/lib/vacuum/request.rb +37 -4
- data/lib/vacuum/response.rb +26 -3
- data/lib/vacuum/version.rb +1 -1
- data/test/helper.rb +10 -0
- data/test/integration/test_requests.rb +105 -0
- data/test/integration_helper.rb +2 -2
- data/test/locales.yml +3 -23
- data/test/{vacuum → unit}/test_locale.rb +7 -7
- data/test/{vacuum → unit}/test_operation.rb +1 -1
- data/test/unit/test_request.rb +23 -0
- data/test/{vacuum → unit}/test_response.rb +5 -1
- metadata +71 -17
- data/test/vacuum/test_request.rb +0 -77
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa1820852b9b98be65a7a8f3a69a65f89a5ac914dff10800bb9524709bb907ea
|
|
4
|
+
data.tar.gz: 8e1b3d9bbc02807619c48259b22424414dbff2f6c7adbf53eddd1962f7b3c055
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a3b132c7c99a7b0f8878e7febc4bed97adac3c26b94b883f3118251f3bc2f71975fe4a9c48d787e0a75b944993bccc8bad78d7a998a7109d8f303a10b95f3ba
|
|
7
|
+
data.tar.gz: 81ebb45404ce50a2519691bc4bfd0acc4898732d0f5c1872aac21892435ded6a345d345c0db8d42ab452cc015dcecdcc6ee4ccab2205dc28b08a22b36da38ed9
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# Vacuum
|
|
2
2
|
|
|
3
3
|
[](https://github.com/hakanensari/vacuum/actions)
|
|
4
|
+
[](https://codeclimate.com/github/hakanensari/vacuum/maintainability)
|
|
5
|
+
[](https://codeclimate.com/github/hakanensari/vacuum/test_coverage)
|
|
4
6
|
|
|
5
7
|
Vacuum is a Ruby wrapper to [Amazon Product Advertising API 5.0](https://webservices.amazon.com/paapi5/documentation/). The API provides programmatic access to query product information on the Amazon marketplaces.
|
|
6
8
|
|
|
9
|
+
Cart Form functionality is not covered by this gem but is a primary focus on [carriage gem](https://github.com/skatkov/carriage)
|
|
10
|
+
|
|
7
11
|
You need to [register first](https://webservices.amazon.com/paapi5/documentation/register-for-pa-api.html) to use the API.
|
|
8
12
|
|
|
9
|
-

|
|
10
14
|
|
|
11
15
|
## Usage
|
|
12
16
|
|
|
@@ -96,16 +100,27 @@ You can also `#dig` into this hash.
|
|
|
96
100
|
response.dig('ItemsResult', 'Items')
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
###
|
|
103
|
+
### Logging
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
Write requests and reponses to a logger using the logging feature of the [HTTP gem](https://github.com/httprb/http) under the hood:
|
|
102
106
|
|
|
103
107
|
```ruby
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
require 'logger'
|
|
109
|
+
|
|
110
|
+
logger = Logger.new(STDOUT)
|
|
111
|
+
request.use(logging: {logger: logger})
|
|
107
112
|
```
|
|
108
113
|
|
|
114
|
+
### Bring your parser
|
|
115
|
+
You can extend Vacuum with a custom parser. Just swap the original with a class or module that responds to `.parse`.
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
response.parser = MyParser
|
|
119
|
+
response.parse
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
If no custom parser is set, `Vacuum::Response#parse` delegates to `#to_h`.
|
|
123
|
+
|
|
109
124
|
### VCR
|
|
110
125
|
|
|
111
126
|
If you are using [VCR](https://github.com/vcr/vcr) to test an app that accesses the API, you can use the custom VCR matcher of Vacuum to stub requests.
|
|
@@ -118,25 +133,11 @@ VCR.insert_cassette('cassette_name',
|
|
|
118
133
|
match_requests_on: [Vacuum::Matcher])
|
|
119
134
|
```
|
|
120
135
|
|
|
121
|
-
In RSpec,
|
|
136
|
+
In RSpec, use the `:paapi` metadata.
|
|
122
137
|
|
|
123
138
|
```ruby
|
|
124
139
|
require 'vacuum/matcher'
|
|
125
140
|
|
|
126
|
-
RSpec.configure do |config|
|
|
127
|
-
config.around do |example|
|
|
128
|
-
if example.metadata[:paapi]
|
|
129
|
-
metadata = example.metadata[:paapi]
|
|
130
|
-
metadata = {} if metadata == true
|
|
131
|
-
example.metadata[:vcr] = metadata.merge(
|
|
132
|
-
match_requests_on: [Vacuum::Matcher]
|
|
133
|
-
)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
example.run
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
141
|
# in your test
|
|
141
142
|
it 'queries Amazon', :paapi do
|
|
142
143
|
end
|
|
@@ -144,22 +145,28 @@ end
|
|
|
144
145
|
|
|
145
146
|
## Development
|
|
146
147
|
|
|
147
|
-
Clone the repo and install dependencies.
|
|
148
|
+
Clone the repo and install dependencies.
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
bundle install
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Tests and Rubocop should now pass as-is.
|
|
148
155
|
|
|
149
156
|
```sh
|
|
150
157
|
bundle exec rake
|
|
151
158
|
```
|
|
152
159
|
|
|
153
|
-
By default,
|
|
160
|
+
By default, the tests stub requests. Use the `RECORD` env var to record new interactions.
|
|
154
161
|
|
|
155
162
|
```sh
|
|
156
|
-
bundle exec
|
|
163
|
+
RECORD=true bundle exec rake test
|
|
157
164
|
```
|
|
158
165
|
|
|
159
|
-
You can
|
|
166
|
+
You can set the `LIVE` env var to run all tests against live data.
|
|
160
167
|
|
|
161
|
-
```
|
|
162
|
-
bundle exec
|
|
168
|
+
```sh
|
|
169
|
+
LIVE=true bundle exec rake test
|
|
163
170
|
```
|
|
164
171
|
|
|
165
172
|
In either case, add actual API credentials to a [`locales.yml`](https://github.com/hakanensari/vacuum/blob/master/test/locales.yml.example) file under `test`.
|
|
@@ -167,6 +174,7 @@ In either case, add actual API credentials to a [`locales.yml`](https://github.c
|
|
|
167
174
|
## Getting Help
|
|
168
175
|
|
|
169
176
|
* Ask specific questions about the API on the [Amazon forum](https://forums.aws.amazon.com/forum.jspa?forumID=9).
|
|
170
|
-
* Report bugs
|
|
177
|
+
* Report bugs in [GitHub issues](https://github.com/hakanensari/vacuum/issues).
|
|
178
|
+
* Discuss potential features in [GitHub Discussions](https://github.com/hakanensari/vacuum/discussions).
|
|
171
179
|
|
|
172
180
|
|
data/lib/vacuum/locale.rb
CHANGED
|
@@ -9,7 +9,6 @@ module Vacuum
|
|
|
9
9
|
# Amazon locale
|
|
10
10
|
class NotFound < KeyError; end
|
|
11
11
|
|
|
12
|
-
# @!visibility private
|
|
13
12
|
HOSTS_AND_REGIONS = {
|
|
14
13
|
au: ['webservices.amazon.com.au', 'us-west-2'],
|
|
15
14
|
br: ['webservices.amazon.com.br', 'us-east-1'],
|
|
@@ -20,12 +19,15 @@ module Vacuum
|
|
|
20
19
|
it: ['webservices.amazon.it', 'eu-west-1'],
|
|
21
20
|
jp: ['webservices.amazon.co.jp', 'us-west-2'],
|
|
22
21
|
mx: ['webservices.amazon.com.mx', 'us-east-1'],
|
|
22
|
+
nl: ['webservices.amazon.nl', 'eu-west-1'],
|
|
23
|
+
sg: ['webservices.amazon.sg', 'us-west-2'],
|
|
23
24
|
es: ['webservices.amazon.es', 'eu-west-1'],
|
|
24
25
|
tr: ['webservices.amazon.com.tr', 'eu-west-1'],
|
|
25
26
|
ae: ['webservices.amazon.ae', 'eu-west-1'],
|
|
26
27
|
gb: ['webservices.amazon.co.uk', 'eu-west-1'],
|
|
27
28
|
us: ['webservices.amazon.com', 'us-east-1']
|
|
28
29
|
}.freeze
|
|
30
|
+
private_constant :HOSTS_AND_REGIONS
|
|
29
31
|
|
|
30
32
|
# @return [String]
|
|
31
33
|
attr_reader :host, :region, :access_key, :secret_key, :partner_tag,
|
data/lib/vacuum/matcher.rb
CHANGED
|
@@ -53,3 +53,21 @@ module Vacuum
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
# :nocov:
|
|
58
|
+
if defined?(RSpec)
|
|
59
|
+
RSpec.configure do |config|
|
|
60
|
+
config.around do |example|
|
|
61
|
+
if example.metadata[:paapi]
|
|
62
|
+
metadata = example.metadata[:paapi]
|
|
63
|
+
metadata = {} if metadata == true
|
|
64
|
+
example.metadata[:vcr] = metadata.merge(
|
|
65
|
+
match_requests_on: [Vacuum::Matcher]
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
example.run
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
# :nocov:
|
data/lib/vacuum/request.rb
CHANGED
|
@@ -28,11 +28,12 @@ module Vacuum
|
|
|
28
28
|
# @param [String] partner_type
|
|
29
29
|
# @raise [Locale::NotFound] if marketplace is not found
|
|
30
30
|
def initialize(marketplace: :us, **args)
|
|
31
|
-
@locale = Locale.new(marketplace, args)
|
|
31
|
+
@locale = Locale.new(marketplace, **args)
|
|
32
32
|
@client = HTTP::Client.new
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# Returns details about specified browse nodes
|
|
36
|
+
#
|
|
36
37
|
# @see https://webservices.amazon.com/paapi5/documentation/getbrowsenodes.html
|
|
37
38
|
# @overload get_browse_nodes(browse_node_ids:, languages_of_preference: nil, marketplace: nil, partner_tag: nil, partner_type: nil, resources: nil)
|
|
38
39
|
# @param [Array<String,Integer>,String,Integer] browse_node_ids
|
|
@@ -48,6 +49,7 @@ module Vacuum
|
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
# Returns the attributes of one or more items
|
|
52
|
+
#
|
|
51
53
|
# @see https://webservices.amazon.com/paapi5/documentation/get-items.html
|
|
52
54
|
# @overload get_items(condition: nil, currency_of_preference: nil, item_id_type: nil, item_ids:, languages_of_preference: nil, marketplace: nil, merchant: nil, offer_count: nil, partner_tag: nil, partner_type: nil, resources: nil)
|
|
53
55
|
# @param [String,nil] condition
|
|
@@ -69,6 +71,7 @@ module Vacuum
|
|
|
69
71
|
|
|
70
72
|
# Returns a set of items that are the same product, but differ according to
|
|
71
73
|
# a consistent theme
|
|
74
|
+
#
|
|
72
75
|
# @see https://webservices.amazon.com/paapi5/documentation/get-variations.html
|
|
73
76
|
# @overload get_variations(asin:, condition: nil, currency_of_preference: nil, languages_of_preference: nil, marketplace: nil, merchant: nil, offer_count: nil, partner_tag: nil, partner_type: nil, resources: nil, variation_count: nil, variation_page: nil)
|
|
74
77
|
# @param [String] asin
|
|
@@ -89,6 +92,7 @@ module Vacuum
|
|
|
89
92
|
end
|
|
90
93
|
|
|
91
94
|
# Searches for items on Amazon based on a search query
|
|
95
|
+
#
|
|
92
96
|
# @see https://webservices.amazon.com/paapi5/documentation/search-items.html
|
|
93
97
|
# @overload search_items(actor: nil, artist: nil, author: nil, availability: nil, brand: nil, browse_node_id: nil, condition: nil, currency_of_preference: nil, delivery_flags: nil, item_count: nil, item_page: nil, keywords: nil, languages_of_preference: nil, marketplace: nil, max_price: nil, merchant: nil, min_price: nil, min_reviews_rating: nil, min_savings_percent: nil, offer_count: nil, partner_tag: nil, partner_type: nil, resources: nil, search_index: nil, sort_by: nil, title: nil)
|
|
94
98
|
# @param [String,nil] actor
|
|
@@ -119,17 +123,46 @@ module Vacuum
|
|
|
119
123
|
request('SearchItems', params)
|
|
120
124
|
end
|
|
121
125
|
|
|
122
|
-
#
|
|
126
|
+
# Flags as persistent
|
|
123
127
|
#
|
|
128
|
+
# @param [Integer] timeout
|
|
124
129
|
# @return [self]
|
|
125
|
-
def persistent
|
|
126
|
-
|
|
130
|
+
def persistent(timeout: 5)
|
|
131
|
+
host = "https://#{locale.host}"
|
|
132
|
+
@client = client.persistent(host, timeout: timeout)
|
|
133
|
+
|
|
127
134
|
self
|
|
128
135
|
end
|
|
129
136
|
|
|
137
|
+
# @!method use(*features)
|
|
138
|
+
# Turn on {https://github.com/httprb/http HTTP} features
|
|
139
|
+
#
|
|
140
|
+
# @param features
|
|
141
|
+
# @return [self]
|
|
142
|
+
#
|
|
143
|
+
# @!method via(*proxy)
|
|
144
|
+
# Make a request through an HTTP proxy
|
|
145
|
+
#
|
|
146
|
+
# @param [Array] proxy
|
|
147
|
+
# @raise [HTTP::Request::Error] if HTTP proxy is invalid
|
|
148
|
+
# @return [self]
|
|
149
|
+
%i[timeout via through headers use].each do |method_name|
|
|
150
|
+
define_method(method_name) do |*args, &block|
|
|
151
|
+
@client = client.send(method_name, *args, &block)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
130
155
|
private
|
|
131
156
|
|
|
157
|
+
def validate_keywords(params)
|
|
158
|
+
return unless params[:keywords]
|
|
159
|
+
return if params[:keywords].is_a?(String)
|
|
160
|
+
|
|
161
|
+
raise ArgumentError, ':keyword argument expects a String'
|
|
162
|
+
end
|
|
163
|
+
|
|
132
164
|
def request(operation_name, params)
|
|
165
|
+
validate_keywords(params)
|
|
133
166
|
@operation = Operation.new(operation_name, params: params, locale: locale)
|
|
134
167
|
response = client.headers(operation.headers)
|
|
135
168
|
.post(operation.url, body: operation.body)
|
data/lib/vacuum/response.rb
CHANGED
|
@@ -10,13 +10,36 @@ module Vacuum
|
|
|
10
10
|
extend Forwardable
|
|
11
11
|
|
|
12
12
|
# @!method dig(*key)
|
|
13
|
-
# Delegates to {Response#to_h} to extract a nested
|
|
14
|
-
#
|
|
15
|
-
#
|
|
13
|
+
# Delegates to the Hash returned by {Response#to_h} to extract a nested
|
|
14
|
+
# value specified by the sequence of keys
|
|
15
|
+
#
|
|
16
|
+
# @param [String] key one or more keys
|
|
16
17
|
# @see https://ruby-doc.org/core/Hash.html#method-i-dig
|
|
17
18
|
def_delegator :to_h, :dig
|
|
18
19
|
|
|
20
|
+
class << self
|
|
21
|
+
# @return [nil,.parse] an optional custom parser
|
|
22
|
+
attr_accessor :parser
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [nil,.parse] an optional custom parser
|
|
26
|
+
attr_writer :parser
|
|
27
|
+
|
|
28
|
+
# @!attribute [r] parser
|
|
29
|
+
# @return [nil,.parse] an optional custom parser
|
|
30
|
+
def parser
|
|
31
|
+
@parser || self.class.parser
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Parses the response body
|
|
35
|
+
#
|
|
36
|
+
# @note Delegates to {#to_h} if no custom parser is set
|
|
37
|
+
def parse
|
|
38
|
+
parser ? parser.parse(body) : to_h
|
|
39
|
+
end
|
|
40
|
+
|
|
19
41
|
# Casts body to Hash
|
|
42
|
+
#
|
|
20
43
|
# @return [Hash]
|
|
21
44
|
def to_h
|
|
22
45
|
JSON.parse(body)
|
data/lib/vacuum/version.rb
CHANGED
data/test/helper.rb
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'integration_helper'
|
|
4
|
+
|
|
5
|
+
module Vacuum
|
|
6
|
+
class TestRequests < IntegrationTest
|
|
7
|
+
def test_get_browse_nodes
|
|
8
|
+
requests.each do |request|
|
|
9
|
+
response = request.get_browse_nodes(browse_node_ids: ['3045'])
|
|
10
|
+
assert_equal 200, response.status
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_get_items
|
|
15
|
+
requests.each do |request|
|
|
16
|
+
response = request.get_items(item_ids: ['B07212L4G2'])
|
|
17
|
+
assert_equal 200, response.status
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
RESOURCE_ALL = %w[BrowseNodeInfo.BrowseNodes
|
|
22
|
+
BrowseNodeInfo.BrowseNodes.Ancestor
|
|
23
|
+
BrowseNodeInfo.BrowseNodes.SalesRank
|
|
24
|
+
BrowseNodeInfo.WebsiteSalesRank
|
|
25
|
+
Images.Primary.Small
|
|
26
|
+
Images.Primary.Medium
|
|
27
|
+
Images.Primary.Large
|
|
28
|
+
Images.Variants.Small
|
|
29
|
+
Images.Variants.Medium
|
|
30
|
+
Images.Variants.Large
|
|
31
|
+
ItemInfo.ByLineInfo
|
|
32
|
+
ItemInfo.Classifications
|
|
33
|
+
ItemInfo.ContentInfo
|
|
34
|
+
ItemInfo.ContentRating
|
|
35
|
+
ItemInfo.ExternalIds
|
|
36
|
+
ItemInfo.Features
|
|
37
|
+
ItemInfo.ManufactureInfo
|
|
38
|
+
ItemInfo.ProductInfo
|
|
39
|
+
ItemInfo.TechnicalInfo
|
|
40
|
+
ItemInfo.Title
|
|
41
|
+
ItemInfo.TradeInInfo
|
|
42
|
+
Offers.Listings.Availability.MaxOrderQuantity
|
|
43
|
+
Offers.Listings.Availability.Message
|
|
44
|
+
Offers.Listings.Availability.MinOrderQuantity
|
|
45
|
+
Offers.Listings.Availability.Type
|
|
46
|
+
Offers.Listings.Condition
|
|
47
|
+
Offers.Listings.Condition.SubCondition
|
|
48
|
+
Offers.Listings.DeliveryInfo.IsAmazonFulfilled
|
|
49
|
+
Offers.Listings.DeliveryInfo.IsFreeShippingEligible
|
|
50
|
+
Offers.Listings.DeliveryInfo.IsPrimeEligible
|
|
51
|
+
Offers.Listings.IsBuyBoxWinner
|
|
52
|
+
Offers.Listings.LoyaltyPoints.Points
|
|
53
|
+
Offers.Listings.MerchantInfo
|
|
54
|
+
Offers.Listings.Price
|
|
55
|
+
Offers.Listings.ProgramEligibility.IsPrimeExclusive
|
|
56
|
+
Offers.Listings.ProgramEligibility.IsPrimePantry
|
|
57
|
+
Offers.Listings.Promotions
|
|
58
|
+
Offers.Listings.SavingBasis
|
|
59
|
+
Offers.Summaries.HighestPrice
|
|
60
|
+
Offers.Summaries.LowestPrice
|
|
61
|
+
Offers.Summaries.OfferCount
|
|
62
|
+
ParentASIN].freeze
|
|
63
|
+
|
|
64
|
+
def test_get_items_with_all_resources
|
|
65
|
+
requests.each do |request|
|
|
66
|
+
response = request.get_items(item_ids: 'B07212L4G2',
|
|
67
|
+
resources: RESOURCE_ALL)
|
|
68
|
+
assert_equal 200, response.status
|
|
69
|
+
item = response.dig('ItemsResult', 'Items').first
|
|
70
|
+
assert item.key?('BrowseNodeInfo')
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_get_variations
|
|
75
|
+
requests.each do |request|
|
|
76
|
+
response = request.get_variations(asin: 'B07212L4G2')
|
|
77
|
+
assert_equal 200, response.status
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_search_items
|
|
82
|
+
requests.each do |request|
|
|
83
|
+
response = request.search_items(keywords: 'Harry Potter')
|
|
84
|
+
assert_equal 200, response.status
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_persistent
|
|
89
|
+
request = requests.sample
|
|
90
|
+
refute request.client.persistent?
|
|
91
|
+
request.persistent
|
|
92
|
+
assert request.client.persistent?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_logging
|
|
96
|
+
require 'logger'
|
|
97
|
+
logdev = StringIO.new
|
|
98
|
+
logger = Logger.new(logdev)
|
|
99
|
+
request = requests.sample
|
|
100
|
+
request.use(logging: { logger: logger })
|
|
101
|
+
request.search_items(keywords: 'Harry Potter')
|
|
102
|
+
refute_empty logdev.string
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
data/test/integration_helper.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'helper'
|
|
4
4
|
require 'vcr'
|
|
5
5
|
|
|
6
6
|
require 'locales'
|
|
@@ -45,7 +45,7 @@ module Vacuum
|
|
|
45
45
|
private
|
|
46
46
|
|
|
47
47
|
def requests
|
|
48
|
-
Locales.map { |credentials| Vacuum.new(credentials) }.shuffle
|
|
48
|
+
Locales.map { |credentials| Vacuum.new(**credentials) }.shuffle
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
data/test/locales.yml
CHANGED
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
- :marketplace:
|
|
2
|
-
:access_key: AKIAIWQTVHVWCQA5THXQ
|
|
3
|
-
:secret_key: VOhSIqIY1wF5selhhJYJGVnIET9k5q0J8QjTX38i
|
|
4
|
-
:partner_tag: adabo00-20
|
|
5
|
-
- :marketplace: ES
|
|
6
|
-
:access_key: AKIAJJF26BJLZLSJLFBQ
|
|
7
|
-
:secret_key: txz+ESbb9Gzw6adcdKtIsLGOP0POFxtP0GHDw1ul
|
|
8
|
-
:partner_tag: adabo00-21
|
|
9
|
-
- :marketplace: DE
|
|
10
|
-
:access_key: AKIAJGN5UNM43HHV5MZA
|
|
11
|
-
:secret_key: ZdccSATM45MN9mjRTTw89mee5VbFoTRd9hYI2sMV
|
|
12
|
-
:partner_tag: adabo23-21
|
|
13
|
-
- :marketplace: FR
|
|
14
|
-
:access_key: AKIAJDNYBNMN23YBFK3A
|
|
15
|
-
:secret_key: hMet2Z4I5tgT6M8mHlGBGUajGyAZN/h2DPFb9z3j
|
|
16
|
-
:partner_tag: adabo-21
|
|
17
|
-
- :marketplace: IT
|
|
18
|
-
:access_key: AKIAJVBAH4XJHK6YF46Q
|
|
19
|
-
:secret_key: aCb2AeLxjNf4KM+Fxx2+ZOw0ftOnnMkuWqVR1kuE
|
|
20
|
-
:partner_tag: adabo0c-21
|
|
21
|
-
- :marketplace: GB
|
|
1
|
+
- :marketplace: UK
|
|
22
2
|
:access_key: AKIAJPAXMP45DOQJPHJQ
|
|
23
3
|
:secret_key: feZKxFjRGLtmEO3JXpmCGdDaCPA7AHiVFBhQ/fkf
|
|
24
|
-
:partner_tag:
|
|
4
|
+
:partner_tag: adabo08-21
|
|
25
5
|
- :marketplace: US
|
|
26
6
|
:access_key: AKIAIWQTVHVWCQA5THXQ
|
|
27
7
|
:secret_key: VOhSIqIY1wF5selhhJYJGVnIET9k5q0J8QjTX38i
|
|
28
|
-
:partner_tag:
|
|
8
|
+
:partner_tag: adabo-20
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'helper'
|
|
4
4
|
require 'vacuum/locale'
|
|
5
5
|
|
|
6
6
|
module Vacuum
|
|
7
7
|
class TestLocale < Minitest::Test
|
|
8
8
|
def test_host
|
|
9
|
-
locale = Locale.new(:us, credentials)
|
|
9
|
+
locale = Locale.new(:us, **credentials)
|
|
10
10
|
assert locale.host
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def test_region
|
|
14
|
-
locale = Locale.new(:us, credentials)
|
|
14
|
+
locale = Locale.new(:us, **credentials)
|
|
15
15
|
assert locale.region
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def test_partner_type_default
|
|
19
|
-
locale = Locale.new(:us, credentials)
|
|
19
|
+
locale = Locale.new(:us, **credentials)
|
|
20
20
|
assert locale.partner_type
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def test_upcased_marketplace
|
|
24
|
-
Locale.new('US', credentials) # does not raise
|
|
24
|
+
Locale.new('US', **credentials) # does not raise
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def test_uk
|
|
28
|
-
Locale.new(:uk, credentials) # does not raise
|
|
28
|
+
Locale.new(:uk, **credentials) # does not raise
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def test_not_found
|
|
32
32
|
assert_raises Locale::NotFound do
|
|
33
|
-
Locale.new(:foo, credentials)
|
|
33
|
+
Locale.new(:foo, **credentials)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'helper'
|
|
4
|
+
require 'vacuum/request'
|
|
5
|
+
|
|
6
|
+
module Vacuum
|
|
7
|
+
class TestRequest < Minitest::Test
|
|
8
|
+
def test_search_keywords
|
|
9
|
+
err = assert_raises(ArgumentError) do
|
|
10
|
+
api.search_items(keywords: ['Harry Potter'])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
assert_equal ':keyword argument expects a String', err.message
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def api
|
|
17
|
+
@api ||= Vacuum::Request.new(marketplace: 'US',
|
|
18
|
+
access_key: 'key',
|
|
19
|
+
secret_key: 'secret',
|
|
20
|
+
partner_tag: 'tag')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'helper'
|
|
4
4
|
require 'vacuum/response'
|
|
5
5
|
|
|
6
6
|
module Vacuum
|
|
@@ -11,6 +11,10 @@ module Vacuum
|
|
|
11
11
|
@response = Response.new(mock)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def test_parse
|
|
15
|
+
assert @response.parse
|
|
16
|
+
end
|
|
17
|
+
|
|
14
18
|
def test_cast_to_hash
|
|
15
19
|
assert_kind_of Hash, @response.to_h
|
|
16
20
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vacuum
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hakan Ensari
|
|
8
|
-
|
|
8
|
+
- Stanislav Katkov
|
|
9
|
+
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2021-05-27 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: aws-sigv4
|
|
@@ -28,16 +29,22 @@ dependencies:
|
|
|
28
29
|
name: http
|
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
|
30
31
|
requirements:
|
|
31
|
-
- - "
|
|
32
|
+
- - ">="
|
|
32
33
|
- !ruby/object:Gem::Version
|
|
33
34
|
version: '4.0'
|
|
35
|
+
- - "<"
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '6.0'
|
|
34
38
|
type: :runtime
|
|
35
39
|
prerelease: false
|
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
41
|
requirements:
|
|
38
|
-
- - "
|
|
42
|
+
- - ">="
|
|
39
43
|
- !ruby/object:Gem::Version
|
|
40
44
|
version: '4.0'
|
|
45
|
+
- - "<"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '6.0'
|
|
41
48
|
- !ruby/object:Gem::Dependency
|
|
42
49
|
name: minitest
|
|
43
50
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,6 +87,48 @@ dependencies:
|
|
|
80
87
|
- - ">="
|
|
81
88
|
- !ruby/object:Gem::Version
|
|
82
89
|
version: '0'
|
|
90
|
+
- !ruby/object:Gem::Dependency
|
|
91
|
+
name: rubocop-minitest
|
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
type: :development
|
|
98
|
+
prerelease: false
|
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
- !ruby/object:Gem::Dependency
|
|
105
|
+
name: rubocop-rake
|
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
type: :development
|
|
112
|
+
prerelease: false
|
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
- !ruby/object:Gem::Dependency
|
|
119
|
+
name: simplecov
|
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - '='
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 0.17.1
|
|
125
|
+
type: :development
|
|
126
|
+
prerelease: false
|
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - '='
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: 0.17.1
|
|
83
132
|
- !ruby/object:Gem::Dependency
|
|
84
133
|
name: vcr
|
|
85
134
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -125,6 +174,7 @@ dependencies:
|
|
|
125
174
|
description: A wrapper to the Amazon Product Advertising API
|
|
126
175
|
email:
|
|
127
176
|
- me@hakanensari.com
|
|
177
|
+
- sk@skylup.com
|
|
128
178
|
executables: []
|
|
129
179
|
extensions: []
|
|
130
180
|
extra_rdoc_files: []
|
|
@@ -139,19 +189,21 @@ files:
|
|
|
139
189
|
- lib/vacuum/response.rb
|
|
140
190
|
- lib/vacuum/version.rb
|
|
141
191
|
- test/cassettes/vacuum.yml
|
|
192
|
+
- test/helper.rb
|
|
193
|
+
- test/integration/test_requests.rb
|
|
142
194
|
- test/integration_helper.rb
|
|
143
195
|
- test/locales.rb
|
|
144
196
|
- test/locales.yml
|
|
145
197
|
- test/locales.yml.example
|
|
146
|
-
- test/
|
|
147
|
-
- test/
|
|
148
|
-
- test/
|
|
149
|
-
- test/
|
|
198
|
+
- test/unit/test_locale.rb
|
|
199
|
+
- test/unit/test_operation.rb
|
|
200
|
+
- test/unit/test_request.rb
|
|
201
|
+
- test/unit/test_response.rb
|
|
150
202
|
homepage: https://github.com/hakanensari/vacuum
|
|
151
203
|
licenses:
|
|
152
204
|
- MIT
|
|
153
205
|
metadata: {}
|
|
154
|
-
post_install_message:
|
|
206
|
+
post_install_message:
|
|
155
207
|
rdoc_options: []
|
|
156
208
|
require_paths:
|
|
157
209
|
- lib
|
|
@@ -159,24 +211,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
159
211
|
requirements:
|
|
160
212
|
- - ">="
|
|
161
213
|
- !ruby/object:Gem::Version
|
|
162
|
-
version: '2.
|
|
214
|
+
version: '2.6'
|
|
163
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
216
|
requirements:
|
|
165
217
|
- - ">="
|
|
166
218
|
- !ruby/object:Gem::Version
|
|
167
219
|
version: '0'
|
|
168
220
|
requirements: []
|
|
169
|
-
rubygems_version: 3.
|
|
170
|
-
signing_key:
|
|
221
|
+
rubygems_version: 3.2.15
|
|
222
|
+
signing_key:
|
|
171
223
|
specification_version: 4
|
|
172
224
|
summary: Amazon Product Advertising in Ruby
|
|
173
225
|
test_files:
|
|
174
|
-
- test/vacuum/test_operation.rb
|
|
175
|
-
- test/vacuum/test_request.rb
|
|
176
|
-
- test/vacuum/test_response.rb
|
|
177
|
-
- test/vacuum/test_locale.rb
|
|
178
226
|
- test/cassettes/vacuum.yml
|
|
227
|
+
- test/helper.rb
|
|
228
|
+
- test/integration/test_requests.rb
|
|
179
229
|
- test/integration_helper.rb
|
|
180
230
|
- test/locales.rb
|
|
181
231
|
- test/locales.yml
|
|
182
232
|
- test/locales.yml.example
|
|
233
|
+
- test/unit/test_locale.rb
|
|
234
|
+
- test/unit/test_operation.rb
|
|
235
|
+
- test/unit/test_request.rb
|
|
236
|
+
- test/unit/test_response.rb
|
data/test/vacuum/test_request.rb
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'integration_helper'
|
|
4
|
-
|
|
5
|
-
module Vacuum
|
|
6
|
-
class TestRequest < IntegrationTest
|
|
7
|
-
def test_get_browse_nodes
|
|
8
|
-
requests.each do |request|
|
|
9
|
-
response = request.get_browse_nodes(browse_node_ids: ['3045'])
|
|
10
|
-
assert_equal 200, response.status
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def test_get_items
|
|
15
|
-
requests.each do |request|
|
|
16
|
-
response = request.get_items(item_ids: ['B07212L4G2'])
|
|
17
|
-
assert_equal 200, response.status
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def test_get_items_with_all_resources
|
|
22
|
-
requests.each do |request|
|
|
23
|
-
response = request.get_items(item_ids: 'B07212L4G2',
|
|
24
|
-
resources: ALL_RESOURCES)
|
|
25
|
-
item = response.dig('ItemsResult', 'Items').first
|
|
26
|
-
assert item.key?('BrowseNodeInfo')
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_get_variations
|
|
31
|
-
requests.each do |request|
|
|
32
|
-
response = request.get_variations(asin: 'B07212L4G2')
|
|
33
|
-
assert_equal 200, response.status
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def test_search_items
|
|
38
|
-
requests.each do |request|
|
|
39
|
-
response = request.search_items(keywords: 'Harry Potter')
|
|
40
|
-
assert_equal 200, response.status
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def test_persistent
|
|
45
|
-
request = requests.sample
|
|
46
|
-
refute request.client.persistent?
|
|
47
|
-
request.persistent
|
|
48
|
-
assert request.client.persistent?
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
ALL_RESOURCES =
|
|
52
|
-
%w[BrowseNodeInfo.BrowseNodes BrowseNodeInfo.BrowseNodes.Ancestor
|
|
53
|
-
BrowseNodeInfo.BrowseNodes.SalesRank BrowseNodeInfo.WebsiteSalesRank
|
|
54
|
-
Images.Primary.Small Images.Primary.Medium Images.Primary.Large
|
|
55
|
-
Images.Variants.Small Images.Variants.Medium Images.Variants.Large
|
|
56
|
-
ItemInfo.ByLineInfo ItemInfo.Classifications ItemInfo.ContentInfo
|
|
57
|
-
ItemInfo.ContentRating ItemInfo.ExternalIds ItemInfo.Features
|
|
58
|
-
ItemInfo.ManufactureInfo ItemInfo.ProductInfo ItemInfo.TechnicalInfo
|
|
59
|
-
ItemInfo.Title ItemInfo.TradeInInfo
|
|
60
|
-
Offers.Listings.Availability.MaxOrderQuantity
|
|
61
|
-
Offers.Listings.Availability.Message
|
|
62
|
-
Offers.Listings.Availability.MinOrderQuantity
|
|
63
|
-
Offers.Listings.Availability.Type Offers.Listings.Condition
|
|
64
|
-
Offers.Listings.Condition.SubCondition
|
|
65
|
-
Offers.Listings.DeliveryInfo.IsAmazonFulfilled
|
|
66
|
-
Offers.Listings.DeliveryInfo.IsFreeShippingEligible
|
|
67
|
-
Offers.Listings.DeliveryInfo.IsPrimeEligible
|
|
68
|
-
Offers.Listings.IsBuyBoxWinner Offers.Listings.LoyaltyPoints.Points
|
|
69
|
-
Offers.Listings.MerchantInfo Offers.Listings.Price
|
|
70
|
-
Offers.Listings.ProgramEligibility.IsPrimeExclusive
|
|
71
|
-
Offers.Listings.ProgramEligibility.IsPrimePantry
|
|
72
|
-
Offers.Listings.Promotions Offers.Listings.SavingBasis
|
|
73
|
-
Offers.Summaries.HighestPrice Offers.Summaries.LowestPrice
|
|
74
|
-
Offers.Summaries.OfferCount ParentASIN].freeze
|
|
75
|
-
private_constant :ALL_RESOURCES
|
|
76
|
-
end
|
|
77
|
-
end
|