peddler 2.1.1 → 2.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of peddler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +43 -41
- data/lib/mws.rb +2 -1
- data/lib/mws/easy_ship.rb +3 -0
- data/lib/mws/easy_ship/client.rb +93 -0
- data/lib/mws/fulfillment_outbound_shipment/client.rb +1 -1
- data/lib/mws/orders/client.rb +7 -9
- data/lib/mws/shipment_invoicing.rb +3 -0
- data/lib/mws/shipment_invoicing/client.rb +74 -0
- data/lib/peddler/client.rb +16 -13
- data/lib/peddler/errors/builder.rb +7 -2
- data/lib/peddler/errors/class_generator.rb +7 -2
- data/lib/peddler/errors/error.rb +6 -2
- data/lib/peddler/errors/parser.rb +1 -1
- data/lib/peddler/flat_file_parser.rb +5 -3
- data/lib/peddler/headers.rb +6 -1
- data/lib/peddler/marketplace.rb +24 -19
- data/lib/peddler/operation.rb +17 -11
- data/lib/peddler/parser.rb +1 -1
- data/lib/peddler/structured_list.rb +1 -1
- data/lib/peddler/vcr_matcher.rb +7 -7
- data/lib/peddler/version.rb +1 -1
- data/lib/peddler/xml_parser.rb +1 -1
- data/lib/peddler/xml_response_parser.rb +3 -2
- metadata +15 -152
- data/lib/mws/off_amazon_payments/client.rb +0 -362
- data/lib/peddler/content.rb +0 -69
- data/lib/peddler/mws.rb +0 -58
- data/test/credentials.rb +0 -23
- data/test/helper.rb +0 -15
- data/test/integration/internals/test_errors.rb +0 -17
- data/test/integration/internals/test_multibyte_queries.rb +0 -17
- data/test/integration/internals/test_mws_headers.rb +0 -21
- data/test/integration/internals/test_string_encodings.rb +0 -38
- data/test/integration/test_feeds.rb +0 -37
- data/test/integration/test_fulfillment_inbound_shipment.rb +0 -35
- data/test/integration/test_fulfillment_inventory.rb +0 -20
- data/test/integration/test_fulfillment_outbound_shipment.rb +0 -13
- data/test/integration/test_merchant_fulfillment.rb +0 -69
- data/test/integration/test_off_amazon_payments.rb +0 -13
- data/test/integration/test_orders.rb +0 -30
- data/test/integration/test_products.rb +0 -97
- data/test/integration/test_recommendations.rb +0 -20
- data/test/integration/test_reports.rb +0 -51
- data/test/integration/test_sellers.rb +0 -13
- data/test/integration/test_subscriptions.rb +0 -27
- data/test/integration_helper.rb +0 -53
- data/test/mws.yml +0 -36
- data/test/mws.yml.example +0 -32
- data/test/null_client.rb +0 -25
- data/test/recorder.rb +0 -39
- data/test/unit/mws/test_feeds_client.rb +0 -103
- data/test/unit/mws/test_finances_client.rb +0 -74
- data/test/unit/mws/test_fulfillment_inbound_shipment_client.rb +0 -426
- data/test/unit/mws/test_fulfillment_inventory_client.rb +0 -48
- data/test/unit/mws/test_fulfillment_outbound_shipment_client.rb +0 -202
- data/test/unit/mws/test_merchant_fulfillment_client.rb +0 -109
- data/test/unit/mws/test_off_amazon_payments_client.rb +0 -286
- data/test/unit/mws/test_orders_client.rb +0 -111
- data/test/unit/mws/test_products_client.rb +0 -248
- data/test/unit/mws/test_recommendations_client.rb +0 -62
- data/test/unit/mws/test_reports_client.rb +0 -209
- data/test/unit/mws/test_sellers_client.rb +0 -47
- data/test/unit/mws/test_subscriptions_client.rb +0 -182
- data/test/unit/peddler/errors/test_builder.rb +0 -65
- data/test/unit/peddler/errors/test_class_generator.rb +0 -18
- data/test/unit/peddler/errors/test_error.rb +0 -33
- data/test/unit/peddler/errors/test_parser.rb +0 -44
- data/test/unit/peddler/test_client.rb +0 -203
- data/test/unit/peddler/test_flat_file_parser.rb +0 -111
- data/test/unit/peddler/test_headers.rb +0 -103
- data/test/unit/peddler/test_marketplace.rb +0 -47
- data/test/unit/peddler/test_operation.rb +0 -87
- data/test/unit/peddler/test_parser.rb +0 -36
- data/test/unit/peddler/test_structured_list.rb +0 -39
- data/test/unit/peddler/test_vcr_matcher.rb +0 -55
- data/test/unit/peddler/test_xml_parser.rb +0 -37
- data/test/unit/peddler/test_xml_response_parser.rb +0 -39
- data/test/unit/test_mws.rb +0 -11
- data/test/vcr_cassettes/CartInformation.yml +0 -433
- data/test/vcr_cassettes/CustomerInformation.yml +0 -433
- data/test/vcr_cassettes/Errors.yml +0 -444
- data/test/vcr_cassettes/Feeds.yml +0 -9957
- data/test/vcr_cassettes/FulfillmentInboundShipment.yml +0 -6166
- data/test/vcr_cassettes/FulfillmentInventory.yml +0 -850
- data/test/vcr_cassettes/FulfillmentOutboundShipment.yml +0 -433
- data/test/vcr_cassettes/MWSHeaders.yml +0 -2964
- data/test/vcr_cassettes/MerchantFulfillment.yml +0 -753
- data/test/vcr_cassettes/MultibyteQueries.yml +0 -437
- data/test/vcr_cassettes/OffAmazonPayments.yml +0 -433
- data/test/vcr_cassettes/Orders.yml +0 -4740
- data/test/vcr_cassettes/PeddlerVCRMatcher.yml +0 -41
- data/test/vcr_cassettes/Products.yml +0 -7139
- data/test/vcr_cassettes/Recommendations.yml +0 -3145
- data/test/vcr_cassettes/Reports.yml +0 -5549
- data/test/vcr_cassettes/Sellers.yml +0 -433
- data/test/vcr_cassettes/Subscriptions.yml +0 -1529
data/lib/peddler/content.rb
DELETED
@@ -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
|
data/lib/peddler/mws.rb
DELETED
@@ -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
|
data/test/credentials.rb
DELETED
@@ -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
|
data/test/helper.rb
DELETED
@@ -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
|