peddler 1.3.0 → 1.4.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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -22
  3. data/lib/mws/fulfillment_outbound_shipment/client.rb +12 -5
  4. data/lib/mws/merchant_fulfillment/client.rb +2 -2
  5. data/lib/mws/orders/client.rb +9 -1
  6. data/lib/mws/products/client.rb +14 -1
  7. data/lib/mws/reports/client.rb +1 -1
  8. data/lib/mws.rb +0 -3
  9. data/lib/peddler/client.rb +12 -19
  10. data/lib/peddler/errors/builder.rb +20 -0
  11. data/lib/peddler/errors/error.rb +13 -0
  12. data/lib/peddler/errors/handler.rb +45 -0
  13. data/lib/peddler/errors/parser.rb +28 -0
  14. data/lib/peddler/flat_file_parser.rb +1 -1
  15. data/lib/peddler/marketplace.rb +2 -2
  16. data/lib/peddler/parser.rb +0 -1
  17. data/lib/peddler/structured_list.rb +1 -0
  18. data/lib/peddler/version.rb +1 -1
  19. data/lib/peddler/xml_parser.rb +1 -1
  20. data/test/helper.rb +1 -82
  21. data/test/integration/test_errors.rb +36 -0
  22. data/test/integration/test_feeds.rb +1 -1
  23. data/test/integration/test_fulfillment_inbound_shipment.rb +1 -1
  24. data/test/integration/test_fulfillment_inventory.rb +1 -1
  25. data/test/integration/test_fulfillment_outbound_shipment.rb +1 -1
  26. data/test/integration/test_merchant_fulfillment.rb +1 -1
  27. data/test/integration/test_off_amazon_payments.rb +1 -1
  28. data/test/integration/test_orders.rb +3 -1
  29. data/test/integration/test_products.rb +1 -1
  30. data/test/integration/test_recommendations.rb +2 -4
  31. data/test/integration/test_reports.rb +1 -1
  32. data/test/integration/test_sellers.rb +1 -1
  33. data/test/integration/test_subscriptions.rb +1 -1
  34. data/test/integration_helper.rb +41 -0
  35. data/test/mws.yml +28 -8
  36. data/test/mws.yml.example +21 -1
  37. data/test/recorder.rb +34 -0
  38. data/test/unit/mws/test_fulfillment_inbound_shipment_client.rb +2 -1
  39. data/test/unit/mws/test_fulfillment_outbound_shipment_client.rb +9 -2
  40. data/test/unit/mws/test_orders_client.rb +12 -0
  41. data/test/unit/mws/test_products_client.rb +37 -0
  42. data/test/unit/peddler/errors/test_builder.rb +16 -0
  43. data/test/unit/peddler/errors/test_error.rb +16 -0
  44. data/test/unit/peddler/errors/test_handler.rb +60 -0
  45. data/test/unit/peddler/{test_error_parser.rb → errors/test_parser.rb} +3 -3
  46. data/test/unit/peddler/test_client.rb +3 -3
  47. data/test/unit/peddler/test_flat_file_parser.rb +39 -30
  48. data/test/unit/peddler/test_structured_list.rb +5 -0
  49. data/test/unit/peddler/test_vcr_matcher.rb +4 -0
  50. data/test/unit/test_mws.rb +1 -1
  51. data/test/vcr_cassettes/CartInformation.yml +263 -13
  52. data/test/vcr_cassettes/CustomerInformation.yml +255 -5
  53. data/test/vcr_cassettes/Errors.yml +885 -0
  54. data/test/vcr_cassettes/Feeds.yml +5588 -17
  55. data/test/vcr_cassettes/FulfillmentInboundShipment.yml +3474 -39
  56. data/test/vcr_cassettes/FulfillmentInventory.yml +504 -9
  57. data/test/vcr_cassettes/FulfillmentOutboundShipment.yml +255 -5
  58. data/test/vcr_cassettes/MerchantFulfillment.yml +254 -4
  59. data/test/vcr_cassettes/OffAmazonPayments.yml +255 -5
  60. data/test/vcr_cassettes/Orders.yml +2696 -36
  61. data/test/vcr_cassettes/Products.yml +5534 -180
  62. data/test/vcr_cassettes/Recommendations.yml +847 -9
  63. data/test/vcr_cassettes/Reports.yml +3994 -101
  64. data/test/vcr_cassettes/Sellers.yml +255 -5
  65. data/test/vcr_cassettes/Subscriptions.yml +875 -13
  66. metadata +37 -27
  67. data/lib/mws/cart_information/client.rb +0 -74
  68. data/lib/mws/cart_information.rb +0 -1
  69. data/lib/mws/customer_information/client.rb +0 -80
  70. data/lib/mws/customer_information.rb +0 -1
  71. data/lib/mws/webstore/client.rb +0 -89
  72. data/lib/mws/webstore.rb +0 -1
  73. data/lib/peddler/error_parser.rb +0 -26
  74. data/test/integration/test_cart_information.rb +0 -11
  75. data/test/integration/test_customer_information.rb +0 -11
  76. data/test/integration/test_webstore.rb +0 -18
  77. data/test/unit/mws/test_cart_information_client.rb +0 -61
  78. data/test/unit/mws/test_customer_information_client.rb +0 -59
  79. data/test/unit/mws/test_webstore_client.rb +0 -101
  80. data/test/vcr_cassettes/Webstore.yml +0 -383
@@ -1,13 +1,11 @@
1
- require 'helper'
1
+ require 'integration_helper'
2
2
  require 'mws/recommendations'
3
3
 
4
4
  class TestRecommendations < IntegrationTest
5
5
  def test_lists_recommendations
6
6
  clients.each do |client|
7
7
  res = client.list_recommendations
8
- content = res.parse
9
- skip unless content
10
- refute_empty content
8
+ refute_empty res.parse
11
9
  end
12
10
  end
13
11
 
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'integration_helper'
2
2
  require 'mws/reports'
3
3
 
4
4
  class TestReports < IntegrationTest
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'integration_helper'
2
2
  require 'mws/sellers'
3
3
 
4
4
  class TestSellers < IntegrationTest
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require 'integration_helper'
2
2
  require 'mws/subscriptions'
3
3
 
4
4
  class TestSubscriptions < IntegrationTest
@@ -0,0 +1,41 @@
1
+ require 'helper'
2
+ require 'recorder'
3
+ require 'dig_rb'
4
+
5
+ %w(mws.yml mws.yml.example).each do |path|
6
+ file = File.expand_path("../#{path}", __FILE__)
7
+ if File.exist?(file)
8
+ $mws = YAML.load_file(file)
9
+ break
10
+ end
11
+ end
12
+
13
+ class IntegrationTest < MiniTest::Test
14
+ include Recorder
15
+
16
+ private
17
+
18
+ def clients
19
+ api = @api || test_name
20
+ $mws.map do |record|
21
+ MWS.const_get("#{api}::Client").new(record)
22
+ end
23
+ end
24
+ end
25
+
26
+ ::Peddler::VCRMatcher.ignore_seller!
27
+
28
+ VCR.configure do |c|
29
+ c.before_record do |interaction|
30
+ %w(
31
+ BuyerName BuyerEmail Name AddressLine1 PostalCode Phone Amount
32
+ ).each do |key|
33
+ interaction.response.body.gsub!(/<#{key}>[^<]+</, "<#{key}>FILTERED<")
34
+ end
35
+ end
36
+
37
+ $mws.each do |record|
38
+ c.filter_sensitive_data('FILTERED') { record['merchant_id'] }
39
+ c.filter_sensitive_data('FILTERED') { record['aws_access_key_id'] }
40
+ end
41
+ end
data/test/mws.yml CHANGED
@@ -1,16 +1,36 @@
1
1
  - primary_marketplace_id: A2EUQ1WTGCTBG2
2
- aws_access_key_id: AKIAITHQMZUJROSOP27Q
3
- aws_secret_access_key: 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
2
+ aws_access_key_id: AKIAILJW7BWJ6YBK4JUQ
3
+ aws_secret_access_key: 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
4
4
  merchant_id: A2A7WNXBU01UJW
5
+ - primary_marketplace_id: A1AM78C64UM0Y8
6
+ aws_access_key_id: AKIAIHE4A3HDKICFHP4A
7
+ aws_secret_access_key: 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
8
+ merchant_id: A1PCFAUFK3U94S
9
+ - primary_marketplace_id: A13V1IB3VIYZZH
10
+ aws_access_key_id: AKIAIOYKJRT4WIH3P72A
11
+ aws_secret_access_key: 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
12
+ merchant_id: A2DP6GIDYN6OTH
13
+ - primary_marketplace_id: APJ6JRA9NG5V4
14
+ aws_access_key_id: AKIAIHE4YSF4UF7CDR6Q
15
+ aws_secret_access_key: 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
16
+ merchant_id: A2APQUVDBVWV7E
17
+ - primary_marketplace_id: A1RKKUPIHCS9HS
18
+ aws_access_key_id: AKIAJAMAR367FRSYNOPA
19
+ aws_secret_access_key: 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
20
+ merchant_id: A2NEU7G6RGUKF
21
+ - primary_marketplace_id: A1F83G8C2ARO7P
22
+ aws_access_key_id: AKIAJCJNB4MASX5JUMUA
23
+ aws_secret_access_key: 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
24
+ merchant_id: A2D9DZ30GEWP6N
25
+ - primary_marketplace_id: A1VC38T7YXB528
26
+ aws_access_key_id: AKIAJZ6EOLNDLSOEOLBA
27
+ aws_secret_access_key: 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
28
+ merchant_id: A7BU5WGNVGQ1I
5
29
  - primary_marketplace_id: A1PA6795UKMFR9
6
30
  aws_access_key_id: AKIAIORT7554FEBW7UBQ
7
31
  aws_secret_access_key: P2ocOVChe/dQUpxRfA1n3TmP+wHrF6GaSzXslvEG
8
32
  merchant_id: A7ZXDJZD3UIRG
9
- - primary_marketplace_id: A1VC38T7YXB528
10
- aws_access_key_id: AKIAJ5RDDSRROM6GXQ5Q
11
- aws_secret_access_key: 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
12
- merchant_id: A7BU5WGNVGQ1I
13
33
  - primary_marketplace_id: ATVPDKIKX0DER
14
- aws_access_key_id: AKIAJ767ZET2BZR4UDDQ
15
- aws_secret_access_key: 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
34
+ aws_access_key_id: AKIAJ25X7BKNXKVCYJXA
35
+ aws_secret_access_key: hguX3TMfKMrqKm71/dQLKqbv2VGCyZANnCXeHAsC
16
36
  merchant_id: A2H6NH4SQYFZ4M
data/test/mws.yml.example CHANGED
@@ -1,8 +1,20 @@
1
+ - primary_marketplace_id: A1AM78C64UM0Y8
2
+ aws_access_key_id: AWS_ACCESS_KEY_ID
3
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
4
+ merchant_id: MERCHANT_ID
5
+ - primary_marketplace_id: A13V1IB3VIYZZH
6
+ aws_access_key_id: AWS_ACCESS_KEY_ID
7
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
8
+ merchant_id: MERCHANT_ID
9
+ - primary_marketplace_id: A1RKKUPIHCS9HS
10
+ aws_access_key_id: AWS_ACCESS_KEY_ID
11
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
12
+ merchant_id: MERCHANT_ID
1
13
  - primary_marketplace_id: A2EUQ1WTGCTBG2
2
14
  aws_access_key_id: AWS_ACCESS_KEY_ID
3
15
  aws_secret_access_key: AWS_SECRET_ACCESS_KEY
4
16
  merchant_id: MERCHANT_ID
5
- - primary_marketplace_id: A1PA6795UKMFR9
17
+ - primary_marketplace_id: APJ6JRA9NG5V4
6
18
  aws_access_key_id: AWS_ACCESS_KEY_ID
7
19
  aws_secret_access_key: AWS_SECRET_ACCESS_KEY
8
20
  merchant_id: MERCHANT_ID
@@ -10,6 +22,14 @@
10
22
  aws_access_key_id: AWS_ACCESS_KEY_ID
11
23
  aws_secret_access_key: AWS_SECRET_ACCESS_KEY
12
24
  merchant_id: MERCHANT_ID
25
+ - primary_marketplace_id: A1F83G8C2ARO7P
26
+ aws_access_key_id: AWS_ACCESS_KEY_ID
27
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
28
+ merchant_id: MERCHANT_ID
29
+ - primary_marketplace_id: A1PA6795UKMFR9
30
+ aws_access_key_id: AWS_ACCESS_KEY_ID
31
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
32
+ merchant_id: MERCHANT_ID
13
33
  - primary_marketplace_id: ATVPDKIKX0DER
14
34
  aws_access_key_id: AWS_ACCESS_KEY_ID
15
35
  aws_secret_access_key: AWS_SECRET_ACCESS_KEY
data/test/recorder.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'peddler/vcr_matcher'
2
+ require 'yaml'
3
+ require 'vcr'
4
+
5
+ VCR.configure do |c|
6
+ c.hook_into :excon
7
+ c.cassette_library_dir = 'test/vcr_cassettes'
8
+
9
+ c.default_cassette_options = {
10
+ match_requests_on: [::Peddler::VCRMatcher],
11
+ record: ENV['RECORD'] ? :new_episodes : :none
12
+ }
13
+
14
+ # c.before_record do |interaction|
15
+ # code = interaction.response.status.code
16
+ # interaction.ignore! if code >= 400 && code != 414
17
+ # end
18
+ end
19
+
20
+ module Recorder
21
+ def setup
22
+ ENV['LIVE'] ? VCR.turn_off! : VCR.insert_cassette(test_name)
23
+ end
24
+
25
+ def teardown
26
+ VCR.eject_cassette if VCR.turned_on?
27
+ end
28
+
29
+ private
30
+
31
+ def test_name
32
+ self.class.name.sub('Test', '')
33
+ end
34
+ end
@@ -165,7 +165,8 @@ class TestMWSFulfillmentInboundShipmentClient < MiniTest::Test
165
165
  @client.stub(:run, nil) do
166
166
  @client.list_inbound_shipments(
167
167
  shipment_status_list: ['Foo'],
168
- shipment_id_list: ['Bar'])
168
+ shipment_id_list: ['Bar']
169
+ )
169
170
  end
170
171
 
171
172
  assert_equal operation, @client.operation
@@ -112,9 +112,16 @@ class TestMWSFulfillmentOutboundShipmentClient < MiniTest::Test
112
112
  end
113
113
 
114
114
  def test_gets_package_tracking_details
115
- assert_raises(NotImplementedError) do
116
- @client.get_package_tracking_details
115
+ operation = {
116
+ 'Action' => 'GetPackageTrackingDetails',
117
+ 'PackageNumber' => '1'
118
+ }
119
+
120
+ @client.stub(:run, nil) do
121
+ @client.get_package_tracking_details('1')
117
122
  end
123
+
124
+ assert_equal operation, @client.operation
118
125
  end
119
126
 
120
127
  def test_cancels_fulfillment_order
@@ -9,6 +9,7 @@ class TestMWSOrdersClient < MiniTest::Test
9
9
  def test_lists_orders
10
10
  operation = {
11
11
  'Action' => 'ListOrders',
12
+ 'CreatedAfter' => '2016-01-01',
12
13
  'OrderStatus.Status.1' => '1',
13
14
  'MarketplaceId.Id.1' => '1',
14
15
  'PaymentMethod.1' => '1',
@@ -19,6 +20,7 @@ class TestMWSOrdersClient < MiniTest::Test
19
20
  @client.stub(:run, nil) do
20
21
  @client.list_orders(
21
22
  marketplace_id: '1',
23
+ created_after: '2016-01-01',
22
24
  order_status: '1',
23
25
  tfm_shipment_status: '1',
24
26
  payment_method: '1',
@@ -29,6 +31,16 @@ class TestMWSOrdersClient < MiniTest::Test
29
31
  assert_equal operation, @client.operation
30
32
  end
31
33
 
34
+ def test_requires_start_time_keyword_when_listing_orders
35
+ @client.stub(:run, nil) do
36
+ assert_raises(ArgumentError) do
37
+ @client.list_orders
38
+ end
39
+ @client.list_orders(created_after: '2016-01-01')
40
+ @client.list_orders(last_updated_after: '2016-01-01')
41
+ end
42
+ end
43
+
32
44
  def test_lists_orders_by_next_token
33
45
  operation = {
34
46
  'Action' => 'ListOrdersByNextToken',
@@ -136,6 +136,43 @@ class TestMWSProductsClient < MiniTest::Test
136
136
  assert_equal operation, @client.operation
137
137
  end
138
138
 
139
+ def test_gets_my_fees_estimate
140
+ operation = {
141
+ 'Action' => 'GetMyFeesEstimate',
142
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.MarketplaceId' => '123',
143
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.IdType' => 'ASIN',
144
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.IdValue' => '123',
145
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.ListingPrice.CurrencyCode' => 'USD',
146
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.ListingPrice.Amount' => 30.00,
147
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Shipping.CurrencyCode' => 'USD',
148
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Shipping.Amount' => 3.99,
149
+ 'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Points.PointsNumber' => 0
150
+ }
151
+
152
+ @client.stub(:run, nil) do
153
+ @client.get_my_fees_estimate(
154
+ marketplace_id: '123',
155
+ id_type: 'ASIN',
156
+ id_value: '123',
157
+ price_to_estimate_fees: {
158
+ listing_price: {
159
+ currency_code: 'USD',
160
+ amount: 30.00
161
+ },
162
+ shipping: {
163
+ currency_code: 'USD',
164
+ amount: 3.99
165
+ },
166
+ points: {
167
+ points_number: 0
168
+ }
169
+ }
170
+ )
171
+ end
172
+
173
+ assert_equal operation, @client.operation
174
+ end
175
+
139
176
  def test_gets_my_price_for_sku
140
177
  operation = {
141
178
  'Action' => 'GetMyPriceForSKU',
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+ require 'peddler/errors/builder'
3
+
4
+ class TestPeddlerErrorsBuilder < MiniTest::Test
5
+ def test_builds_error_class
6
+ Peddler::Errors::Builder.build('Foo')
7
+ assert Peddler::Errors::Foo
8
+ end
9
+
10
+ def test_thread_safety
11
+ Peddler::Errors::Builder.build('Foo')
12
+ assert_output '', '' do
13
+ Peddler::Errors::Builder.build('Foo')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+ require 'peddler/errors/error'
3
+
4
+ class TestPeddlerErrorsError < MiniTest::Test
5
+ def setup
6
+ @error = Peddler::Errors::Error.new('message', 'cause')
7
+ end
8
+
9
+ def test_sets_message
10
+ assert_equal 'message', @error.message
11
+ end
12
+
13
+ def test_sets_cause
14
+ assert_equal 'cause', @error.cause
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ require 'helper'
2
+ require 'peddler/errors/handler'
3
+
4
+ class TestPeddlerErrorsHandler < MiniTest::Test
5
+ def setup
6
+ @error = Peddler::Errors::Handler.call(@cause)
7
+ rescue => @error
8
+ end
9
+
10
+ class CausedByHTTPStatusError < TestPeddlerErrorsHandler
11
+ def setup
12
+ @code = 'FeedProcessingResultNotReady'
13
+ @message = 'Feed Submission Result is not ready for Feed 123'
14
+ @cause = Excon::Error::NotFound.new(
15
+ 'Expected(200) <=> Actual(404 Not Found)',
16
+ nil,
17
+ OpenStruct.new(code: @code, message: @message)
18
+ )
19
+ super
20
+ end
21
+
22
+ def test_generates_custom_error
23
+ assert_includes @error.class.name, @code
24
+ end
25
+
26
+ def test_provides_message
27
+ assert_equal @message, @error.message
28
+ end
29
+
30
+ def test_provides_cause
31
+ assert_equal @cause, @error.cause
32
+ end
33
+ end
34
+
35
+ class CausedByAnotherError < TestPeddlerErrorsHandler
36
+ def setup
37
+ @cause = StandardError.new
38
+ super
39
+ end
40
+
41
+ def test_returns_original_error
42
+ assert_equal @cause, @error
43
+ end
44
+ end
45
+
46
+ class CausedByInternalServerError < TestPeddlerErrorsHandler
47
+ def setup
48
+ @cause = Excon::Error::InternalServerError.new(
49
+ nil,
50
+ nil,
51
+ OpenStruct.new(code: '500', message: nil)
52
+ )
53
+ super
54
+ end
55
+
56
+ def test_returns_original_error
57
+ assert_equal @cause, @error
58
+ end
59
+ end
60
+ end
@@ -1,7 +1,7 @@
1
1
  require 'helper'
2
- require 'peddler/error_parser'
2
+ require 'peddler/errors/parser'
3
3
 
4
- class TestPeddlerErrorParser < MiniTest::Test
4
+ class TestPeddlerErrorsParser < MiniTest::Test
5
5
  def setup
6
6
  body = <<-XML
7
7
  <ErrorResponse>
@@ -21,7 +21,7 @@ class TestPeddlerErrorParser < MiniTest::Test
21
21
  }
22
22
  )
23
23
 
24
- @parser = Peddler::ErrorParser.new(res)
24
+ @parser = Peddler::Errors::Parser.new(res)
25
25
  end
26
26
 
27
27
  def test_parses_data
@@ -138,7 +138,7 @@ class TestPeddlerClient < MiniTest::Test
138
138
  def test_error_callback_on_class
139
139
  Excon.stub({}, status: 503)
140
140
 
141
- assert_raises(Excon::Errors::ServiceUnavailable) do
141
+ assert_raises(Excon::Error::ServiceUnavailable) do
142
142
  @client.run
143
143
  end
144
144
 
@@ -153,7 +153,7 @@ class TestPeddlerClient < MiniTest::Test
153
153
  def test_error_callback_on_instance
154
154
  Excon.stub({}, status: 503)
155
155
 
156
- assert_raises(Excon::Errors::ServiceUnavailable) do
156
+ assert_raises(Excon::Error::ServiceUnavailable) do
157
157
  @client.run
158
158
  end
159
159
 
@@ -177,7 +177,7 @@ class TestPeddlerClient < MiniTest::Test
177
177
  other_client = klass.new
178
178
  other_client.configure_with_mock_data!
179
179
  other_client.operation('Foo')
180
- assert_raises(Excon::Errors::ServiceUnavailable) do
180
+ assert_raises(Excon::Error::ServiceUnavailable) do
181
181
  other_client.run
182
182
  end
183
183
 
@@ -2,76 +2,85 @@ require 'helper'
2
2
  require 'peddler/flat_file_parser'
3
3
 
4
4
  class TestPeddlerFlatFileParser < MiniTest::Test
5
- def setup
5
+ def test_parses_data
6
6
  body = "Feed Processing Summary:\n\tNumber of records processed\t\t11006\n\tNumber of records successful\t\t11006\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n1822\t85da472e-ba6c-11e3-95af-002590a74356\t5000\tWarning\tThe update for Sku '85da472e-ba6c-11e3-95af-002590a74356' was skipped because it is identical to the update in feed '9518995390'.\n"
7
7
  body.encode!('ASCII-8BIT')
8
- headers = { 'Content-Type' => 'application/octet-stream', 'Content-MD5' => 'SmZIMTs2mCO8u8QzR5LE7Q==' }
9
- res = OpenStruct.new(body: body, headers: headers)
10
-
11
- @parser = Peddler::FlatFileParser.new(res, 'ISO-8859-1')
12
- end
13
-
14
- def test_parses_data
15
- assert_kind_of CSV::Table, @parser.parse
8
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ISO-8859-1')
9
+ assert_kind_of CSV::Table, parser.parse
16
10
  end
17
11
 
18
12
  def test_parses_data_a_line_at_a_time
13
+ body = "Feed Processing Summary:\n\tNumber of records processed\t\t11006\n\tNumber of records successful\t\t11006\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n1822\t85da472e-ba6c-11e3-95af-002590a74356\t5000\tWarning\tThe update for Sku '85da472e-ba6c-11e3-95af-002590a74356' was skipped because it is identical to the update in feed '9518995390'.\n"
14
+ body.encode!('ASCII-8BIT')
15
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ISO-8859-1')
19
16
  counter = 0
20
- @parser.parse { counter += 1 }
17
+ parser.parse { counter += 1 }
21
18
  assert counter > 0
22
19
  end
23
20
 
24
21
  def test_summarises
25
- refute_empty @parser.records_count
22
+ body = "Feed Processing Summary:\n\tNumber of records processed\t\t11006\n\tNumber of records successful\t\t11006\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n1822\t85da472e-ba6c-11e3-95af-002590a74356\t5000\tWarning\tThe update for Sku '85da472e-ba6c-11e3-95af-002590a74356' was skipped because it is identical to the update in feed '9518995390'.\n"
23
+ body.encode!('ASCII-8BIT')
24
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ISO-8859-1')
25
+ refute_empty parser.records_count
26
+ end
27
+
28
+ def test_summarises_non_english_reports
29
+ body = "Riepilogo elaborazione feed:\n\tNumero record elaborati\t\t1\n\tNumero record elaborati con successo\t\t1\n\n"
30
+ body.encode!('Cp1252')
31
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ISO-8859-1')
32
+ refute_empty parser.records_count
26
33
  end
27
34
 
28
35
  def test_validates
29
- assert @parser.valid?
36
+ body = "Feed Processing Summary:\n\tNumber of records processed\t\t11006\n\tNumber of records successful\t\t11006\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n1822\t85da472e-ba6c-11e3-95af-002590a74356\t5000\tWarning\tThe update for Sku '85da472e-ba6c-11e3-95af-002590a74356' was skipped because it is identical to the update in feed '9518995390'.\n"
37
+ body.encode!('ASCII-8BIT')
38
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ISO-8859-1')
39
+ assert parser.valid?
30
40
  end
31
41
 
32
42
  def test_handles_reports_without_a_summary
33
- res = OpenStruct.new(body: "Foo\nBar\n")
34
- parser = Peddler::FlatFileParser.new(res, 'ISO-8859-1')
35
-
43
+ response = OpenStruct.new(body: "Foo\nBar\n")
44
+ parser = Peddler::FlatFileParser.new(response, 'ISO-8859-1')
36
45
  refute_empty parser.content
37
46
  end
38
47
 
39
48
  def test_handles_japanese_flat_files
40
49
  body = "Foo\nこんにちは\n"
41
50
  body.encode!('SHIFT_JIS')
42
- body.force_encoding('ASCII-8BIT')
43
- res = OpenStruct.new(body: body)
44
- parser = Peddler::FlatFileParser.new(res, 'Windows-31J')
45
-
51
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'Windows-31J')
46
52
  assert_equal 'こんにちは', parser.parse[0]['Foo']
47
53
  end
48
54
 
49
55
  def test_handles_japanese_curly_braces
50
56
  body = "Foo\n〝\n"
51
57
  body.encode!('Windows-31J')
52
- body.force_encoding('ASCII-8BIT')
53
- res = OpenStruct.new(body: body)
54
- parser = Peddler::FlatFileParser.new(res, 'Windows-31J')
55
-
58
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'Windows-31J')
56
59
  assert_equal '〝', parser.parse[0]['Foo']
57
60
  end
58
61
 
59
62
  def test_handles_latin_1_flat_files
60
63
  body = "Foo\n™\n"
61
64
  body.encode!('Cp1252')
62
- body.force_encoding('ASCII-8BIT')
63
- res = OpenStruct.new(body: body)
64
- parser = Peddler::FlatFileParser.new(res, 'Cp1252')
65
-
65
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'Cp1252')
66
66
  assert_equal '™', parser.parse['Foo'][0]
67
67
  end
68
68
 
69
69
  def test_handles_undefined_characters
70
70
  body = "Foo\n\xFF\n"
71
71
  body.force_encoding('ASCII-8BIT')
72
- res = OpenStruct.new(body: body)
73
- parser = Peddler::FlatFileParser.new(res, 'ASCII-8BIT')
74
-
72
+ parser = Peddler::FlatFileParser.new(build_mock_response(body), 'ASCII-8BIT')
75
73
  assert_equal '?', parser.parse['Foo'][0]
76
74
  end
75
+
76
+ private
77
+
78
+ def build_mock_response(body)
79
+ body.force_encoding('ASCII-8BIT')
80
+ headers = {
81
+ 'Content-MD5' => Digest::MD5.base64digest(body)
82
+ }
83
+
84
+ OpenStruct.new(body: body, headers: headers)
85
+ end
77
86
  end
@@ -16,6 +16,11 @@ class TestPeddlerStructuredList < MiniTest::Test
16
16
  assert_equal exp, @list.build(%w(foo bar))
17
17
  end
18
18
 
19
+ def test_flattens_nested_arrays_of_values
20
+ exp = { 'OrderStatus.Status.1' => 'foo', 'OrderStatus.Status.2' => 'bar' }
21
+ assert_equal exp, @list.build([%w(foo bar)])
22
+ end
23
+
19
24
  def test_handles_single_key
20
25
  list = Peddler::StructuredList.new('Foo')
21
26
  exp = { 'Foo.1' => 'bar' }
@@ -5,6 +5,10 @@ require 'peddler/vcr_matcher'
5
5
  class TestPeddlerVCRMatcher < MiniTest::Test
6
6
  include Recorder
7
7
 
8
+ def setup
9
+ VCR.insert_cassette(test_name, record: :none)
10
+ end
11
+
8
12
  def test_matches_recorded_post_without_body
9
13
  client.run
10
14
  end
@@ -3,7 +3,7 @@ require 'mws'
3
3
 
4
4
  class Test < MiniTest::Test
5
5
  def test_delegates_to_apis
6
- assert_equal MWS.methods(false).size, MWS.constants.size
6
+ assert_equal MWS.constants.size, MWS.methods(false).size
7
7
  assert_kind_of MWS::Products::Client, MWS.products
8
8
  end
9
9
  end