peddler 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -28
  3. data/lib/mws.rb +2 -0
  4. data/lib/mws/cart_information/client.rb +7 -6
  5. data/lib/mws/customer_information/client.rb +6 -6
  6. data/lib/mws/feeds/client.rb +8 -8
  7. data/lib/mws/finances/client.rb +6 -6
  8. data/lib/mws/fulfillment_inbound_shipment/client.rb +41 -40
  9. data/lib/mws/fulfillment_inventory/client.rb +3 -3
  10. data/lib/mws/fulfillment_outbound_shipment/client.rb +18 -18
  11. data/lib/mws/merchant_fulfillment.rb +1 -0
  12. data/lib/mws/merchant_fulfillment/client.rb +88 -0
  13. data/lib/mws/off_amazon_payments/client.rb +203 -202
  14. data/lib/mws/orders/client.rb +6 -6
  15. data/lib/mws/products/client.rb +38 -38
  16. data/lib/mws/recommendations/client.rb +4 -4
  17. data/lib/mws/reports/client.rb +19 -17
  18. data/lib/mws/sellers/client.rb +2 -2
  19. data/lib/mws/subscriptions/client.rb +22 -22
  20. data/lib/mws/webstore/client.rb +8 -8
  21. data/lib/peddler/client.rb +7 -7
  22. data/lib/peddler/flat_file_parser.rb +1 -1
  23. data/lib/peddler/marketplace.rb +2 -2
  24. data/lib/peddler/operation.rb +7 -12
  25. data/lib/peddler/vcr_matcher.rb +5 -3
  26. data/lib/peddler/version.rb +2 -1
  27. data/test/helper.rb +11 -2
  28. data/test/integration/test_fulfillment_inbound_shipment.rb +1 -1
  29. data/test/integration/test_merchant_fulfillment.rb +11 -0
  30. data/test/integration/test_orders.rb +20 -0
  31. data/test/unit/mws/test_merchant_fulfillment_client.rb +83 -0
  32. data/test/unit/peddler/test_client.rb +12 -10
  33. data/test/unit/peddler/test_vcr_matcher.rb +3 -3
  34. data/test/vcr_cassettes/MerchantFulfillment.yml +195 -0
  35. data/test/vcr_cassettes/Orders.yml +1902 -5
  36. metadata +10 -2
@@ -13,7 +13,7 @@ module MWS
13
13
  # that your Webstore tracks, can help you determine how many notifications
14
14
  # were converted into sales.
15
15
  class Client < ::Peddler::Client
16
- version "2014-09-01"
16
+ version '2014-09-01'
17
17
  path "/Webstore/#{version}/"
18
18
 
19
19
  # Lists subscription counts of subscriptions in a specified state,
@@ -21,8 +21,8 @@ module MWS
21
21
  #
22
22
  # @see http://docs.developer.amazonservices.com/en_US/webstore/Webstore_ListSubscriptionsCount.html
23
23
  # @overload list_subscriptions_count(subscription_state, opts = { marketplace_id: primary_marketplace_id })
24
- # @param subscription_state [String]
25
- # @param opts [Hash]
24
+ # @param [String] subscription_state
25
+ # @param [Hash] opts
26
26
  # @option opts [String] :marketplace_id
27
27
  # @option opts [String, #iso8601] :date_range_start
28
28
  # @option opts [String, #iso8601] :date_range_end
@@ -43,7 +43,7 @@ module MWS
43
43
  # Lists the next page of subscription counts
44
44
  #
45
45
  # @see http://docs.developer.amazonservices.com/en_US/webstore/Webstore_ListSubscriptionsCountByNextToken.html
46
- # @param next_token [String]
46
+ # @param [String] next_token
47
47
  # @return [Peddler::XMLParser]
48
48
  def list_subscriptions_count_by_next_token(next_token)
49
49
  operation('ListSubscriptionsCountByNextToken')
@@ -57,10 +57,10 @@ module MWS
57
57
  #
58
58
  # @see http://docs.developer.amazonservices.com/en_US/webstore/Webstore_ListSubscriptionsCount.html
59
59
  # @overload get_subscription_details(seller_sku, subscription_state, date_range_start, opts = { marketplace_id: marketplace_id })
60
- # @param seller_sku [String]
61
- # @param subscription_state [String]
62
- # @param date_range_start [String, #iso8601]
63
- # @param opts [Hash]
60
+ # @param [String] seller_sku
61
+ # @param [String] subscription_state
62
+ # @param [String, #iso8601] date_range_start
63
+ # @param [Hash] opts
64
64
  # @option opts [String] :marketplace_id
65
65
  # @option opts [String, #iso8601] :date_range_end
66
66
  # @return [Peddler::XMLParser]
@@ -25,7 +25,7 @@ module Peddler
25
25
  # @return [String]
26
26
  attr_reader :body
27
27
 
28
- alias_method :configure, :tap
28
+ alias configure tap
29
29
 
30
30
  def_delegators :marketplace, :host, :encoding
31
31
 
@@ -57,8 +57,8 @@ module Peddler
57
57
  end
58
58
 
59
59
  # Sets an error handler
60
- # @yieldparam request [Excon::Request]
61
- # @yieldparam response [Excon::Response]
60
+ # @yieldparam [Excon::Request] request
61
+ # @yieldparam [Excon::Response] response
62
62
  def on_error(&blk)
63
63
  @error_handler = blk
64
64
  end
@@ -77,7 +77,7 @@ module Peddler
77
77
 
78
78
  # Creates a new client instance
79
79
  #
80
- # @param opts [Hash]
80
+ # @param [Hash] opts
81
81
  # @option opts [String] :primary_marketplace_id
82
82
  # @option opts [String] :merchant_id
83
83
  # @option opts [String] :aws_access_key_id
@@ -155,8 +155,8 @@ module Peddler
155
155
  end
156
156
 
157
157
  # Sets an error handler
158
- # @yieldparam request [Excon::Request]
159
- # @yieldparam response [Excon::Response]
158
+ # @yieldparam [Excon::Request] request
159
+ # @yieldparam [Excon::Response] response
160
160
  def on_error(&blk)
161
161
  @error_handler = blk
162
162
  end
@@ -224,7 +224,7 @@ module Peddler
224
224
 
225
225
  def deprecate_error_handler_arguments(e)
226
226
  if error_handler.parameters.size == 2
227
- warn "[DEPRECATION] Error handler now expects exception as argument."
227
+ warn '[DEPRECATION] Error handler now expects exception as argument.'
228
228
  [e.request, e.response]
229
229
  else
230
230
  [e]
@@ -6,7 +6,7 @@ module Peddler
6
6
  # @api private
7
7
  class FlatFileParser < SimpleDelegator
8
8
  # http://stackoverflow.com/questions/8073920/importing-csv-quoting-error-is-driving-me-nuts
9
- OPTIONS = { col_sep: "\t", quote_char: "\x00", headers: true }
9
+ OPTIONS = { col_sep: "\t", quote_char: "\x00", headers: true }.freeze
10
10
 
11
11
  attr_reader :content, :summary, :encoding
12
12
 
@@ -13,14 +13,14 @@ module Peddler
13
13
  'A1VC38T7YXB528' => 'mws.amazonservices.jp',
14
14
  'A1AM78C64UM0Y8' => 'mws.amazonservices.com.mx',
15
15
  'ATVPDKIKX0DER' => 'mws.amazonservices.com'
16
- }
16
+ }.freeze
17
17
 
18
18
  BadId = Class.new(StandardError)
19
19
 
20
20
  attr_reader :id
21
21
 
22
22
  def initialize(id)
23
- @id = id or fail BadId, 'missing MarketplaceId'
23
+ @id = id || fail(BadId, 'missing MarketplaceId')
24
24
  end
25
25
 
26
26
  def host
@@ -21,20 +21,15 @@ module Peddler
21
21
  self
22
22
  end
23
23
 
24
- def store(key, val)
24
+ def store(key, val, parent: '')
25
25
  key = camelize(key) if key.is_a?(Symbol)
26
+ key = "#{parent}.#{key}" unless parent.empty?
26
27
 
27
- if val.respond_to?(:iso8601)
28
- val = val.iso8601
29
- elsif val.is_a?(Struct)
30
- val = val.to_h
31
- end
28
+ val = val.iso8601 if val.respond_to?(:iso8601)
29
+ val = val.to_h if val.is_a?(Struct)
32
30
 
33
31
  if val.is_a?(Hash)
34
- val.each do |subkey, subval|
35
- subkey = camelize(subkey) if subkey.is_a?(Symbol)
36
- store([key, subkey].join('.'), subval)
37
- end
32
+ val.each { |keyval| store(*keyval, parent: key) }
38
33
  else
39
34
  __getobj__.store(key, val)
40
35
  end
@@ -45,7 +40,7 @@ module Peddler
45
40
  self
46
41
  end
47
42
 
48
- alias_method :add, :update
43
+ alias add update
49
44
 
50
45
  private
51
46
 
@@ -53,7 +48,7 @@ module Peddler
53
48
  sym
54
49
  .to_s
55
50
  .split('_')
56
- .map { |token| token == "sku" ? "SKU" : token.capitalize }
51
+ .map { |token| token == 'sku' ? 'SKU' : token.capitalize }
57
52
  .join
58
53
  end
59
54
  end
@@ -1,12 +1,14 @@
1
1
  module Peddler
2
+ # A custom matcher that can be used to record MWS interactions when
3
+ # integration-testing
2
4
  class VCRMatcher
3
5
  TRANSIENT_PARAMS = %w(
4
6
  Signature Timestamp StartDate CreatedAfter QueryStartDateTime
5
- )
7
+ ).freeze
6
8
 
7
9
  SELLER_PARAMS = %w(
8
10
  AWSAccessKeyId SellerId
9
- )
11
+ ).freeze
10
12
 
11
13
  class << self
12
14
  def call(*requests)
@@ -14,7 +16,7 @@ module Peddler
14
16
  end
15
17
 
16
18
  def ignored_params
17
- @ignored_params ||= TRANSIENT_PARAMS
19
+ @ignored_params ||= TRANSIENT_PARAMS.dup
18
20
  end
19
21
 
20
22
  def ignore_seller!
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Peddler
2
- VERSION = '1.2.0'
3
+ VERSION = '1.3.0'.freeze
3
4
  end
@@ -1,6 +1,5 @@
1
1
  require 'simplecov'
2
2
  require 'coveralls'
3
- require 'peddler/vcr_matcher'
4
3
 
5
4
  SimpleCov.formatters = [
6
5
  SimpleCov::Formatter::HTMLFormatter,
@@ -9,10 +8,11 @@ SimpleCov.formatters = [
9
8
 
10
9
  SimpleCov.start do
11
10
  add_filter '/test/'
12
- minimum_coverage(99.62)
13
11
  end
14
12
 
13
+ require 'dig_rb'
15
14
  require 'minitest/autorun'
15
+ require 'peddler/vcr_matcher'
16
16
  require 'yaml'
17
17
  require 'vcr'
18
18
  begin
@@ -71,6 +71,8 @@ VCR.configure do |c|
71
71
  c.hook_into :excon
72
72
  c.cassette_library_dir = 'test/vcr_cassettes'
73
73
 
74
+ ::Peddler::VCRMatcher.ignore_seller!
75
+
74
76
  # HTTP errors are not Peddler's concern, so ignore them to ease development.
75
77
  c.before_record do |interaction|
76
78
  code = interaction.response.status.code
@@ -85,5 +87,12 @@ VCR.configure do |c|
85
87
  Accounts.each do |account|
86
88
  c.filter_sensitive_data('MERCHANT_ID') { account['merchant_id'] }
87
89
  c.filter_sensitive_data('AWS_ACCESS_KEY_ID') { account['aws_access_key_id'] }
90
+ c.before_record do |interaction|
91
+ %w(
92
+ BuyerName BuyerEmail Name AddressLine1 PostalCode Phone Amount
93
+ ).each do |key|
94
+ interaction.response.body.gsub!(/<#{key}>[^<]+</, "<#{key}>FILTERED<")
95
+ end
96
+ end
88
97
  end
89
98
  end
@@ -24,7 +24,7 @@ class TestFulfillmentInboundShipment < IntegrationTest
24
24
 
25
25
  def test_handles_large_requests
26
26
  address = Address.new('John', '1 Main St', 'New York', 'NY', '10001', 'US')
27
- items = 100.times.map { |count| Item.new(count, 1) }
27
+ items = Array.new(100) { |i| Item.new(i, 1) }
28
28
  clients.each do |client|
29
29
  res = client.create_inbound_shipment_plan(address, items)
30
30
  assert_equal 200, res.status
@@ -0,0 +1,11 @@
1
+ require 'helper'
2
+ require 'mws/merchant_fulfillment'
3
+
4
+ class TestMerchantFulfillment < IntegrationTest
5
+ def test_gets_service_status
6
+ clients.each do |client|
7
+ res = client.get_service_status
8
+ refute_empty res.parse
9
+ end
10
+ end
11
+ end
@@ -2,6 +2,26 @@ require 'helper'
2
2
  require 'mws/orders'
3
3
 
4
4
  class TestOrders < IntegrationTest
5
+ def test_gets_orders
6
+ clients.each do |client|
7
+ order_ids = client
8
+ .list_orders(
9
+ created_after: Date.new(2015),
10
+ max_results_per_page: 5
11
+ )
12
+ .parse
13
+ .dig('Orders', 'Order')
14
+ .map { |order| order['AmazonOrderId'] }
15
+
16
+ orders = client
17
+ .get_order(*order_ids)
18
+ .parse
19
+ .dig('Orders', 'Order')
20
+
21
+ assert_equal order_ids.count, orders.count
22
+ end
23
+ end
24
+
5
25
  def test_gets_service_status
6
26
  clients.each do |client|
7
27
  res = client.get_service_status
@@ -0,0 +1,83 @@
1
+ require 'helper'
2
+ require 'mws/merchant_fulfillment/client'
3
+
4
+ class TestMWSMerchantFulfillmentClient < MiniTest::Test
5
+ def setup
6
+ @client = MWS::MerchantFulfillment::Client.new
7
+ end
8
+
9
+ def test_gets_eligible_shipping_services
10
+ operation = {
11
+ 'Action' => 'GetEligibleShippingServices',
12
+ 'ShipmentRequestDetails.Id' => '123',
13
+ 'ShipmentRequestDetails.Foo.Bar' => 'baz'
14
+ }
15
+
16
+ @client.stub(:run, nil) do
17
+ shipment_request_details = {
18
+ id: '123',
19
+ foo: { bar: 'baz' }
20
+ }
21
+ @client.get_eligible_shipping_services(shipment_request_details)
22
+ end
23
+
24
+ assert_equal operation, @client.operation
25
+ end
26
+
27
+ def test_creates_shipment
28
+ operation = {
29
+ 'Action' => 'CreateShipment',
30
+ 'ShipmentRequestDetails.Id' => '123',
31
+ 'ShipmentRequestDetails.Foo.Bar' => 'baz',
32
+ 'ShippingServiceId' => 'FOO'
33
+ }
34
+
35
+ @client.stub(:run, nil) do
36
+ shipment_request_details = {
37
+ id: '123',
38
+ foo: { bar: 'baz' }
39
+ }
40
+ @client.create_shipment(shipment_request_details, 'FOO')
41
+ end
42
+
43
+ assert_equal operation, @client.operation
44
+ end
45
+
46
+ def test_gets_shipment
47
+ operation = {
48
+ 'Action' => 'GetShipment',
49
+ 'ShipmentId' => '123'
50
+ }
51
+
52
+ @client.stub(:run, nil) do
53
+ @client.get_shipment('123')
54
+ end
55
+
56
+ assert_equal operation, @client.operation
57
+ end
58
+
59
+ def test_cancels_shipment
60
+ operation = {
61
+ 'Action' => 'CancelShipment',
62
+ 'ShipmentId' => '123'
63
+ }
64
+
65
+ @client.stub(:run, nil) do
66
+ @client.cancel_shipment('123')
67
+ end
68
+
69
+ assert_equal operation, @client.operation
70
+ end
71
+
72
+ def test_gets_service_status
73
+ operation = {
74
+ 'Action' => 'GetServiceStatus'
75
+ }
76
+
77
+ @client.stub(:run, nil) do
78
+ @client.get_service_status
79
+ end
80
+
81
+ assert_equal operation, @client.operation
82
+ end
83
+ end
@@ -51,11 +51,11 @@ class TestPeddlerClient < MiniTest::Test
51
51
  end
52
52
 
53
53
  def test_params_include_seller_id
54
- assert @klass.params.key?("SellerId")
54
+ assert @klass.params.key?('SellerId')
55
55
  end
56
56
 
57
57
  def test_params_include_auth_token
58
- @klass.params.key?("MWSAuthToken")
58
+ @klass.params.key?('MWSAuthToken')
59
59
  end
60
60
 
61
61
  def test_configures
@@ -114,9 +114,8 @@ class TestPeddlerClient < MiniTest::Test
114
114
  assert_equal @body, chunks
115
115
  end
116
116
 
117
- def test_request_preserves_user_agent
118
- instrumentor = Class.new
119
- class << instrumentor
117
+ class Instrumentor
118
+ class << self
120
119
  attr_accessor :events
121
120
 
122
121
  def instrument(name, params = {})
@@ -124,11 +123,14 @@ class TestPeddlerClient < MiniTest::Test
124
123
  yield if block_given?
125
124
  end
126
125
  end
127
- instrumentor.events = {}
128
126
 
129
- @client.defaults.update(instrumentor: instrumentor)
127
+ @events = {}
128
+ end
129
+
130
+ def test_request_preserves_user_agent
131
+ @client.defaults.update(instrumentor: Instrumentor)
130
132
  @client.run
131
- headers = instrumentor.events['excon.request'][:headers]
133
+ headers = Instrumentor.events['excon.request'][:headers]
132
134
 
133
135
  assert headers.key?('User-Agent')
134
136
  end
@@ -214,8 +216,8 @@ class TestPeddlerClient < MiniTest::Test
214
216
 
215
217
  def test_deprecated_marketplace_id_accessor
216
218
  refute_nil @client.marketplace_id
217
- @client.marketplace_id = "123"
218
- assert_equal "123", @client.marketplace_id
219
+ @client.marketplace_id = '123'
220
+ assert_equal '123', @client.marketplace_id
219
221
  assert_equal @client.primary_marketplace_id, @client.marketplace_id
220
222
  end
221
223
  end
@@ -17,20 +17,20 @@ class TestPeddlerVCRMatcher < MiniTest::Test
17
17
  end
18
18
 
19
19
  def test_matches_recorded_post_with_body
20
- client.body = "content"
20
+ client.body = 'content'
21
21
  client.run
22
22
  end
23
23
 
24
24
  def test_wont_match_unrecorded_post_with_different_query_and_same_body
25
25
  client.operation.add(foo: 'bar')
26
- client.body = "content"
26
+ client.body = 'content'
27
27
  assert_raises(VCR::Errors::UnhandledHTTPRequestError) do
28
28
  client.run
29
29
  end
30
30
  end
31
31
 
32
32
  def test_wont_match_unrecorded_post_with_same_query_and_different_body
33
- client.body = "other content"
33
+ client.body = 'other content'
34
34
  assert_raises(VCR::Errors::UnhandledHTTPRequestError) do
35
35
  client.run
36
36
  end