peddler 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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