peddler 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +62 -81
- data/lib/mws/cart_information.rb +13 -0
- data/lib/mws/customer_information.rb +16 -0
- data/lib/mws/feeds.rb +110 -1
- data/lib/mws/fulfillment_inbound_shipment.rb +13 -1
- data/lib/mws/fulfillment_inventory.rb +15 -1
- data/lib/mws/fulfillment_outbound_shipment.rb +17 -1
- data/lib/mws/off_amazon_payments.rb +15 -1
- data/lib/mws/orders.rb +100 -1
- data/lib/mws/products.rb +238 -1
- data/lib/mws/recommendations.rb +13 -1
- data/lib/mws/reports.rb +221 -1
- data/lib/mws/sellers.rb +40 -1
- data/lib/mws/subscriptions.rb +175 -1
- data/lib/peddler/client.rb +77 -37
- data/lib/peddler/csv_parser.rb +42 -0
- data/lib/peddler/operation.rb +44 -0
- data/lib/peddler/parser.rb +21 -0
- data/lib/peddler/structured_list.rb +22 -0
- data/lib/peddler/version.rb +1 -1
- data/lib/peddler/xml_parser.rb +25 -0
- data/lib/peddler.rb +2 -0
- data/test/helper.rb +1 -1
- data/test/integration/test_feeds.rb +18 -0
- data/test/integration/test_orders.rb +22 -0
- data/test/integration/test_products.rb +53 -0
- data/test/integration/test_reports.rb +47 -0
- data/test/integration/test_sellers.rb +18 -0
- data/test/integration/test_subscriptions.rb +26 -0
- data/test/integration_helper.rb +41 -8
- data/test/mws.yml +32 -0
- data/test/mws.yml.example +4 -0
- data/test/unit/peddler/test_client.rb +97 -0
- data/test/unit/peddler/test_csv_parser.rb +24 -0
- data/test/unit/peddler/test_operation.rb +34 -0
- data/test/{peddler/request → unit/peddler}/test_structured_list.rb +5 -5
- data/test/unit/peddler/test_xml_parser.rb +19 -0
- data/test/{test_peddler.rb → unit/test_peddler.rb} +2 -2
- data/test/vcr_cassettes/Feeds.yml +695 -0
- data/test/vcr_cassettes/Orders.yml +29855 -0
- data/test/vcr_cassettes/Products.yml +8597 -0
- data/test/vcr_cassettes/Reports.yml +1881 -0
- data/test/vcr_cassettes/Sellers.yml +697 -0
- data/test/vcr_cassettes/Subscriptions.yml +1369 -0
- metadata +91 -297
- data/lib/mws/feeds/client.rb +0 -116
- data/lib/mws/feeds/parsers/feed.rb +0 -14
- data/lib/mws/feeds/parsers/feed_submission_count.rb +0 -10
- data/lib/mws/feeds/parsers/feed_submission_info.rb +0 -25
- data/lib/mws/feeds/parsers/feed_submission_list.rb +0 -23
- data/lib/mws/feeds/parsers/feed_submission_result.rb +0 -10
- data/lib/mws/feeds/parsers/feed_submissions.rb +0 -18
- data/lib/mws/feeds/requests/feed.rb +0 -38
- data/lib/mws/feeds/requests/feed_submission_count.rb +0 -20
- data/lib/mws/feeds/requests/feed_submission_list.rb +0 -30
- data/lib/mws/feeds/requests/feed_submission_result.rb +0 -18
- data/lib/mws/feeds/requests/feed_submissions.rb +0 -20
- data/lib/mws/fulfillment_inbound_shipment/client.rb +0 -7
- data/lib/mws/fulfillment_inventory/client.rb +0 -7
- data/lib/mws/fulfillment_outbound_shipment/client.rb +0 -7
- data/lib/mws/off_amazon_payments/client.rb +0 -7
- data/lib/mws/orders/client.rb +0 -98
- data/lib/mws/orders/parsers/invoice_data.rb +0 -25
- data/lib/mws/orders/parsers/order.rb +0 -113
- data/lib/mws/orders/parsers/order_item.rb +0 -110
- data/lib/mws/orders/parsers/order_items.rb +0 -23
- data/lib/mws/orders/parsers/orders.rb +0 -23
- data/lib/mws/orders/parsers/payment_execution_detail.rb +0 -20
- data/lib/mws/orders/parsers/payment_execution_detail_item.rb +0 -17
- data/lib/mws/orders/parsers/service_status.rb +0 -36
- data/lib/mws/orders/parsers/service_status_message.rb +0 -17
- data/lib/mws/orders/parsers/shipping_address.rb +0 -37
- data/lib/mws/orders/requests/order_items.rb +0 -28
- data/lib/mws/orders/requests/orders.rb +0 -41
- data/lib/mws/orders/requests/service_status.rb +0 -15
- data/lib/mws/products/client.rb +0 -7
- data/lib/mws/recommendations/client.rb +0 -7
- data/lib/mws/reports/client.rb +0 -249
- data/lib/mws/reports/parsers/report.rb +0 -10
- data/lib/mws/reports/parsers/report_acknowledgements.rb +0 -20
- data/lib/mws/reports/parsers/report_count.rb +0 -10
- data/lib/mws/reports/parsers/report_info.rb +0 -29
- data/lib/mws/reports/parsers/report_list.rb +0 -23
- data/lib/mws/reports/parsers/report_request.rb +0 -14
- data/lib/mws/reports/parsers/report_request_count.rb +0 -10
- data/lib/mws/reports/parsers/report_request_info.rb +0 -49
- data/lib/mws/reports/parsers/report_request_list.rb +0 -23
- data/lib/mws/reports/parsers/report_requests.rb +0 -18
- data/lib/mws/reports/parsers/report_schedule.rb +0 -21
- data/lib/mws/reports/parsers/report_schedule_count.rb +0 -10
- data/lib/mws/reports/parsers/report_schedule_list.rb +0 -23
- data/lib/mws/reports/parsers/report_scheduler.rb +0 -19
- data/lib/mws/reports/requests/report.rb +0 -18
- data/lib/mws/reports/requests/report_acknowledgements.rb +0 -27
- data/lib/mws/reports/requests/report_count.rb +0 -20
- data/lib/mws/reports/requests/report_list.rb +0 -30
- data/lib/mws/reports/requests/report_request.rb +0 -21
- data/lib/mws/reports/requests/report_request_count.rb +0 -20
- data/lib/mws/reports/requests/report_request_list.rb +0 -30
- data/lib/mws/reports/requests/report_requests.rb +0 -20
- data/lib/mws/reports/requests/report_schedule_count.rb +0 -19
- data/lib/mws/reports/requests/report_schedule_list.rb +0 -23
- data/lib/mws/reports/requests/report_scheduler.rb +0 -29
- data/lib/mws/sellers/client.rb +0 -53
- data/lib/mws/sellers/parsers/marketplace.rb +0 -33
- data/lib/mws/sellers/parsers/marketplace_participations.rb +0 -32
- data/lib/mws/sellers/parsers/participation.rb +0 -21
- data/lib/mws/sellers/parsers/service_status.rb +0 -36
- data/lib/mws/sellers/parsers/service_status_message.rb +0 -17
- data/lib/mws/sellers/requests/marketplace_participations.rb +0 -27
- data/lib/mws/sellers/requests/service_status.rb +0 -15
- data/lib/mws/subscriptions/client.rb +0 -7
- data/lib/peddler/parsers/base.rb +0 -15
- data/lib/peddler/parsers/collection.rb +0 -23
- data/lib/peddler/parsers/counter.rb +0 -13
- data/lib/peddler/parsers/model.rb +0 -42
- data/lib/peddler/parsers/text.rb +0 -8
- data/lib/peddler/parsers/tokenable.rb +0 -13
- data/lib/peddler/parsers/xml.rb +0 -30
- data/lib/peddler/request/parameters.rb +0 -57
- data/lib/peddler/request/structured_list.rb +0 -48
- data/lib/peddler/request.rb +0 -52
- data/lib/peddler/response/base.rb +0 -0
- data/lib/peddler/response/payload/base.rb +0 -0
- data/lib/peddler/response/payload/csv.rb +0 -0
- data/lib/peddler/response/payload/xml.rb +0 -0
- data/lib/peddler/response.rb +0 -27
- data/test/fixtures/feeds/feed_submission.xml +0 -14
- data/test/fixtures/feeds/feed_submission_count.xml +0 -9
- data/test/fixtures/feeds/feed_submission_list.xml +0 -17
- data/test/fixtures/feeds/feed_submissions.xml +0 -15
- data/test/fixtures/mws.yml +0 -12
- data/test/fixtures/mws.yml.example +0 -4
- data/test/fixtures/orders/order_items.xml +0 -83
- data/test/fixtures/orders/orders.xml +0 -109
- data/test/fixtures/orders/service_status.xml +0 -19
- data/test/fixtures/reports/report.xml +0 -8
- data/test/fixtures/reports/report_acknowledgements.xml +0 -18
- data/test/fixtures/reports/report_count.xml +0 -9
- data/test/fixtures/reports/report_list.xml +0 -17
- data/test/fixtures/reports/report_request_count.xml +0 -9
- data/test/fixtures/reports/report_request_list.xml +0 -24
- data/test/fixtures/reports/report_requests.xml +0 -19
- data/test/fixtures/reports/report_schedule_count.xml +0 -10
- data/test/fixtures/reports/report_schedule_list.xml +0 -16
- data/test/fixtures/reports/report_scheduler.xml +0 -15
- data/test/fixtures/sellers/market_participations.xml +0 -27
- data/test/fixtures/sellers/service_status.xml +0 -9
- data/test/integration/feeds/test_feed_submission_count.rb +0 -13
- data/test/integration/feeds/test_feed_submission_list.rb +0 -17
- data/test/integration/feeds/test_feed_submission_result.rb +0 -15
- data/test/integration/orders/test_order_items.rb +0 -19
- data/test/integration/orders/test_orders.rb +0 -23
- data/test/integration/orders/test_service_status.rb +0 -12
- data/test/integration/reports/test_report.rb +0 -15
- data/test/integration/reports/test_report_count.rb +0 -13
- data/test/integration/reports/test_report_list.rb +0 -17
- data/test/integration/reports/test_report_request_count.rb +0 -13
- data/test/integration/reports/test_report_request_list.rb +0 -17
- data/test/integration/reports/test_report_schedule_count.rb +0 -13
- data/test/integration/reports/test_report_schedule_list.rb +0 -13
- data/test/integration/reports/test_report_scheduler.rb +0 -16
- data/test/integration/sellers/test_marketplace_participations.rb +0 -13
- data/test/integration/sellers/test_service_status.rb +0 -12
- data/test/mws/feeds/parsers/test_feed.rb +0 -13
- data/test/mws/feeds/parsers/test_feed_submission_count.rb +0 -13
- data/test/mws/feeds/parsers/test_feed_submission_info.rb +0 -25
- data/test/mws/feeds/parsers/test_feed_submission_list.rb +0 -18
- data/test/mws/feeds/parsers/test_feed_submission_result.rb +0 -13
- data/test/mws/feeds/parsers/test_feed_submissions.rb +0 -17
- data/test/mws/feeds/requests/test_feed.rb +0 -63
- data/test/mws/feeds/requests/test_feed_submission_count.rb +0 -23
- data/test/mws/feeds/requests/test_feed_submission_list.rb +0 -37
- data/test/mws/feeds/requests/test_feed_submissions.rb +0 -29
- data/test/mws/orders/parsers/test_order.rb +0 -86
- data/test/mws/orders/parsers/test_order_item.rb +0 -69
- data/test/mws/orders/parsers/test_order_items.rb +0 -18
- data/test/mws/orders/parsers/test_orders.rb +0 -18
- data/test/mws/orders/parsers/test_payment_execution_detail.rb +0 -14
- data/test/mws/orders/parsers/test_payment_execution_detail_item.rb +0 -17
- data/test/mws/orders/parsers/test_service_status.rb +0 -39
- data/test/mws/orders/parsers/test_service_status_message.rb +0 -17
- data/test/mws/orders/parsers/test_shipping_address.rb +0 -36
- data/test/mws/orders/requests/test_order_items.rb +0 -36
- data/test/mws/orders/requests/test_orders.rb +0 -46
- data/test/mws/orders/requests/test_service_status.rb +0 -25
- data/test/mws/reports/parsers/test_report_acknowledgments.rb +0 -14
- data/test/mws/reports/parsers/test_report_count.rb +0 -13
- data/test/mws/reports/parsers/test_report_info.rb +0 -29
- data/test/mws/reports/parsers/test_report_list.rb +0 -18
- data/test/mws/reports/parsers/test_report_request.rb +0 -13
- data/test/mws/reports/parsers/test_report_request_count.rb +0 -13
- data/test/mws/reports/parsers/test_report_request_info.rb +0 -49
- data/test/mws/reports/parsers/test_report_request_list.rb +0 -18
- data/test/mws/reports/parsers/test_report_requests.rb +0 -17
- data/test/mws/reports/parsers/test_report_schedule_count.rb +0 -13
- data/test/mws/reports/parsers/test_report_schedule_list.rb +0 -18
- data/test/mws/reports/parsers/test_report_scheduler.rb +0 -17
- data/test/mws/reports/requests/test_acknowledgements.rb +0 -36
- data/test/mws/reports/requests/test_report_count.rb +0 -23
- data/test/mws/reports/requests/test_report_list.rb +0 -39
- data/test/mws/reports/requests/test_report_request.rb +0 -31
- data/test/mws/reports/requests/test_report_request_count.rb +0 -23
- data/test/mws/reports/requests/test_report_request_list.rb +0 -44
- data/test/mws/reports/requests/test_report_requests.rb +0 -29
- data/test/mws/reports/requests/test_report_schedule_count.rb +0 -22
- data/test/mws/reports/requests/test_report_schedule_list.rb +0 -36
- data/test/mws/reports/requests/test_report_scheduler.rb +0 -33
- data/test/mws/sellers/parsers/test_market_participations.rb +0 -19
- data/test/mws/sellers/parsers/test_service_status.rb +0 -35
- data/test/mws/sellers/requests/test_marketplace_participation_list.rb +0 -39
- data/test/mws/sellers/requests/test_service_status.rb +0 -25
- data/test/parser_helper.rb +0 -11
- data/test/peddler/parsers/test_collection.rb +0 -8
- data/test/peddler/parsers/test_model.rb +0 -70
- data/test/peddler/request/test_parameters.rb +0 -35
- data/test/peddler/test_client.rb +0 -42
- data/test/request_helper.rb +0 -20
data/lib/peddler/client.rb
CHANGED
@@ -1,45 +1,33 @@
|
|
1
|
-
require 'forwardable'
|
2
1
|
require 'jeff'
|
2
|
+
require 'peddler/operation'
|
3
|
+
require 'peddler/parser'
|
3
4
|
|
4
5
|
module Peddler
|
6
|
+
# @abstract Subclass to implement an MWS API section.
|
5
7
|
class Client
|
6
|
-
extend Forwardable
|
7
8
|
include Jeff
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(default_country = nil, aws_access_key_id = nil, aws_secret_access_key = nil, merchant_id = nil)
|
12
|
-
@default_country = default_country
|
13
|
-
@aws_access_key_id = aws_access_key_id || ENV['AWS_ACCESS_KEY_ID']
|
14
|
-
@aws_secret_access_key = aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY']
|
15
|
-
@merchant_id = merchant_id || ENV['MERCHANT_ID']
|
16
|
-
end
|
10
|
+
BadMarketplaceId = Class.new(StandardError)
|
17
11
|
|
18
12
|
HOSTS = {
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'
|
22
|
-
'
|
23
|
-
'
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'
|
28
|
-
'
|
13
|
+
'A2EUQ1WTGCTBG2' => 'mws.amazonservices.ca',
|
14
|
+
'AAHKV2X7AFYLW' => 'mws.amazonservices.com.cn',
|
15
|
+
'A1PA6795UKMFR9' => 'mws-eu.amazonservices.com',
|
16
|
+
'A1RKKUPIHCS9HS' => 'mws-eu.amazonservices.com',
|
17
|
+
'A13V1IB3VIYZZH' => 'mws-eu.amazonservices.com',
|
18
|
+
'A1F83G8C2ARO7P' => 'mws-eu.amazonservices.com',
|
19
|
+
'A21TJRUUN4KGV' => 'mws.amazonservices.in',
|
20
|
+
'APJ6JRA9NG5V4' => 'mws-eu.amazonservices.com',
|
21
|
+
'A1VC38T7YXB528' => 'mws.amazonservices.jp',
|
22
|
+
'ATVPDKIKX0DER' => 'mws.amazonservices.com'
|
29
23
|
}
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
'GB' => 'A1F83G8C2ARO7P',
|
38
|
-
'IN' => 'A21TJRUUN4KGV',
|
39
|
-
'IT' => 'APJ6JRA9NG5V4',
|
40
|
-
'JP' => 'A1VC38T7YXB528',
|
41
|
-
'US' => 'ATVPDKIKX0DER'
|
42
|
-
}
|
25
|
+
attr_writer :merchant_id, :marketplace_id
|
26
|
+
attr_reader :body
|
27
|
+
|
28
|
+
alias :configure :tap
|
29
|
+
|
30
|
+
params('SellerId' => -> { merchant_id })
|
43
31
|
|
44
32
|
def self.path(path = nil)
|
45
33
|
path ? @path = path : @path
|
@@ -49,14 +37,66 @@ module Peddler
|
|
49
37
|
base.params(params)
|
50
38
|
end
|
51
39
|
|
52
|
-
params('SellerId' => -> { merchant_id })
|
53
|
-
|
54
40
|
def aws_endpoint
|
55
|
-
"https://#{
|
41
|
+
"https://#{host}/#{self.class.path}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def marketplace_id
|
45
|
+
@marketplace_id ||= ENV['MWS_MARKETPLACE_ID']
|
46
|
+
end
|
47
|
+
|
48
|
+
def merchant_id
|
49
|
+
@merchant_id ||= ENV['MWS_MERCHANT_ID']
|
50
|
+
end
|
51
|
+
|
52
|
+
def headers
|
53
|
+
@headers ||= {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def body=(str)
|
57
|
+
headers['Content-Type'] = content_type(str)
|
58
|
+
@body = str
|
59
|
+
end
|
60
|
+
|
61
|
+
def operation(action = nil)
|
62
|
+
action ? @operation = Operation.new(action) : @operation
|
63
|
+
end
|
64
|
+
|
65
|
+
def run(parser = Parser, &blk)
|
66
|
+
opts = { query: operation, headers: headers, expects: 200 }
|
67
|
+
opts.store(:body, body) if body
|
68
|
+
opts.store(:response_block, blk) if block_given?
|
69
|
+
res = post(opts)
|
70
|
+
|
71
|
+
parser.parse(res)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def content_type(str)
|
77
|
+
if str.start_with?('<?xml')
|
78
|
+
'text/xml'
|
79
|
+
else
|
80
|
+
"text/tab-separated-values; charset=#{host_encoding}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def host_encoding
|
85
|
+
if host.end_with?('jp')
|
86
|
+
'Shift_JIS'
|
87
|
+
elsif host.end_with?('cn')
|
88
|
+
'UTF-16'
|
89
|
+
else
|
90
|
+
'ISO-8859-1'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def host
|
95
|
+
HOSTS.fetch(marketplace_id) { raise BadMarketplaceId }
|
56
96
|
end
|
57
97
|
|
58
|
-
def
|
59
|
-
|
98
|
+
def extract_options(args)
|
99
|
+
args.last.is_a?(Hash) ? args.pop : {}
|
60
100
|
end
|
61
101
|
end
|
62
102
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'csv'
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
module Peddler
|
6
|
+
# @api private
|
7
|
+
class CSVParser < SimpleDelegator
|
8
|
+
attr :content, :summary
|
9
|
+
|
10
|
+
def initialize(res)
|
11
|
+
super(res)
|
12
|
+
split_body
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse
|
16
|
+
# http://stackoverflow.com/questions/8073920/importing-csv-quoting-error-is-driving-me-nuts
|
17
|
+
CSV.parse(content, col_sep: "\t", quote_char: "\x00", headers: true) if content
|
18
|
+
end
|
19
|
+
|
20
|
+
def records_count
|
21
|
+
Hash[summary.split("\n\t")[1, 2].map { |line| line.split("\t\t") }]
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?
|
25
|
+
headers['Content-MD5'] == Digest::MD5.base64digest(body)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def split_body
|
31
|
+
@summary, @content = body.split("\n\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
def scrub_content
|
35
|
+
content.force_encoding(encoding).encode('UTF-8')
|
36
|
+
end
|
37
|
+
|
38
|
+
def encoding
|
39
|
+
'ISO-8859-1'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'time'
|
3
|
+
require 'peddler/structured_list'
|
4
|
+
|
5
|
+
module Peddler
|
6
|
+
# @api private
|
7
|
+
class Operation < SimpleDelegator
|
8
|
+
def initialize(action)
|
9
|
+
super('Action' => action)
|
10
|
+
end
|
11
|
+
|
12
|
+
def structure!(*list_keys)
|
13
|
+
list_key = list_keys.first
|
14
|
+
|
15
|
+
if has_key?(list_key)
|
16
|
+
builder = StructuredList.new(*list_keys)
|
17
|
+
vals = delete(list_key)
|
18
|
+
update(builder.build(vals))
|
19
|
+
end
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def store(key, val)
|
25
|
+
key = camelize(key) if key.is_a?(Symbol)
|
26
|
+
val = val.iso8601 if val.respond_to?(:iso8601)
|
27
|
+
|
28
|
+
__getobj__.store(key, val)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update(hsh)
|
32
|
+
hsh.each { |key, val| store(key, val) }
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
alias :add :update
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def camelize(sym)
|
41
|
+
sym.to_s.split('_').map(&:capitalize).join
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'peddler/csv_parser'
|
2
|
+
require 'peddler/xml_parser'
|
3
|
+
|
4
|
+
module Peddler
|
5
|
+
# @api private
|
6
|
+
module Parser
|
7
|
+
def self.parse(res)
|
8
|
+
# Don't parse if there's no body
|
9
|
+
return res unless res.body
|
10
|
+
|
11
|
+
case res.headers['Content-Type']
|
12
|
+
when 'text/xml'
|
13
|
+
XMLParser.new(res)
|
14
|
+
when 'application/octet-stream'
|
15
|
+
CSVParser.new(res)
|
16
|
+
else
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Peddler
|
2
|
+
# @api private
|
3
|
+
class StructuredList
|
4
|
+
def initialize(*keys)
|
5
|
+
@keys = keys
|
6
|
+
end
|
7
|
+
|
8
|
+
def build(vals)
|
9
|
+
Array(vals)
|
10
|
+
.each_with_index
|
11
|
+
.reduce(Hash.new) { |hsh, (v, i)|
|
12
|
+
hsh.merge(compose_key(i + 1) => v)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def compose_key(index)
|
19
|
+
(@keys.dup << index).join('.')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/peddler/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'multi_xml'
|
3
|
+
|
4
|
+
module Peddler
|
5
|
+
# @api private
|
6
|
+
class XMLParser < SimpleDelegator
|
7
|
+
def next_token
|
8
|
+
parse.fetch('NextToken', false)
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse
|
12
|
+
@result ||= find_result
|
13
|
+
end
|
14
|
+
|
15
|
+
def xml
|
16
|
+
MultiXml.parse(body)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def find_result
|
22
|
+
xml.values[0].find { |k, v| k.include?('Result') }.last
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/peddler.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/feeds'
|
3
|
+
|
4
|
+
class FeedsTest < IntegrationTest
|
5
|
+
def test_gets_feed_submission_count
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.get_feed_submission_count
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_gets_feed_submission_list
|
13
|
+
clients.each do |client|
|
14
|
+
res = client.get_feed_submission_list
|
15
|
+
refute_empty res.parse
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/orders'
|
3
|
+
|
4
|
+
class OrdersTest < IntegrationTest
|
5
|
+
def a_year_ago
|
6
|
+
Date.today - 365
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_lists_orders
|
10
|
+
clients.each do |client|
|
11
|
+
res = client.list_orders(created_after: a_year_ago)
|
12
|
+
refute_empty res.parse
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_gets_service_status
|
17
|
+
clients.each do |client|
|
18
|
+
res = client.get_service_status
|
19
|
+
refute_empty res.parse
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/products'
|
3
|
+
|
4
|
+
class ProductsTest < IntegrationTest
|
5
|
+
def test_lists_matching_products
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.list_matching_products('architecture')
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_gets_matching_product
|
13
|
+
clients.each do |client|
|
14
|
+
res = client.get_matching_product('1780935374')
|
15
|
+
refute_empty res.parse
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_gets_matching_product_for_id
|
20
|
+
clients.each do |client|
|
21
|
+
res = client.get_matching_product_for_id('ISBN', '9781780935379')
|
22
|
+
refute_empty res.parse
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_gets_competitive_pricing_for_asin
|
27
|
+
clients.each do |client|
|
28
|
+
res = client.get_competitive_pricing_for_asin('1780935374')
|
29
|
+
refute_empty res.parse
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_gets_lowest_offer_listings_for_asin
|
34
|
+
clients.each do |client|
|
35
|
+
res = client.get_lowest_offer_listings_for_asin('1780935374')
|
36
|
+
refute_empty res.parse
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_gets_product_categories_for_asin
|
41
|
+
clients.each do |client|
|
42
|
+
res = client.get_product_categories_for_asin('1780935374')
|
43
|
+
refute_empty res.parse
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_gets_service_status
|
48
|
+
clients.each do |client|
|
49
|
+
res = client.get_service_status
|
50
|
+
refute_empty res.parse
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/reports'
|
3
|
+
|
4
|
+
class ReportsTest < IntegrationTest
|
5
|
+
def test_gets_report_request_count
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.get_report_request_count
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_gets_report_request_list
|
13
|
+
clients.each do |client|
|
14
|
+
res = client.get_report_request_list
|
15
|
+
refute_empty res.parse
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_gets_report_schedule_count
|
20
|
+
clients.each do |client|
|
21
|
+
res = client.get_report_schedule_count
|
22
|
+
refute_empty res.parse
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_lists_report_schedules
|
27
|
+
clients.each do |client|
|
28
|
+
res = client.get_report_schedule_list
|
29
|
+
refute_empty res.parse
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_gets_report_count
|
34
|
+
skip("Some endpoints don't work")
|
35
|
+
clients.each do |client|
|
36
|
+
res = client.get_report_count
|
37
|
+
refute_empty res.parse
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_gets_report_list
|
42
|
+
clients.each do |client|
|
43
|
+
res = client.get_report_list
|
44
|
+
refute_empty res.parse
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/sellers'
|
3
|
+
|
4
|
+
class SellersTest < IntegrationTest
|
5
|
+
def test_lists_marketplace_participations
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.list_marketplace_participations
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_gets_service_status
|
13
|
+
clients.each do |client|
|
14
|
+
res = client.get_service_status
|
15
|
+
refute_empty res.parse
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/subscriptions'
|
3
|
+
|
4
|
+
class SubscriptionsTest < IntegrationTest
|
5
|
+
def test_lists_registered_destinations
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.list_registered_destinations
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def test_lists_subscriptions
|
14
|
+
clients.each do |client|
|
15
|
+
res = client.list_subscriptions
|
16
|
+
refute_empty res.parse
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_gets_service_status
|
21
|
+
clients.each do |client|
|
22
|
+
res = client.get_service_status
|
23
|
+
refute_empty res.parse
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/integration_helper.rb
CHANGED
@@ -1,19 +1,52 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'vcr'
|
3
|
+
|
2
4
|
require 'helper'
|
3
5
|
|
6
|
+
VCR.configure do |c|
|
7
|
+
c.hook_into :excon
|
8
|
+
c.cassette_library_dir = 'test/vcr_cassettes'
|
9
|
+
|
10
|
+
c.before_record do |interaction|
|
11
|
+
interaction.ignore! if interaction.response.status.code >= 400
|
12
|
+
end
|
13
|
+
|
14
|
+
nondeterministic_params = %w(
|
15
|
+
AWSAccessKeyId SellerId Signature Timestamp StartDate CreatedAfter
|
16
|
+
Destination.AttributeList.member.1.Value
|
17
|
+
)
|
18
|
+
matcher = VCR.request_matchers.uri_without_param(*nondeterministic_params)
|
19
|
+
c.default_cassette_options = {
|
20
|
+
match_requests_on: [:method, matcher],
|
21
|
+
record: :new_episodes
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
4
25
|
class IntegrationTest < MiniTest::Test
|
5
|
-
|
6
|
-
|
26
|
+
def api_name
|
27
|
+
self.class.name.match(/(.*)Test/)[1]
|
7
28
|
end
|
8
29
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
30
|
+
def clients
|
31
|
+
accounts = begin
|
32
|
+
YAML.load_file(File.expand_path('../mws.yml', __FILE__)).shuffle
|
33
|
+
rescue Errno::ENOENT
|
34
|
+
warn('Skipping integration tests')
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
|
38
|
+
accounts.map do |account|
|
39
|
+
MWS.const_get(api_name).new.configure do |c|
|
40
|
+
account.each { |k, v| c.send("#{k}=", v) }
|
41
|
+
end
|
42
|
+
end
|
14
43
|
end
|
15
44
|
|
16
45
|
def setup
|
17
|
-
|
46
|
+
VCR.insert_cassette(api_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def teardown
|
50
|
+
VCR.eject_cassette
|
18
51
|
end
|
19
52
|
end
|
data/test/mws.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
- marketplace_id: A2EUQ1WTGCTBG2
|
2
|
+
aws_access_key_id: AKIAITHQMZUJROSOP27Q
|
3
|
+
aws_secret_access_key: YDCmgpYmM5q2ucqLAeFUEbYKOAADvorsfJOgY5N6
|
4
|
+
merchant_id: A2A7WNXBU01UJW
|
5
|
+
- marketplace_id: A1PA6795UKMFR9
|
6
|
+
aws_access_key_id: AKIAIORT7554FEBW7UBQ
|
7
|
+
aws_secret_access_key: P2ocOVChe/dQUpxRfA1n3TmP+wHrF6GaSzXslvEG
|
8
|
+
merchant_id: A7ZXDJZD3UIRG
|
9
|
+
- marketplace_id: A1RKKUPIHCS9HS
|
10
|
+
aws_access_key_id: AKIAI6X4QZRXSHGHABJA
|
11
|
+
aws_secret_access_key: FVGVfjOHDnyzjtQvFODKtZcrQhziL2Ka9wKARNk7
|
12
|
+
merchant_id: A2NEU7G6RGUKF
|
13
|
+
- marketplace_id: A13V1IB3VIYZZH
|
14
|
+
aws_access_key_id: AKIAI4ZNSD76DH7UBRDA
|
15
|
+
aws_secret_access_key: FUwcEYYsesa1wpaKQYJebfE0rjuIKkyOl2GMnhY0
|
16
|
+
merchant_id: A2DP6GIDYN6OTH
|
17
|
+
- marketplace_id: A1F83G8C2ARO7P
|
18
|
+
aws_access_key_id: AKIAJJDQ2MJTMPXKJE4A
|
19
|
+
aws_secret_access_key: BhGTh8zXIEuMjKlRJIrX+cXYqWFFYmzcGXscGblS
|
20
|
+
merchant_id: A2D9DZ30GEWP6N
|
21
|
+
- marketplace_id: APJ6JRA9NG5V4
|
22
|
+
aws_access_key_id: AKIAJLUHOXLR5S2L6A6A
|
23
|
+
aws_secret_access_key: 5yiCg1/KXmbf4PqeXzlf/1Q6346rAl2brJ/5WLn/
|
24
|
+
merchant_id: A2APQUVDBVWV7E
|
25
|
+
- marketplace_id: A1VC38T7YXB528
|
26
|
+
aws_access_key_id: AKIAJ5RDDSRROM6GXQ5Q
|
27
|
+
aws_secret_access_key: WGPMtwkUvlRXg22byoI+ceXyhnDQOMozUoFmsHzW
|
28
|
+
merchant_id: A7BU5WGNVGQ1I
|
29
|
+
- marketplace_id: ATVPDKIKX0DER
|
30
|
+
aws_access_key_id: AKIAJ767ZET2BZR4UDDQ
|
31
|
+
aws_secret_access_key: rONa3ydPBTJ5JD0bxERTOX0Fv0fBK6Q986/cfMRO
|
32
|
+
merchant_id: A2H6NH4SQYFZ4M
|