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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ebc3731112b872c4fd188f5f2a670906d306deb
4
- data.tar.gz: 6dd3f8389d2ab5837fd6a614da7f005fc74f35f9
3
+ metadata.gz: d7eb80f7f028b5464f42c29cb72ce60e2eda123d
4
+ data.tar.gz: 8a814e73f8695da5b01b0e14d62732beec970cd6
5
5
  SHA512:
6
- metadata.gz: bb1753e3b07215bc3749d7a49cca3441d7149b61bb1b76f024b0d938553c9a30d90129cfa785ad831b243637b6c4a32c79c1c4b1a72d24ab15b449baa0d92e61
7
- data.tar.gz: d08981d7ee8b42ab481983ae999671619517be7d7e0df8e23c17731a62bbca01001c167943845cbcc8705e645c5527d2619f2b5aa030af4fec37625e0cc3c5ee
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
@@ -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 = ->(e) { fail e }
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
@@ -1,3 +1,3 @@
1
1
  module Peddler
2
- VERSION = '1.1.1'
2
+ VERSION = '1.2.0'
3
3
  end
data/test/helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'simplecov'
2
2
  require 'coveralls'
3
- require 'peddler/test/vcr_matcher'
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
- # Sets up clients and bootstraps VCR for integration tests
44
- class IntegrationTest < MiniTest::Test
43
+ # Bootstraps VCR
44
+ module Recorder
45
45
  def setup
46
- ENV['LIVE'] ? VCR.turn_off! : VCR.insert_cassette(api)
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("#{api}::Client")
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::Test::VCRMatcher],
80
+ match_requests_on: [::Peddler::VCRMatcher],
78
81
  record: !ENV['RECORD'] ? :none : :new_episodes
79
82
  }
80
83
 
@@ -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 'excon'
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(Peddler::Client)
18
- @klass.parser = Parser
10
+ @klass = Class.new(Null::Client)
19
11
  @client = @klass.new
20
- @client.aws_access_key_id = 'key'
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(Peddler::Client)
178
- klass.parser = Parser
174
+ klass = Class.new(Null::Client)
179
175
  other_client = klass.new
180
- other_client.aws_access_key_id = 'key'
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.1.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: 2015-12-27 00:00:00.000000000 Z
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/test/vcr_matcher.rb
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.4.5.1
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