peddler 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/peddler/client.rb +3 -1
- data/lib/peddler/vcr_matcher.rb +83 -0
- data/lib/peddler/version.rb +1 -1
- data/test/helper.rb +15 -12
- data/test/null_client.rb +23 -0
- data/test/unit/peddler/test_client.rb +13 -20
- data/test/unit/peddler/test_vcr_matcher.rb +47 -0
- data/test/vcr_cassettes/PeddlerVCRMatcher.yml +41 -0
- metadata +10 -4
- data/lib/peddler/test/vcr_matcher.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7eb80f7f028b5464f42c29cb72ce60e2eda123d
|
4
|
+
data.tar.gz: 8a814e73f8695da5b01b0e14d62732beec970cd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d736136aed3d96ebc1fc61be23638350ba84e82a7473e8ce62bf3f8086cac12e3640539895b3c25f41f739c41d7d76ff3a5193d38636932c323351967d5d9701
|
7
|
+
data.tar.gz: c03d025e24a676ab7150f685eef1db93b183f942f2b7259ba44e51f394dd77d195d335bbe92f2f8fd79ca9cc626a7be02ba8673d0ad0ec5911cc03ce58eed682
|
data/README.md
CHANGED
@@ -65,7 +65,7 @@ client.auth_token = "corge"
|
|
65
65
|
|
66
66
|
Once you have a client with valid credentials, you should be able to make requests to the API. Clients map operation names in a flat structure. Methods have positional arguments for required input and keyword arguments for optional parameters. Both method and argument names are underscored but otherwise identical to the names of the corresponding operations and parameters documented in the API.
|
67
67
|
|
68
|
-
Peddler wraps successful responses in a parser that handles both XML documents and flat files
|
68
|
+
Peddler wraps successful responses in a parser that handles both XML documents and flat files:
|
69
69
|
|
70
70
|
```ruby
|
71
71
|
parser = client.get_service_status
|
data/lib/peddler/client.rb
CHANGED
@@ -66,12 +66,14 @@ module Peddler
|
|
66
66
|
private
|
67
67
|
|
68
68
|
def inherited(base)
|
69
|
+
base.parser = parser
|
70
|
+
base.path(path)
|
69
71
|
base.params(params)
|
70
72
|
base.on_error(&@error_handler)
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
74
|
-
@error_handler =
|
76
|
+
@error_handler = proc { fail }
|
75
77
|
|
76
78
|
# Creates a new client instance
|
77
79
|
#
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Peddler
|
2
|
+
class VCRMatcher
|
3
|
+
TRANSIENT_PARAMS = %w(
|
4
|
+
Signature Timestamp StartDate CreatedAfter QueryStartDateTime
|
5
|
+
)
|
6
|
+
|
7
|
+
SELLER_PARAMS = %w(
|
8
|
+
AWSAccessKeyId SellerId
|
9
|
+
)
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def call(*requests)
|
13
|
+
new(*requests).compare
|
14
|
+
end
|
15
|
+
|
16
|
+
def ignored_params
|
17
|
+
@ignored_params ||= TRANSIENT_PARAMS
|
18
|
+
end
|
19
|
+
|
20
|
+
def ignore_seller!
|
21
|
+
ignored_params.concat(SELLER_PARAMS)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :requests
|
26
|
+
|
27
|
+
def initialize(*requests)
|
28
|
+
@requests = requests
|
29
|
+
end
|
30
|
+
|
31
|
+
def compare
|
32
|
+
compare_uris && compare_bodies
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def compare_uris
|
38
|
+
return false if hosts.reduce(:!=) || paths.reduce(:!=)
|
39
|
+
return true if queries.all?(&:empty?)
|
40
|
+
|
41
|
+
queries.reduce(:==)
|
42
|
+
end
|
43
|
+
|
44
|
+
def compare_bodies
|
45
|
+
bodies.reduce(:==)
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_params(string)
|
49
|
+
return {} unless string
|
50
|
+
|
51
|
+
params = ::CGI.parse(string)
|
52
|
+
self.class.ignored_params.each do |k|
|
53
|
+
params.delete(k)
|
54
|
+
end
|
55
|
+
|
56
|
+
params
|
57
|
+
end
|
58
|
+
|
59
|
+
def uris
|
60
|
+
requests.map { |r| URI.parse(r.uri) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def hosts
|
64
|
+
uris.map(&:host)
|
65
|
+
end
|
66
|
+
|
67
|
+
def paths
|
68
|
+
uris.map(&:path)
|
69
|
+
end
|
70
|
+
|
71
|
+
def queries
|
72
|
+
uris.map { |uri| extract_params(uri.query) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def bodies
|
76
|
+
if queries.all?(&:empty?)
|
77
|
+
requests.map { |request| extract_params(request.body) }
|
78
|
+
else
|
79
|
+
requests.map(&:body)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/peddler/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'simplecov'
|
2
2
|
require 'coveralls'
|
3
|
-
require 'peddler/
|
3
|
+
require 'peddler/vcr_matcher'
|
4
4
|
|
5
5
|
SimpleCov.formatters = [
|
6
6
|
SimpleCov::Formatter::HTMLFormatter,
|
@@ -40,28 +40,31 @@ module Accounts
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
44
|
-
|
43
|
+
# Bootstraps VCR
|
44
|
+
module Recorder
|
45
45
|
def setup
|
46
|
-
ENV['LIVE'] ? VCR.turn_off! : VCR.insert_cassette(
|
46
|
+
ENV['LIVE'] ? VCR.turn_off! : VCR.insert_cassette(test_name)
|
47
47
|
end
|
48
48
|
|
49
49
|
def teardown
|
50
50
|
VCR.eject_cassette if VCR.turned_on?
|
51
51
|
end
|
52
52
|
|
53
|
+
def test_name
|
54
|
+
self.class.name.sub('Test', '')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Sets up clients for integration testing
|
59
|
+
class IntegrationTest < MiniTest::Test
|
60
|
+
include Recorder
|
61
|
+
|
53
62
|
def clients
|
54
63
|
Accounts.map do |account|
|
55
|
-
klass = MWS.const_get("#{
|
64
|
+
klass = MWS.const_get("#{test_name}::Client")
|
56
65
|
klass.new(account)
|
57
66
|
end
|
58
67
|
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def api
|
63
|
-
self.class.name.sub('Test', '')
|
64
|
-
end
|
65
68
|
end
|
66
69
|
|
67
70
|
VCR.configure do |c|
|
@@ -74,7 +77,7 @@ VCR.configure do |c|
|
|
74
77
|
interaction.ignore! if code >= 400 && code != 414
|
75
78
|
end
|
76
79
|
c.default_cassette_options = {
|
77
|
-
match_requests_on: [::Peddler::
|
80
|
+
match_requests_on: [::Peddler::VCRMatcher],
|
78
81
|
record: !ENV['RECORD'] ? :none : :new_episodes
|
79
82
|
}
|
80
83
|
|
data/test/null_client.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'peddler/client'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
::Peddler::VCRMatcher.ignore_seller!
|
5
|
+
|
6
|
+
module Null
|
7
|
+
class Client < ::Peddler::Client
|
8
|
+
def configure_with_mock_data!
|
9
|
+
self.aws_access_key_id = SecureRandom.hex
|
10
|
+
self.aws_secret_access_key = SecureRandom.hex
|
11
|
+
self.merchant_id = SecureRandom.hex
|
12
|
+
self.primary_marketplace_id = 'ATVPDKIKX0DER'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Parser
|
17
|
+
def self.new(res, *)
|
18
|
+
res
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Client.parser = Parser
|
23
|
+
end
|
@@ -1,26 +1,15 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require '
|
3
|
-
require 'peddler/client'
|
2
|
+
require 'null_client'
|
4
3
|
|
5
4
|
class TestPeddlerClient < MiniTest::Test
|
6
|
-
module Parser
|
7
|
-
def self.new(res, *)
|
8
|
-
res
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
5
|
def setup
|
13
6
|
@body = 'foo'
|
14
7
|
Excon.defaults[:mock] = true
|
15
8
|
Excon.stub({}, body: @body, status: 200)
|
16
9
|
|
17
|
-
@klass = Class.new(
|
18
|
-
@klass.parser = Parser
|
10
|
+
@klass = Class.new(Null::Client)
|
19
11
|
@client = @klass.new
|
20
|
-
@client.
|
21
|
-
@client.aws_secret_access_key = 'secret'
|
22
|
-
@client.merchant_id = 'seller'
|
23
|
-
@client.primary_marketplace_id = 'ATVPDKIKX0DER' # US
|
12
|
+
@client.configure_with_mock_data!
|
24
13
|
@client.operation('Foo')
|
25
14
|
end
|
26
15
|
|
@@ -53,6 +42,14 @@ class TestPeddlerClient < MiniTest::Test
|
|
53
42
|
assert_equal Peddler::Client.params, @klass.params
|
54
43
|
end
|
55
44
|
|
45
|
+
def test_inherits_parents_path
|
46
|
+
assert_equal @klass.path, Class.new(@klass).path
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_inherits_parents_parser
|
50
|
+
assert_equal @klass.parser, Class.new(@klass).parser
|
51
|
+
end
|
52
|
+
|
56
53
|
def test_params_include_seller_id
|
57
54
|
assert @klass.params.key?("SellerId")
|
58
55
|
end
|
@@ -174,13 +171,9 @@ class TestPeddlerClient < MiniTest::Test
|
|
174
171
|
end
|
175
172
|
@client.run # no longer raises
|
176
173
|
|
177
|
-
klass = Class.new(
|
178
|
-
klass.parser = Parser
|
174
|
+
klass = Class.new(Null::Client)
|
179
175
|
other_client = klass.new
|
180
|
-
other_client.
|
181
|
-
other_client.aws_secret_access_key = 'secret'
|
182
|
-
other_client.merchant_id = 'seller'
|
183
|
-
other_client.primary_marketplace_id = 'ATVPDKIKX0DER' # US
|
176
|
+
other_client.configure_with_mock_data!
|
184
177
|
other_client.operation('Foo')
|
185
178
|
assert_raises(Excon::Errors::ServiceUnavailable) do
|
186
179
|
other_client.run
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'null_client'
|
3
|
+
require 'peddler/vcr_matcher'
|
4
|
+
|
5
|
+
class TestPeddlerVCRMatcher < MiniTest::Test
|
6
|
+
include Recorder
|
7
|
+
|
8
|
+
def test_matches_recorded_post_without_body
|
9
|
+
client.run
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_wont_match_unrecorded_post_without_body
|
13
|
+
client.operation.add(foo: 'bar')
|
14
|
+
assert_raises(VCR::Errors::UnhandledHTTPRequestError) do
|
15
|
+
client.run
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_matches_recorded_post_with_body
|
20
|
+
client.body = "content"
|
21
|
+
client.run
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_wont_match_unrecorded_post_with_different_query_and_same_body
|
25
|
+
client.operation.add(foo: 'bar')
|
26
|
+
client.body = "content"
|
27
|
+
assert_raises(VCR::Errors::UnhandledHTTPRequestError) do
|
28
|
+
client.run
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_wont_match_unrecorded_post_with_same_query_and_different_body
|
33
|
+
client.body = "other content"
|
34
|
+
assert_raises(VCR::Errors::UnhandledHTTPRequestError) do
|
35
|
+
client.run
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def client
|
40
|
+
@client ||= begin
|
41
|
+
client = Class.new(Null::Client).new
|
42
|
+
client.configure_with_mock_data!
|
43
|
+
client.operation('Action')
|
44
|
+
client
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://mws.amazonservices.com/
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: AWSAccessKeyId=123&Action=Action&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-01-06T18%3A21%3A12Z&Signature=123
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Jeff/1.5.1 (Language=Ruby; Hakans-MacBook-Pro.local)
|
12
|
+
response:
|
13
|
+
status:
|
14
|
+
code: 200
|
15
|
+
message:
|
16
|
+
headers: {}
|
17
|
+
body:
|
18
|
+
encoding: UTF-8
|
19
|
+
string: OK
|
20
|
+
http_version:
|
21
|
+
recorded_at: Sat, 28 Mar 2015 18:10:18 GMT
|
22
|
+
- request:
|
23
|
+
method: post
|
24
|
+
uri: https://mws.amazonservices.com/?AWSAccessKeyId=123&Action=Action&SellerId=123&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-01-06T18%3A53%3A50Z&Signature=123
|
25
|
+
body:
|
26
|
+
encoding: US-ASCII
|
27
|
+
string: content
|
28
|
+
headers:
|
29
|
+
User-Agent:
|
30
|
+
- Jeff/1.5.1 (Language=Ruby; Hakans-MacBook-Pro.local)
|
31
|
+
response:
|
32
|
+
status:
|
33
|
+
code: 200
|
34
|
+
message:
|
35
|
+
headers: {}
|
36
|
+
body:
|
37
|
+
encoding: UTF-8
|
38
|
+
string: OK
|
39
|
+
http_version:
|
40
|
+
recorded_at: Sat, 28 Mar 2015 18:10:18 GMT
|
41
|
+
recorded_with: VCR 3.0.1
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peddler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jeff
|
@@ -86,7 +86,7 @@ files:
|
|
86
86
|
- lib/peddler/operation.rb
|
87
87
|
- lib/peddler/parser.rb
|
88
88
|
- lib/peddler/structured_list.rb
|
89
|
-
- lib/peddler/
|
89
|
+
- lib/peddler/vcr_matcher.rb
|
90
90
|
- lib/peddler/version.rb
|
91
91
|
- lib/peddler/xml_parser.rb
|
92
92
|
- lib/peddler/xml_response_parser.rb
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- test/integration/test_webstore.rb
|
108
108
|
- test/mws.yml
|
109
109
|
- test/mws.yml.example
|
110
|
+
- test/null_client.rb
|
110
111
|
- test/unit/mws/test_cart_information_client.rb
|
111
112
|
- test/unit/mws/test_customer_information_client.rb
|
112
113
|
- test/unit/mws/test_feeds_client.rb
|
@@ -129,6 +130,7 @@ files:
|
|
129
130
|
- test/unit/peddler/test_operation.rb
|
130
131
|
- test/unit/peddler/test_parser.rb
|
131
132
|
- test/unit/peddler/test_structured_list.rb
|
133
|
+
- test/unit/peddler/test_vcr_matcher.rb
|
132
134
|
- test/unit/peddler/test_xml_parser.rb
|
133
135
|
- test/unit/peddler/test_xml_response_parser.rb
|
134
136
|
- test/unit/test_mws.rb
|
@@ -140,6 +142,7 @@ files:
|
|
140
142
|
- test/vcr_cassettes/FulfillmentOutboundShipment.yml
|
141
143
|
- test/vcr_cassettes/OffAmazonPayments.yml
|
142
144
|
- test/vcr_cassettes/Orders.yml
|
145
|
+
- test/vcr_cassettes/PeddlerVCRMatcher.yml
|
143
146
|
- test/vcr_cassettes/Products.yml
|
144
147
|
- test/vcr_cassettes/Recommendations.yml
|
145
148
|
- test/vcr_cassettes/Reports.yml
|
@@ -166,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
169
|
version: '0'
|
167
170
|
requirements: []
|
168
171
|
rubyforge_project:
|
169
|
-
rubygems_version: 2.
|
172
|
+
rubygems_version: 2.5.1
|
170
173
|
signing_key:
|
171
174
|
specification_version: 4
|
172
175
|
summary: Wraps the Amazon MWS APIs
|
@@ -188,6 +191,7 @@ test_files:
|
|
188
191
|
- test/integration/test_webstore.rb
|
189
192
|
- test/mws.yml
|
190
193
|
- test/mws.yml.example
|
194
|
+
- test/null_client.rb
|
191
195
|
- test/unit/mws/test_cart_information_client.rb
|
192
196
|
- test/unit/mws/test_customer_information_client.rb
|
193
197
|
- test/unit/mws/test_feeds_client.rb
|
@@ -210,6 +214,7 @@ test_files:
|
|
210
214
|
- test/unit/peddler/test_operation.rb
|
211
215
|
- test/unit/peddler/test_parser.rb
|
212
216
|
- test/unit/peddler/test_structured_list.rb
|
217
|
+
- test/unit/peddler/test_vcr_matcher.rb
|
213
218
|
- test/unit/peddler/test_xml_parser.rb
|
214
219
|
- test/unit/peddler/test_xml_response_parser.rb
|
215
220
|
- test/unit/test_mws.rb
|
@@ -221,6 +226,7 @@ test_files:
|
|
221
226
|
- test/vcr_cassettes/FulfillmentOutboundShipment.yml
|
222
227
|
- test/vcr_cassettes/OffAmazonPayments.yml
|
223
228
|
- test/vcr_cassettes/Orders.yml
|
229
|
+
- test/vcr_cassettes/PeddlerVCRMatcher.yml
|
224
230
|
- test/vcr_cassettes/Products.yml
|
225
231
|
- test/vcr_cassettes/Recommendations.yml
|
226
232
|
- test/vcr_cassettes/Reports.yml
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Peddler
|
2
|
-
module Test
|
3
|
-
class VCRMatcher
|
4
|
-
TRANSIENT_PARAMS = %w( AWSAccessKeyId SellerId Signature Timestamp
|
5
|
-
StartDate CreatedAfter QueryStartDateTime ).freeze
|
6
|
-
|
7
|
-
attr_reader :req_1, :req_2
|
8
|
-
|
9
|
-
def self.call(req_1, req_2)
|
10
|
-
new(req_1, req_2).compare
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(req_1, req_2)
|
14
|
-
@req_1 = req_1
|
15
|
-
@req_2 = req_2
|
16
|
-
end
|
17
|
-
|
18
|
-
def compare
|
19
|
-
compare_uri && compare_body
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def compare_uri
|
25
|
-
uri_1 = URI.parse(req_1.uri)
|
26
|
-
uri_2 = URI.parse(req_2.uri)
|
27
|
-
|
28
|
-
uri_1.host == uri_2.host &&
|
29
|
-
uri_1.path == uri_2.path &&
|
30
|
-
extract_params(uri_1.query) == extract_params(uri_2.query)
|
31
|
-
end
|
32
|
-
|
33
|
-
def compare_body
|
34
|
-
extract_params(req_1.body) == extract_params(req_2.body)
|
35
|
-
end
|
36
|
-
|
37
|
-
def extract_params(string)
|
38
|
-
return {} unless string
|
39
|
-
|
40
|
-
params = ::CGI.parse(string)
|
41
|
-
TRANSIENT_PARAMS.each do |k|
|
42
|
-
params.delete(k)
|
43
|
-
end
|
44
|
-
|
45
|
-
params
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|