peddler 2.1.1 → 2.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -41
  3. data/lib/mws.rb +2 -1
  4. data/lib/mws/easy_ship.rb +3 -0
  5. data/lib/mws/easy_ship/client.rb +93 -0
  6. data/lib/mws/fulfillment_outbound_shipment/client.rb +1 -1
  7. data/lib/mws/orders/client.rb +7 -9
  8. data/lib/mws/shipment_invoicing.rb +3 -0
  9. data/lib/mws/shipment_invoicing/client.rb +74 -0
  10. data/lib/mws/subscriptions/client.rb +2 -2
  11. data/lib/peddler/client.rb +17 -13
  12. data/lib/peddler/errors/builder.rb +7 -2
  13. data/lib/peddler/errors/class_generator.rb +9 -4
  14. data/lib/peddler/errors/error.rb +6 -2
  15. data/lib/peddler/errors/parser.rb +1 -1
  16. data/lib/peddler/flat_file_parser.rb +5 -3
  17. data/lib/peddler/headers.rb +6 -1
  18. data/lib/peddler/marketplace.rb +25 -19
  19. data/lib/peddler/operation.rb +17 -11
  20. data/lib/peddler/parser.rb +1 -1
  21. data/lib/peddler/structured_list.rb +1 -1
  22. data/lib/peddler/vcr_matcher.rb +7 -7
  23. data/lib/peddler/version.rb +1 -1
  24. data/lib/peddler/xml_parser.rb +1 -1
  25. data/lib/peddler/xml_response_parser.rb +3 -2
  26. metadata +15 -152
  27. data/lib/mws/off_amazon_payments/client.rb +0 -362
  28. data/lib/peddler/content.rb +0 -69
  29. data/lib/peddler/mws.rb +0 -58
  30. data/test/credentials.rb +0 -23
  31. data/test/helper.rb +0 -15
  32. data/test/integration/internals/test_errors.rb +0 -17
  33. data/test/integration/internals/test_multibyte_queries.rb +0 -17
  34. data/test/integration/internals/test_mws_headers.rb +0 -21
  35. data/test/integration/internals/test_string_encodings.rb +0 -38
  36. data/test/integration/test_feeds.rb +0 -37
  37. data/test/integration/test_fulfillment_inbound_shipment.rb +0 -35
  38. data/test/integration/test_fulfillment_inventory.rb +0 -20
  39. data/test/integration/test_fulfillment_outbound_shipment.rb +0 -13
  40. data/test/integration/test_merchant_fulfillment.rb +0 -69
  41. data/test/integration/test_off_amazon_payments.rb +0 -13
  42. data/test/integration/test_orders.rb +0 -30
  43. data/test/integration/test_products.rb +0 -97
  44. data/test/integration/test_recommendations.rb +0 -20
  45. data/test/integration/test_reports.rb +0 -51
  46. data/test/integration/test_sellers.rb +0 -13
  47. data/test/integration/test_subscriptions.rb +0 -27
  48. data/test/integration_helper.rb +0 -53
  49. data/test/mws.yml +0 -36
  50. data/test/mws.yml.example +0 -32
  51. data/test/null_client.rb +0 -25
  52. data/test/recorder.rb +0 -39
  53. data/test/unit/mws/test_feeds_client.rb +0 -103
  54. data/test/unit/mws/test_finances_client.rb +0 -74
  55. data/test/unit/mws/test_fulfillment_inbound_shipment_client.rb +0 -426
  56. data/test/unit/mws/test_fulfillment_inventory_client.rb +0 -48
  57. data/test/unit/mws/test_fulfillment_outbound_shipment_client.rb +0 -202
  58. data/test/unit/mws/test_merchant_fulfillment_client.rb +0 -109
  59. data/test/unit/mws/test_off_amazon_payments_client.rb +0 -286
  60. data/test/unit/mws/test_orders_client.rb +0 -111
  61. data/test/unit/mws/test_products_client.rb +0 -248
  62. data/test/unit/mws/test_recommendations_client.rb +0 -62
  63. data/test/unit/mws/test_reports_client.rb +0 -209
  64. data/test/unit/mws/test_sellers_client.rb +0 -47
  65. data/test/unit/mws/test_subscriptions_client.rb +0 -182
  66. data/test/unit/peddler/errors/test_builder.rb +0 -65
  67. data/test/unit/peddler/errors/test_class_generator.rb +0 -18
  68. data/test/unit/peddler/errors/test_error.rb +0 -33
  69. data/test/unit/peddler/errors/test_parser.rb +0 -44
  70. data/test/unit/peddler/test_client.rb +0 -203
  71. data/test/unit/peddler/test_flat_file_parser.rb +0 -111
  72. data/test/unit/peddler/test_headers.rb +0 -103
  73. data/test/unit/peddler/test_marketplace.rb +0 -47
  74. data/test/unit/peddler/test_operation.rb +0 -87
  75. data/test/unit/peddler/test_parser.rb +0 -36
  76. data/test/unit/peddler/test_structured_list.rb +0 -39
  77. data/test/unit/peddler/test_vcr_matcher.rb +0 -55
  78. data/test/unit/peddler/test_xml_parser.rb +0 -37
  79. data/test/unit/peddler/test_xml_response_parser.rb +0 -39
  80. data/test/unit/test_mws.rb +0 -11
  81. data/test/vcr_cassettes/CartInformation.yml +0 -433
  82. data/test/vcr_cassettes/CustomerInformation.yml +0 -433
  83. data/test/vcr_cassettes/Errors.yml +0 -444
  84. data/test/vcr_cassettes/Feeds.yml +0 -9957
  85. data/test/vcr_cassettes/FulfillmentInboundShipment.yml +0 -6166
  86. data/test/vcr_cassettes/FulfillmentInventory.yml +0 -850
  87. data/test/vcr_cassettes/FulfillmentOutboundShipment.yml +0 -433
  88. data/test/vcr_cassettes/MWSHeaders.yml +0 -2964
  89. data/test/vcr_cassettes/MerchantFulfillment.yml +0 -753
  90. data/test/vcr_cassettes/MultibyteQueries.yml +0 -437
  91. data/test/vcr_cassettes/OffAmazonPayments.yml +0 -433
  92. data/test/vcr_cassettes/Orders.yml +0 -4740
  93. data/test/vcr_cassettes/PeddlerVCRMatcher.yml +0 -41
  94. data/test/vcr_cassettes/Products.yml +0 -7139
  95. data/test/vcr_cassettes/Recommendations.yml +0 -3145
  96. data/test/vcr_cassettes/Reports.yml +0 -5549
  97. data/test/vcr_cassettes/Sellers.yml +0 -433
  98. data/test/vcr_cassettes/Subscriptions.yml +0 -1529
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Peddler
4
- # Parses content metadata provided in the headers of a response
5
- class Content
6
- # @api private
7
- attr_reader :headers
8
-
9
- # @api private
10
- def initialize(headers)
11
- @headers = headers.select { |key| key.start_with?('Content') }
12
- end
13
-
14
- # The size of the response body in bytes
15
- # @return [String, nil]
16
- def length
17
- return unless headers['Content-Length']
18
-
19
- headers['Content-Length'].to_i
20
- end
21
-
22
- # The MD5 digest of the response body
23
- # @return [String, nil]
24
- def md5
25
- headers['Content-MD5']
26
- end
27
-
28
- # The MIME type of the response
29
- # @return [String, nil]
30
- def media_type
31
- return unless headers['Content-Type']
32
-
33
- headers['Content-Type'].split(';').first
34
- end
35
-
36
- # The general category into which the MIME type falls
37
- # @return [String, nil]
38
- def type
39
- return unless media_type
40
-
41
- media_type.split('/').first
42
- end
43
-
44
- # The exact kind of data of the specified type the MIME type represents
45
- # @return [String, nil]
46
- def subtype
47
- return unless media_type
48
-
49
- media_type.split('/').last
50
- end
51
-
52
- # The character encoding of the response
53
- # @return [Encoding, nil]
54
- def charset
55
- match_data = headers['Content-Type']&.match(/charset=(.*);?/)
56
- return unless match_data
57
-
58
- Encoding.find(match_data[1])
59
- end
60
-
61
- # Whether the response is an XML document
62
- # @return [Boolean, nil]
63
- def xml?
64
- return unless subtype
65
-
66
- subtype == 'xml'
67
- end
68
- end
69
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Peddler
4
- # Parses MWS metadata provided in the headers of a response
5
- class MWS
6
- # @api private
7
- attr_reader :headers
8
-
9
- # @api private
10
- def initialize(headers)
11
- @headers = headers.select { |key| key.start_with?('x-mws') }
12
- end
13
-
14
- # The max hourly request quota for the requested operation
15
- # @return [Integer, nil]
16
- def quota_max
17
- return unless headers['x-mws-quota-max']
18
-
19
- headers['x-mws-quota-max'].to_i
20
- end
21
-
22
- # The remaining hourly request quota for the requested operation
23
- # @return [Integer, nil]
24
- def quota_remaining
25
- return unless headers['x-mws-quota-remaining']
26
-
27
- headers['x-mws-quota-remaining'].to_i
28
- end
29
-
30
- # When the hourly request quota for the requested operation resets
31
- # @return [Time, nil]
32
- def quota_resets_on
33
- return unless headers['x-mws-quota-resetsOn']
34
-
35
- Time.parse(headers['x-mws-quota-resetsOn'])
36
- end
37
-
38
- # The ID of the request
39
- # @return [String, nil]
40
- def request_id
41
- headers['x-mws-request-id']
42
- end
43
-
44
- # The timestamp of the request
45
- # @return [Time, nil]
46
- def timestamp
47
- return unless headers['x-mws-timestamp']
48
-
49
- Time.parse(headers['x-mws-timestamp'])
50
- end
51
-
52
- # The context of the response
53
- # @return [String, nil]
54
- def response_context
55
- headers['x-mws-response-context']
56
- end
57
- end
58
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'forwardable'
4
- require 'yaml'
5
-
6
- module Credentials
7
- class <<self
8
- extend Forwardable
9
- include Enumerable
10
-
11
- attr_reader :all
12
-
13
- def_delegators :all, :each
14
- end
15
-
16
- %w[mws.yml mws.yml.example].each do |path|
17
- file = File.expand_path("../#{path}", __FILE__)
18
- if File.exist?(file)
19
- @all = YAML.load_file(file)
20
- break
21
- end
22
- end
23
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Keep SimpleCov at top.
4
- require 'simplecov'
5
- SimpleCov.start do
6
- add_filter '/test/'
7
- end
8
-
9
- require 'minitest/autorun'
10
- require 'minitest/focus'
11
- begin
12
- require 'pry'
13
- rescue LoadError
14
- nil
15
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/orders'
5
-
6
- class TestErrors < IntegrationTest
7
- use 'Orders'
8
-
9
- def test_invalid_key
10
- clients.each do |client|
11
- assert_raises Peddler::Errors::InvalidAccessKeyId do
12
- client.aws_access_key_id = 'foo'
13
- client.get_order('bar')
14
- end
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/products'
5
-
6
- class TestMultibyteQueries < IntegrationTest
7
- use 'Products'
8
-
9
- def test_posting_multibyte_queries_properly
10
- ret = clients.map do |client|
11
- res = client.list_matching_products(client.marketplace.id, 'félix guattari machinic eros')
12
- res.body.force_encoding 'UTF-8' if defined? Ox # Ox workaround
13
- res.parse
14
- end
15
- assert ret.map(&:to_s).join.include?('Félix')
16
- end
17
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/products'
5
-
6
- class TestMWSHeaders < IntegrationTest
7
- use 'Products'
8
-
9
- def test_parsing_headers
10
- clients.each do |client|
11
- res = client.get_lowest_priced_offers_for_asin(client.marketplace.id,
12
- '1780935374', 'New')
13
- refute_nil res.mws_quota_max
14
- refute_nil res.mws_quota_remaining
15
- refute_nil res.mws_quota_resets_on
16
- refute_nil res.mws_request_id
17
- refute_nil res.mws_timestamp
18
- refute_nil res.mws_response_context
19
- end
20
- end
21
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/reports'
5
-
6
- class TestStringEncodings < IntegrationTest
7
- use 'Reports'
8
-
9
- def setup
10
- skip unless ENV['LIVE']
11
- end
12
-
13
- def test_flat_file_responses
14
- get_report('_GET_SELLER_FEEDBACK_DATA_') do |res|
15
- assert_equal res.content_charset, res.body.encoding
16
- end
17
- end
18
-
19
- private
20
-
21
- def get_report(report_type, start_date: Date.today - 30)
22
- clients.each do |client|
23
- res = client.request_report(report_type, start_date: start_date)
24
- report_request_id = res.dig('ReportRequestInfo', 'ReportRequestId')
25
- loop do
26
- sleep 15
27
- res = client.get_report_request_list(report_request_id_list:
28
- report_request_id)
29
- status = res.dig('ReportRequestInfo', 'ReportProcessingStatus')
30
- next unless status.include?('_DONE_')
31
-
32
- report_id = res.dig('ReportRequestInfo', 'GeneratedReportId')
33
- yield client.get_report(report_id)
34
- break
35
- end
36
- end
37
- end
38
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/feeds'
5
-
6
- class TestFeeds < IntegrationTest
7
- def test_getting_feed_submission_count
8
- clients.each do |client|
9
- res = client.get_feed_submission_count
10
- refute_empty res.parse
11
- end
12
- end
13
-
14
- def test_getting_feed_submission_list
15
- clients.each do |client|
16
- res = client.get_feed_submission_list
17
- refute_empty res.parse
18
- end
19
- end
20
-
21
- def test_submitting_feeds
22
- feed_content = "sku\tprice\tquantity\nwidget\t\t0\n"
23
- feed_type = '_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_'
24
-
25
- clients.each do |client|
26
- res = client.submit_feed(feed_content, feed_type)
27
- feed_submission_id = res.dig('FeedSubmissionInfo', 'FeedSubmissionId')
28
- assert feed_submission_id
29
-
30
- # Clean up
31
- client.cancel_feed_submissions(
32
- feed_submission_id: feed_submission_id,
33
- feed_type_list: feed_type
34
- )
35
- end
36
- end
37
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/fulfillment_inbound_shipment'
5
-
6
- class TestFulfillmentInboundShipment < IntegrationTest
7
- Address = Struct.new(:name, :address_line_1, :city, :state_or_province_code,
8
- :postal_code, :country_code)
9
- Item = Struct.new(:seller_sku, :quantity)
10
-
11
- def test_creating_inbound_shipment_plan
12
- address = Address.new('John', '1 Main St', 'New York', 'NY', '10001', 'US')
13
- item = Item.new('123', 1)
14
- clients.each do |client|
15
- res = client.create_inbound_shipment_plan(address, [item])
16
- refute_empty res.parse
17
- end
18
- end
19
-
20
- def test_getting_service_status
21
- clients.each do |client|
22
- res = client.get_service_status
23
- refute_empty res.parse
24
- end
25
- end
26
-
27
- def test_handling_large_requests
28
- address = Address.new('John', '1 Main St', 'New York', 'NY', '10001', 'US')
29
- items = Array.new(100) { |i| Item.new(i, 1) }
30
- clients.each do |client|
31
- res = client.create_inbound_shipment_plan(address, items)
32
- assert_equal 200, res.status
33
- end
34
- end
35
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/fulfillment_inventory'
5
-
6
- class TestFulfillmentInventory < IntegrationTest
7
- def test_listing_inventory_supply
8
- clients.each do |client|
9
- res = client.list_inventory_supply(query_start_date_time: Date.today - 30)
10
- refute_empty res.parse
11
- end
12
- end
13
-
14
- def test_getting_service_status
15
- clients.each do |client|
16
- res = client.get_service_status
17
- refute_empty res.parse
18
- end
19
- end
20
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/fulfillment_outbound_shipment'
5
-
6
- class TestFulfillmentOutboundShipment < IntegrationTest
7
- def test_getting_service_status
8
- clients.each do |client|
9
- res = client.get_service_status
10
- refute_empty res.parse
11
- end
12
- end
13
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'integration_helper'
4
- require 'mws/merchant_fulfillment'
5
-
6
- class TestMerchantFulfillment < IntegrationTest
7
- def test_getting_eligible_shipments_in_the_us
8
- client = clients.us
9
- res = client.get_eligible_shipping_services(shipment_request_details)
10
- refute res.dig('ShippingServiceList', 'ShippingService').count.zero?
11
- end
12
-
13
- def test_shipping_in_the_us
14
- client = clients.us
15
- res = client.create_shipment(shipment_request_details, 'UPS_PTP_GND')
16
- label = res.dig('Shipment', 'Label')
17
- data_compressed = Base64.decode64(label['FileContents']['Contents'])
18
- # data = Zlib.gunzip(data_compressed)
19
- data = Zlib::GzipReader.new(StringIO.new(data_compressed)).read
20
- assert_equal label['FileContents']['Checksum'], Digest::MD5.base64digest(data)
21
- res = client.cancel_shipment(res.dig('Shipment', 'ShipmentId'))
22
- assert_equal 'RefundPending', res.dig('Shipment', 'Status')
23
- end
24
-
25
- def test_getting_service_status
26
- clients.each do |client|
27
- res = client.get_service_status
28
- refute_empty res.parse
29
- end
30
- end
31
-
32
- private
33
-
34
- def shipment_request_details
35
- {
36
- amazon_order_id: '123-1234567-1234567',
37
- item_list: [
38
- {
39
- order_item_id: '12345678901234',
40
- quantity: 1
41
- }
42
- ],
43
- ship_from_address: {
44
- name: 'John Doe',
45
- address_line_1: '10 Jay St',
46
- email: 'john@example.com',
47
- city: 'Brooklyn',
48
- state_or_province_code: 'NY',
49
- postal_code: '11201',
50
- country_code: 'US',
51
- phone: '7181231234'
52
- },
53
- package_dimensions: {
54
- length: 40,
55
- width: 30,
56
- height: 10,
57
- unit: 'centimeters'
58
- },
59
- weight: {
60
- value: 1000,
61
- unit: 'grams'
62
- },
63
- shipping_service_options: {
64
- carrier_will_pick_up: false,
65
- delivery_experience: 'DeliveryConfirmationWithoutSignature'
66
- }
67
- }
68
- end
69
- end