active_fulfillment 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/active_fulfillment.gemspec +53 -49
- data/lib/active_fulfillment.rb +10 -0
- data/lib/active_fulfillment/fulfillment/services/amazon.rb +52 -3
- data/lib/active_fulfillment/fulfillment/services/shipwire.rb +7 -5
- data/lib/active_fulfillment/fulfillment/services/webgistix.rb +92 -25
- data/lib/active_merchant/common/connection.rb +3 -13
- data/lib/active_merchant/common/country.rb +15 -6
- data/lib/active_merchant/common/posts_data.rb +18 -4
- data/test/fixtures/xml/amazon/tracking_response_1.xml +56 -0
- data/test/fixtures/xml/amazon/tracking_response_2.xml +38 -0
- data/test/fixtures/xml/amazon/tracking_response_error.xml +13 -0
- data/test/fixtures/xml/amazon/tracking_response_not_found.xml +13 -0
- data/test/fixtures/xml/webgistix/tracking_response.xml +14 -0
- data/test/remote/amazon_test.rb +12 -0
- data/test/remote/shipwire_test.rb +2 -2
- data/test/remote/webgistix_test.rb +13 -3
- data/test/unit/services/amazon_test.rb +43 -0
- data/test/unit/services/shipwire_test.rb +7 -4
- data/test/unit/services/webgistix_test.rb +34 -4
- metadata +12 -7
data/CHANGELOG
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= ActiveFulfillment CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.0.1 (Dec 13, 2010)
|
4
|
+
|
5
|
+
* Updated common files with changes from activemerchant [Dennis Theisen]
|
6
|
+
* Updated Webgistix USPS shipping methods (4 added, 1 removed) [Dennis Theisen]
|
7
|
+
* Changed Webgistix to treat a duplicate response as success instead of failure and to retry failed connection errors. [Dennis Theisen]
|
8
|
+
|
3
9
|
== Version 1.0.0 (July 12, 2010)
|
4
10
|
|
5
11
|
* Add inventory support to Amazon and Webgistix [Adrian Irving-Beer]
|
data/Rakefile
CHANGED
@@ -47,13 +47,14 @@ begin
|
|
47
47
|
gemspec.email = "cody@shopify.com"
|
48
48
|
gemspec.homepage = "http://github.com/shopify/active_fulfillment"
|
49
49
|
gemspec.authors = ["Cody Fauser", "James MacAulay"]
|
50
|
-
gemspec.add_dependency('activesupport', '
|
50
|
+
gemspec.add_dependency('activesupport', '>= 2.3.2')
|
51
51
|
gemspec.add_dependency('builder', '>= 2.0.0')
|
52
52
|
end
|
53
53
|
rescue LoadError
|
54
54
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
55
55
|
end
|
56
56
|
|
57
|
+
desc "Update common files from active_merchant directory"
|
57
58
|
task :update_common do
|
58
59
|
STDERR.puts "Updating common include from ../active_merchant. Please make sure this is up-to-date"
|
59
60
|
system("diff -u lib/active_merchant/common.rb ../active_merchant/lib/active_merchant/common.rb | patch -p0")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
data/active_fulfillment.gemspec
CHANGED
@@ -1,68 +1,72 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{active_fulfillment}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Cody Fauser", "James MacAulay"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-13}
|
13
13
|
s.email = %q{cody@shopify.com}
|
14
14
|
s.files = [
|
15
15
|
"CHANGELOG",
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
16
|
+
"Rakefile",
|
17
|
+
"VERSION",
|
18
|
+
"active_fulfillment.gemspec",
|
19
|
+
"init.rb",
|
20
|
+
"lib/active_fulfillment.rb",
|
21
|
+
"lib/active_fulfillment/fulfillment/base.rb",
|
22
|
+
"lib/active_fulfillment/fulfillment/response.rb",
|
23
|
+
"lib/active_fulfillment/fulfillment/service.rb",
|
24
|
+
"lib/active_fulfillment/fulfillment/services.rb",
|
25
|
+
"lib/active_fulfillment/fulfillment/services/amazon.rb",
|
26
|
+
"lib/active_fulfillment/fulfillment/services/shipwire.rb",
|
27
|
+
"lib/active_fulfillment/fulfillment/services/webgistix.rb",
|
28
|
+
"lib/active_merchant/common.rb",
|
29
|
+
"lib/active_merchant/common/connection.rb",
|
30
|
+
"lib/active_merchant/common/country.rb",
|
31
|
+
"lib/active_merchant/common/error.rb",
|
32
|
+
"lib/active_merchant/common/post_data.rb",
|
33
|
+
"lib/active_merchant/common/posts_data.rb",
|
34
|
+
"lib/active_merchant/common/requires_parameters.rb",
|
35
|
+
"lib/active_merchant/common/utils.rb",
|
36
|
+
"lib/active_merchant/common/validateable.rb",
|
37
|
+
"lib/certs/cacert.pem",
|
38
|
+
"test/fixtures.yml",
|
39
|
+
"test/fixtures/xml/amazon/inventory_get_response.xml",
|
40
|
+
"test/fixtures/xml/amazon/inventory_list_response.xml",
|
41
|
+
"test/fixtures/xml/amazon/inventory_list_response_with_next_1.xml",
|
42
|
+
"test/fixtures/xml/amazon/inventory_list_response_with_next_2.xml",
|
43
|
+
"test/fixtures/xml/amazon/tracking_response_1.xml",
|
44
|
+
"test/fixtures/xml/amazon/tracking_response_2.xml",
|
45
|
+
"test/fixtures/xml/amazon/tracking_response_error.xml",
|
46
|
+
"test/fixtures/xml/amazon/tracking_response_not_found.xml",
|
47
|
+
"test/fixtures/xml/webgistix/tracking_response.xml",
|
48
|
+
"test/remote/amazon_test.rb",
|
49
|
+
"test/remote/shipwire_test.rb",
|
50
|
+
"test/remote/webgistix_test.rb",
|
51
|
+
"test/test_helper.rb",
|
52
|
+
"test/unit/base_test.rb",
|
53
|
+
"test/unit/services/amazon_test.rb",
|
54
|
+
"test/unit/services/shipwire_test.rb",
|
55
|
+
"test/unit/services/webgistix_test.rb"
|
51
56
|
]
|
52
57
|
s.homepage = %q{http://github.com/shopify/active_fulfillment}
|
53
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
54
58
|
s.require_paths = ["lib"]
|
55
59
|
s.rubygems_version = %q{1.3.7}
|
56
60
|
s.summary = %q{Framework and tools for dealing with shipping, tracking and order fulfillment services.}
|
57
61
|
s.test_files = [
|
58
62
|
"test/remote/amazon_test.rb",
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
"test/remote/shipwire_test.rb",
|
64
|
+
"test/remote/webgistix_test.rb",
|
65
|
+
"test/test_helper.rb",
|
66
|
+
"test/unit/base_test.rb",
|
67
|
+
"test/unit/services/amazon_test.rb",
|
68
|
+
"test/unit/services/shipwire_test.rb",
|
69
|
+
"test/unit/services/webgistix_test.rb"
|
66
70
|
]
|
67
71
|
|
68
72
|
if s.respond_to? :specification_version then
|
@@ -70,14 +74,14 @@ Gem::Specification.new do |s|
|
|
70
74
|
s.specification_version = 3
|
71
75
|
|
72
76
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
73
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
77
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
|
74
78
|
s.add_runtime_dependency(%q<builder>, [">= 2.0.0"])
|
75
79
|
else
|
76
|
-
s.add_dependency(%q<activesupport>, ["
|
80
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.2"])
|
77
81
|
s.add_dependency(%q<builder>, [">= 2.0.0"])
|
78
82
|
end
|
79
83
|
else
|
80
|
-
s.add_dependency(%q<activesupport>, ["
|
84
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.2"])
|
81
85
|
s.add_dependency(%q<builder>, [">= 2.0.0"])
|
82
86
|
end
|
83
87
|
end
|
data/lib/active_fulfillment.rb
CHANGED
@@ -30,6 +30,16 @@ rescue LoadError
|
|
30
30
|
require 'active_support'
|
31
31
|
end
|
32
32
|
|
33
|
+
require 'active_support/core_ext/class/inheritable_attributes'
|
34
|
+
require 'active_support/core_ext/class/delegating_attributes'
|
35
|
+
require 'active_support/core_ext/time/calculations'
|
36
|
+
require 'active_support/core_ext/numeric/time'
|
37
|
+
require 'active_support/core_ext/enumerable'
|
38
|
+
begin
|
39
|
+
require 'active_support/core_ext/time/acts_like'
|
40
|
+
rescue LoadError
|
41
|
+
end
|
42
|
+
|
33
43
|
begin
|
34
44
|
require 'builder'
|
35
45
|
rescue LoadError
|
@@ -54,7 +54,8 @@ module ActiveMerchant
|
|
54
54
|
:outbound => {
|
55
55
|
:status => 'GetServiceStatus',
|
56
56
|
:create => 'CreateFulfillmentOrder',
|
57
|
-
:list => 'ListAllFulfillmentOrders'
|
57
|
+
:list => 'ListAllFulfillmentOrders',
|
58
|
+
:tracking => 'GetFulfillmentOrder'
|
58
59
|
},
|
59
60
|
:inventory => {
|
60
61
|
:get => 'GetInventorySupply',
|
@@ -113,6 +114,26 @@ module ActiveMerchant
|
|
113
114
|
response
|
114
115
|
end
|
115
116
|
end
|
117
|
+
|
118
|
+
def fetch_tracking_numbers(order_ids, options = {})
|
119
|
+
order_ids.inject(nil) do |previous, o_id|
|
120
|
+
response = commit :outbound, :tracking, build_tracking_request(o_id, options)
|
121
|
+
|
122
|
+
if !response.success?
|
123
|
+
if response.faultstring =~ /Reason: requested order not found./
|
124
|
+
response = Response.new(true, nil, {
|
125
|
+
:status => SUCCESS,
|
126
|
+
:tracking_numbers => {}
|
127
|
+
})
|
128
|
+
else
|
129
|
+
return response
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
response.tracking_numbers.merge!(previous.tracking_numbers) if previous
|
134
|
+
response
|
135
|
+
end
|
136
|
+
end
|
116
137
|
|
117
138
|
def valid_credentials?
|
118
139
|
status.success?
|
@@ -202,6 +223,15 @@ module ActiveMerchant
|
|
202
223
|
end
|
203
224
|
end
|
204
225
|
|
226
|
+
def build_tracking_request(order_id, options)
|
227
|
+
request = OPERATIONS[:outbound][:tracking]
|
228
|
+
soap_request(request) do |xml|
|
229
|
+
xml.tag! request, { 'xmlns' => SERVICES[:outbound][:xmlns] } do
|
230
|
+
xml.tag! "MerchantFulfillmentOrderId", order_id
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
205
235
|
def add_credentials(xml, request)
|
206
236
|
login = @options[:login]
|
207
237
|
timestamp = "#{Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S")}Z"
|
@@ -264,7 +294,12 @@ module ActiveMerchant
|
|
264
294
|
|
265
295
|
case service
|
266
296
|
when :outbound
|
267
|
-
|
297
|
+
case op
|
298
|
+
when :tracking
|
299
|
+
parse_tracking_response(document)
|
300
|
+
else
|
301
|
+
parse_fulfillment_response(op, document)
|
302
|
+
end
|
268
303
|
when :inventory
|
269
304
|
parse_inventory_response(document)
|
270
305
|
else
|
@@ -288,7 +323,7 @@ module ActiveMerchant
|
|
288
323
|
|
289
324
|
document.each_element('//ns1:MerchantSKUSupply') do |node|
|
290
325
|
# {MerchantSKU => 'SOME-ID', InStockSupplyQuantity => '101', ...}
|
291
|
-
params = node.elements.to_a.
|
326
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
292
327
|
|
293
328
|
response[:stock_levels][params['MerchantSKU']] = params['InStockSupplyQuantity'].to_i
|
294
329
|
end
|
@@ -300,6 +335,20 @@ module ActiveMerchant
|
|
300
335
|
response
|
301
336
|
end
|
302
337
|
|
338
|
+
def parse_tracking_response(document)
|
339
|
+
response = {}
|
340
|
+
response[:tracking_numbers] = {}
|
341
|
+
|
342
|
+
track_node = REXML::XPath.first(document, '//ns1:FulfillmentShipmentPackage/ns1:TrackingNumber')
|
343
|
+
if track_node
|
344
|
+
id_node = REXML::XPath.first(document, '//ns1:MerchantFulfillmentOrderId')
|
345
|
+
response[:tracking_numbers][id_node.text] = track_node.text
|
346
|
+
end
|
347
|
+
|
348
|
+
response[:response_status] = SUCCESS
|
349
|
+
response
|
350
|
+
end
|
351
|
+
|
303
352
|
def parse_error(http_response)
|
304
353
|
response = {}
|
305
354
|
response[:http_code] = http_response.code
|
@@ -54,12 +54,12 @@ module ActiveMerchant
|
|
54
54
|
commit :inventory, build_inventory_request(options)
|
55
55
|
end
|
56
56
|
|
57
|
-
def fetch_tracking_numbers(
|
58
|
-
commit :tracking, build_tracking_request(
|
57
|
+
def fetch_tracking_numbers(order_ids)
|
58
|
+
commit :tracking, build_tracking_request(order_ids)
|
59
59
|
end
|
60
60
|
|
61
61
|
def valid_credentials?
|
62
|
-
response = fetch_tracking_numbers
|
62
|
+
response = fetch_tracking_numbers([])
|
63
63
|
response.message !~ INVALID_LOGIN
|
64
64
|
end
|
65
65
|
|
@@ -91,14 +91,16 @@ module ActiveMerchant
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def build_tracking_request(
|
94
|
+
def build_tracking_request(order_ids)
|
95
95
|
xml = Builder::XmlMarkup.new
|
96
96
|
xml.instruct!
|
97
97
|
xml.declare! :DOCTYPE, :InventoryStatus, :SYSTEM, SCHEMA_URLS[:inventory]
|
98
98
|
xml.tag! 'TrackingUpdate' do
|
99
99
|
add_credentials(xml)
|
100
100
|
xml.tag! 'Server', test? ? 'Test' : 'Production'
|
101
|
-
|
101
|
+
order_ids.each do |o_id|
|
102
|
+
xml.tag! 'OrderNo', o_id
|
103
|
+
end
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
@@ -3,16 +3,26 @@ module ActiveMerchant
|
|
3
3
|
class WebgistixService < Service
|
4
4
|
SERVICE_URLS = {
|
5
5
|
:fulfillment => 'https://www.webgistix.com/XML/CreateOrder.asp',
|
6
|
-
:inventory => 'https://www.webgistix.com/XML/GetInventory.asp'
|
6
|
+
:inventory => 'https://www.webgistix.com/XML/GetInventory.asp',
|
7
|
+
:tracking => 'https://www.webgistix.com/XML/GetTracking.asp'
|
7
8
|
}
|
8
9
|
TEST_URLS = SERVICE_URLS.merge({
|
9
10
|
:fulfillment => 'https://www.webgistix.com/XML/CreateOrderTest.asp'
|
10
11
|
})
|
12
|
+
|
13
|
+
SUCCESS, DUPLICATE, FAILURE = 'True', 'Duplicate', 'False'
|
11
14
|
|
12
|
-
SUCCESS, FAILURE = 'True', 'False'
|
13
15
|
SUCCESS_MESSAGE = 'Successfully submitted the order'
|
14
16
|
FAILURE_MESSAGE = 'Failed to submit the order'
|
15
|
-
|
17
|
+
DUPLICATE_MESSAGE = 'This order has already been successfully submitted'
|
18
|
+
|
19
|
+
INVALID_LOGIN = 'Invalid Credentials'
|
20
|
+
NOT_SHIPPED = 'Not Shipped'
|
21
|
+
|
22
|
+
# If a request is detected as a duplicate only the original data will be
|
23
|
+
# used by Webgistix, and the subsequent responses will have a
|
24
|
+
# :duplicate parameter set in the params hash.
|
25
|
+
self.retry_safe = true
|
16
26
|
|
17
27
|
# The first is the label, and the last is the code
|
18
28
|
def self.shipping_methods
|
@@ -37,16 +47,18 @@ module ActiveMerchant
|
|
37
47
|
["FedEx International Economy", "FedEx International Economy"],
|
38
48
|
["FedEx International First", "FedEx International First"],
|
39
49
|
["FedEx Ground", "FedEx Ground"],
|
40
|
-
["USPS Priority Mail
|
41
|
-
["USPS Priority Mail
|
50
|
+
["USPS Priority Mail", "Priority Mail"],
|
51
|
+
["USPS Priority Mail International", "Priority Mail International"],
|
52
|
+
["USPS Priority Mail Small Flat Rate Box", "Priority Mail Small Flat Rate Box"],
|
53
|
+
["USPS Priority Mail Medium Flat Rate Box", "Priority Mail Medium Flat Rate Box"],
|
54
|
+
["USPS Priority Mail Large Flat Rate Box", "Priority Mail Large Flat Rate Box"],
|
55
|
+
["USPS Priority Mail Flat Rate Envelope", "Priority Mail Flat Rate Envelope"],
|
42
56
|
["USPS First Class Mail", "First Class"],
|
43
|
-
["USPS Express Mail & Global Express Mail", "Express"],
|
44
|
-
["USPS Flat Rate Global Express Mail", "Global Express Mail Flat Rate"],
|
45
|
-
["USPS Parcel Post", "Parcel"],
|
46
57
|
["USPS First Class International", "First Class International"],
|
47
|
-
["USPS
|
48
|
-
["USPS
|
49
|
-
["USPS
|
58
|
+
["USPS Express Mail", "Express"],
|
59
|
+
["USPS Express Mail International", "Express Mail International"],
|
60
|
+
["USPS Parcel Post", "Parcel"],
|
61
|
+
["USPS Media Mail", "Media Mail"]
|
50
62
|
].inject(ActiveSupport::OrderedHash.new){|h, (k,v)| h[k] = v; h}
|
51
63
|
end
|
52
64
|
|
@@ -65,6 +77,10 @@ module ActiveMerchant
|
|
65
77
|
def fetch_stock_levels(options = {})
|
66
78
|
commit :inventory, build_inventory_request(options)
|
67
79
|
end
|
80
|
+
|
81
|
+
def fetch_tracking_numbers(order_ids, options = {})
|
82
|
+
commit :tracking, build_tracking_request(order_ids, options)
|
83
|
+
end
|
68
84
|
|
69
85
|
def valid_credentials?
|
70
86
|
response = fulfill('', {}, [], :shipping_method => '')
|
@@ -124,7 +140,32 @@ module ActiveMerchant
|
|
124
140
|
add_credentials(xml)
|
125
141
|
end
|
126
142
|
end
|
127
|
-
|
143
|
+
|
144
|
+
#<?xml version="1.0"?>
|
145
|
+
# <TrackingXML>
|
146
|
+
# <Password>Webgistix</Password>
|
147
|
+
# <CustomerID>3</CustomerID>
|
148
|
+
# <Tracking>
|
149
|
+
# <Order>AB12345</Order>
|
150
|
+
# </Tracking>
|
151
|
+
# <Tracking>
|
152
|
+
# <Order>XY4567</Order>
|
153
|
+
# </Tracking>
|
154
|
+
# </TrackingXML>
|
155
|
+
def build_tracking_request(order_ids, options)
|
156
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
157
|
+
xml.instruct!
|
158
|
+
xml.tag! 'TrackingXML' do
|
159
|
+
add_credentials(xml)
|
160
|
+
|
161
|
+
order_ids.each do |o_id|
|
162
|
+
xml.tag! 'Tracking' do
|
163
|
+
xml.tag! 'Order', o_id
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
128
169
|
def add_credentials(xml)
|
129
170
|
xml.tag! 'CustomerID', @options[:login]
|
130
171
|
xml.tag! 'Password', @options[:password]
|
@@ -184,13 +225,15 @@ module ActiveMerchant
|
|
184
225
|
end
|
185
226
|
|
186
227
|
def success?(response)
|
187
|
-
response[:success] == SUCCESS
|
228
|
+
response[:success] == SUCCESS || response[:success] == DUPLICATE
|
188
229
|
end
|
189
230
|
|
190
231
|
def message_from(response)
|
191
|
-
|
192
|
-
|
193
|
-
|
232
|
+
if response[:duplicate]
|
233
|
+
DUPLICATE_MESSAGE
|
234
|
+
elsif success?(response)
|
235
|
+
SUCCESS_MESSAGE
|
236
|
+
elsif response[:error_0] == INVALID_LOGIN
|
194
237
|
INVALID_LOGIN
|
195
238
|
else
|
196
239
|
FAILURE_MESSAGE
|
@@ -209,18 +252,15 @@ module ActiveMerchant
|
|
209
252
|
parse_fulfillment_response(document)
|
210
253
|
when :inventory
|
211
254
|
parse_inventory_response(document)
|
255
|
+
when :tracking
|
256
|
+
parse_tracking_response(document)
|
212
257
|
else
|
213
258
|
raise ArgumentError, "Unknown action #{action}"
|
214
259
|
end
|
215
260
|
end
|
216
261
|
|
217
262
|
def parse_fulfillment_response(document)
|
218
|
-
response =
|
219
|
-
|
220
|
-
# Fetch the errors
|
221
|
-
document.root.elements.to_a("Error").each_with_index do |e, i|
|
222
|
-
response["error_#{i}".to_sym] = e.text
|
223
|
-
end
|
263
|
+
response = parse_errors(document)
|
224
264
|
|
225
265
|
# Check if completed
|
226
266
|
if completed = REXML::XPath.first(document, '//Completed')
|
@@ -231,23 +271,50 @@ module ActiveMerchant
|
|
231
271
|
response[:success] = FAILURE
|
232
272
|
end
|
233
273
|
|
274
|
+
response[:duplicate] = response[:success] == DUPLICATE
|
275
|
+
|
234
276
|
response
|
235
277
|
end
|
236
278
|
|
237
279
|
def parse_inventory_response(document)
|
238
|
-
response =
|
280
|
+
response = parse_errors(document)
|
239
281
|
response[:stock_levels] = {}
|
240
282
|
|
241
283
|
document.root.each_element('//Item') do |node|
|
242
284
|
# {ItemID => 'SOME-ID', ItemQty => '101'}
|
243
|
-
params = node.elements.to_a.
|
285
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
244
286
|
|
245
287
|
response[:stock_levels][params['ItemID']] = params['ItemQty'].to_i
|
246
288
|
end
|
247
289
|
|
248
|
-
response[:success] = SUCCESS
|
249
290
|
response
|
250
291
|
end
|
292
|
+
|
293
|
+
def parse_tracking_response(document)
|
294
|
+
response = parse_errors(document)
|
295
|
+
response[:tracking_numbers] = {}
|
296
|
+
|
297
|
+
document.root.each_element('//Shipment') do |node|
|
298
|
+
# {InvoiceNumber => 'SOME-ID', ShipmentTrackingNumber => 'SOME-TRACKING-NUMBER'}
|
299
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
300
|
+
|
301
|
+
tracking = params['ShipmentTrackingNumber']
|
302
|
+
response[:tracking_numbers][params['InvoiceNumber']] = tracking unless tracking == NOT_SHIPPED
|
303
|
+
end
|
304
|
+
|
305
|
+
response
|
306
|
+
end
|
307
|
+
|
308
|
+
def parse_errors(document)
|
309
|
+
response = {}
|
310
|
+
|
311
|
+
REXML::XPath.match(document, "//Errors/Error").to_a.each_with_index do |e, i|
|
312
|
+
response["error_#{i}".to_sym] = e.text
|
313
|
+
end
|
314
|
+
|
315
|
+
response[:success] = response.empty? ? SUCCESS : FAILURE
|
316
|
+
response
|
317
|
+
end
|
251
318
|
end
|
252
319
|
end
|
253
320
|
end
|
@@ -71,9 +71,8 @@ module ActiveMerchant
|
|
71
71
|
end
|
72
72
|
|
73
73
|
info "--> %d %s (%d %.4fs)" % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag
|
74
|
-
|
75
|
-
|
76
|
-
response
|
74
|
+
debug result.body
|
75
|
+
result
|
77
76
|
rescue EOFError => e
|
78
77
|
raise ConnectionError, "The remote server dropped the connection"
|
79
78
|
rescue Errno::ECONNRESET => e
|
@@ -147,15 +146,6 @@ module ActiveMerchant
|
|
147
146
|
end
|
148
147
|
end
|
149
148
|
|
150
|
-
def handle_response(response)
|
151
|
-
case response.code.to_i
|
152
|
-
when 200...300
|
153
|
-
response.body
|
154
|
-
else
|
155
|
-
raise ResponseError.new(response)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
149
|
def debug(message, tag = nil)
|
160
150
|
log(:debug, message, tag)
|
161
151
|
end
|
@@ -169,4 +159,4 @@ module ActiveMerchant
|
|
169
159
|
logger.send(level, message) if logger
|
170
160
|
end
|
171
161
|
end
|
172
|
-
end
|
162
|
+
end
|
@@ -46,7 +46,16 @@ module ActiveMerchant #:nodoc:
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def code(format)
|
49
|
-
@codes.
|
49
|
+
@codes.detect{|c| c.format == format}
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
(@name == other.name)
|
54
|
+
end
|
55
|
+
alias eql? ==
|
56
|
+
|
57
|
+
def hash
|
58
|
+
@name.hash
|
50
59
|
end
|
51
60
|
|
52
61
|
def to_s
|
@@ -67,7 +76,6 @@ module ActiveMerchant #:nodoc:
|
|
67
76
|
{ :alpha2 => 'AW', :name => 'Aruba', :alpha3 => 'ABW', :numeric => '533' },
|
68
77
|
{ :alpha2 => 'AU', :name => 'Australia', :alpha3 => 'AUS', :numeric => '036' },
|
69
78
|
{ :alpha2 => 'AT', :name => 'Austria', :alpha3 => 'AUT', :numeric => '040' },
|
70
|
-
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' },
|
71
79
|
{ :alpha2 => 'AZ', :name => 'Azerbaijan', :alpha3 => 'AZE', :numeric => '031' },
|
72
80
|
{ :alpha2 => 'BS', :name => 'Bahamas', :alpha3 => 'BHS', :numeric => '044' },
|
73
81
|
{ :alpha2 => 'BH', :name => 'Bahrain', :alpha3 => 'BHR', :numeric => '048' },
|
@@ -84,8 +92,8 @@ module ActiveMerchant #:nodoc:
|
|
84
92
|
{ :alpha2 => 'BW', :name => 'Botswana', :alpha3 => 'BWA', :numeric => '072' },
|
85
93
|
{ :alpha2 => 'BV', :name => 'Bouvet Island', :alpha3 => 'BVD', :numeric => '074' },
|
86
94
|
{ :alpha2 => 'BR', :name => 'Brazil', :alpha3 => 'BRA', :numeric => '076' },
|
87
|
-
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
88
95
|
{ :alpha2 => 'IO', :name => 'British Indian Ocean Territory', :alpha3 => 'IOT', :numeric => '086' },
|
96
|
+
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
89
97
|
{ :alpha2 => 'BG', :name => 'Bulgaria', :alpha3 => 'BGR', :numeric => '100' },
|
90
98
|
{ :alpha2 => 'BF', :name => 'Burkina Faso', :alpha3 => 'BFA', :numeric => '854' },
|
91
99
|
{ :alpha2 => 'BI', :name => 'Burundi', :alpha3 => 'BDI', :numeric => '108' },
|
@@ -142,15 +150,15 @@ module ActiveMerchant #:nodoc:
|
|
142
150
|
{ :alpha2 => 'GP', :name => 'Guadeloupe', :alpha3 => 'GLP', :numeric => '312' },
|
143
151
|
{ :alpha2 => 'GU', :name => 'Guam', :alpha3 => 'GUM', :numeric => '316' },
|
144
152
|
{ :alpha2 => 'GT', :name => 'Guatemala', :alpha3 => 'GTM', :numeric => '320' },
|
153
|
+
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
145
154
|
{ :alpha2 => 'GN', :name => 'Guinea', :alpha3 => 'GIN', :numeric => '324' },
|
146
155
|
{ :alpha2 => 'GW', :name => 'Guinea-Bissau', :alpha3 => 'GNB', :numeric => '624' },
|
147
156
|
{ :alpha2 => 'GY', :name => 'Guyana', :alpha3 => 'GUY', :numeric => '328' },
|
148
|
-
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
149
157
|
{ :alpha2 => 'HT', :name => 'Haiti', :alpha3 => 'HTI', :numeric => '332' },
|
158
|
+
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
150
159
|
{ :alpha2 => 'VA', :name => 'Holy See (Vatican City State)', :alpha3 => 'VAT', :numeric => '336' },
|
151
160
|
{ :alpha2 => 'HN', :name => 'Honduras', :alpha3 => 'HND', :numeric => '340' },
|
152
161
|
{ :alpha2 => 'HK', :name => 'Hong Kong', :alpha3 => 'HKG', :numeric => '344' },
|
153
|
-
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
154
162
|
{ :alpha2 => 'HU', :name => 'Hungary', :alpha3 => 'HUN', :numeric => '348' },
|
155
163
|
{ :alpha2 => 'IS', :name => 'Iceland', :alpha3 => 'ISL', :numeric => '352' },
|
156
164
|
{ :alpha2 => 'IN', :name => 'India', :alpha3 => 'IND', :numeric => '356' },
|
@@ -298,7 +306,8 @@ module ActiveMerchant #:nodoc:
|
|
298
306
|
{ :alpha2 => 'EH', :name => 'Western Sahara', :alpha3 => 'ESH', :numeric => '732' },
|
299
307
|
{ :alpha2 => 'YE', :name => 'Yemen', :alpha3 => 'YEM', :numeric => '887' },
|
300
308
|
{ :alpha2 => 'ZM', :name => 'Zambia', :alpha3 => 'ZMB', :numeric => '894' },
|
301
|
-
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' }
|
309
|
+
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' },
|
310
|
+
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' }
|
302
311
|
]
|
303
312
|
|
304
313
|
def self.find(name)
|
@@ -25,9 +25,12 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
def ssl_post(endpoint, data, headers = {})
|
26
26
|
ssl_request(:post, endpoint, data, headers)
|
27
27
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
|
29
|
+
def ssl_request(method, endpoint, data, headers)
|
30
|
+
handle_response(raw_ssl_request(method, endpoint, data, headers))
|
31
|
+
end
|
32
|
+
|
33
|
+
def raw_ssl_request(method, endpoint, data, headers = {})
|
31
34
|
connection = Connection.new(endpoint)
|
32
35
|
connection.open_timeout = open_timeout
|
33
36
|
connection.read_timeout = read_timeout
|
@@ -42,6 +45,17 @@ module ActiveMerchant #:nodoc:
|
|
42
45
|
|
43
46
|
connection.request(method, data, headers)
|
44
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def handle_response(response)
|
52
|
+
case response.code.to_i
|
53
|
+
when 200...300
|
54
|
+
response.body
|
55
|
+
else
|
56
|
+
raise ResponseError.new(response)
|
57
|
+
end
|
58
|
+
end
|
45
59
|
|
46
60
|
end
|
47
|
-
end
|
61
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soapenv:Body>
|
3
|
+
<ns1:GetFulfillmentOrderResponse
|
4
|
+
xmlns:ns1="http://fba-outbound.amazonaws.com/doc/2007-08-02/">
|
5
|
+
<ns1:GetFulfillmentOrderResult>
|
6
|
+
<ns1:FulfillmentOrder>
|
7
|
+
<ns1:MerchantFulfillmentOrderId>TEST-00000001</ns1:MerchantFulfillmentOrderId>
|
8
|
+
<ns1:ReceivedDateTime>2007-08-02T08:00:00Z</ns1:ReceivedDateTime>
|
9
|
+
<ns1:ShippingSpeedCategory>Standard</ns1:ShippingSpeedCategory>
|
10
|
+
<ns1:DisplayableOrderDateTime>2007-08-02T00:00:00Z</ns1:DisplayableOrderDateTime>
|
11
|
+
<ns1:DisplayableOrderComment>Thank you for your order!</ns1:DisplayableOrderComment>
|
12
|
+
<ns1:DisplayableOrderId>TEST-00000001</ns1:DisplayableOrderId>
|
13
|
+
<ns1:DestinationAddress>
|
14
|
+
<ns1:Name>John Smith</ns1:Name>
|
15
|
+
<ns1:Line1>2412 25th Ave NW.</ns1:Line1>
|
16
|
+
<ns1:City>Seattle</ns1:City>
|
17
|
+
<ns1:StateOrProvinceCode>WA</ns1:StateOrProvinceCode>
|
18
|
+
<ns1:CountryCode>US</ns1:CountryCode>
|
19
|
+
<ns1:PostalCode>98104</ns1:PostalCode>
|
20
|
+
<ns1:PhoneNumber>206-266-1000</ns1:PhoneNumber>
|
21
|
+
</ns1:DestinationAddress>
|
22
|
+
<ns1:FulfillmentOrderStatus>Complete</ns1:FulfillmentOrderStatus>
|
23
|
+
<ns1:StatusUpdatedDateTime>2007-08-03T16:00:00Z</ns1:StatusUpdatedDateTime>
|
24
|
+
</ns1:FulfillmentOrder>
|
25
|
+
<ns1:FulfillmentOrderItem>
|
26
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
27
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
28
|
+
<ns1:Quantity>2</ns1:Quantity>
|
29
|
+
<ns1:CancelledQuantity>0</ns1:CancelledQuantity>
|
30
|
+
<ns1:UnfulfillableQuantity>0</ns1:UnfulfillableQuantity>
|
31
|
+
</ns1:FulfillmentOrderItem>
|
32
|
+
<ns1:FulfillmentShipment>
|
33
|
+
<ns1:AmazonShipmentId>TEST00000001</ns1:AmazonShipmentId>
|
34
|
+
<ns1:FulfillmentCenterId>TST1</ns1:FulfillmentCenterId>
|
35
|
+
<ns1:FulfillmentShipmentStatus>Shipped</ns1:FulfillmentShipmentStatus>
|
36
|
+
<ns1:ShippingDateTime>2007-08-03T16:00:00Z</ns1:ShippingDateTime>
|
37
|
+
<ns1:EstimatedArrivalDateTime>2007-08-10T16:00:00Z</ns1:EstimatedArrivalDateTime>
|
38
|
+
<ns1:FulfillmentShipmentItem>
|
39
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
40
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
41
|
+
<ns1:Quantity>2</ns1:Quantity>
|
42
|
+
<ns1:PackageNumber>1</ns1:PackageNumber>
|
43
|
+
</ns1:FulfillmentShipmentItem>
|
44
|
+
<ns1:FulfillmentShipmentPackage>
|
45
|
+
<ns1:PackageNumber>1</ns1:PackageNumber>
|
46
|
+
<ns1:CarrierCode>UPS</ns1:CarrierCode>
|
47
|
+
<ns1:TrackingNumber>UPS00000001</ns1:TrackingNumber>
|
48
|
+
</ns1:FulfillmentShipmentPackage>
|
49
|
+
</ns1:FulfillmentShipment>
|
50
|
+
</ns1:GetFulfillmentOrderResult>
|
51
|
+
<ns1:ResponseMetadata>
|
52
|
+
<ns1:RequestId>963215ec-bec6-4ae0-84e0-19f5823ee33a</ns1:RequestId>
|
53
|
+
</ns1:ResponseMetadata>
|
54
|
+
</ns1:GetFulfillmentOrderResponse>
|
55
|
+
</soapenv:Body>
|
56
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soapenv:Body>
|
3
|
+
<ns1:GetFulfillmentOrderResponse
|
4
|
+
xmlns:ns1="http://fba-outbound.amazonaws.com/doc/2007-08-02/">
|
5
|
+
<ns1:GetFulfillmentOrderResult>
|
6
|
+
<ns1:FulfillmentOrder>
|
7
|
+
<ns1:MerchantFulfillmentOrderId>TEST-00000002</ns1:MerchantFulfillmentOrderId>
|
8
|
+
<ns1:ReceivedDateTime>2007-08-02T08:00:00Z</ns1:ReceivedDateTime>
|
9
|
+
<ns1:ShippingSpeedCategory>Standard</ns1:ShippingSpeedCategory>
|
10
|
+
<ns1:DisplayableOrderDateTime>2007-08-02T00:00:00Z</ns1:DisplayableOrderDateTime>
|
11
|
+
<ns1:DisplayableOrderComment>Thank you for your order!</ns1:DisplayableOrderComment>
|
12
|
+
<ns1:DisplayableOrderId>TEST-00000001</ns1:DisplayableOrderId>
|
13
|
+
<ns1:DestinationAddress>
|
14
|
+
<ns1:Name>John Smith</ns1:Name>
|
15
|
+
<ns1:Line1>2412 25th Ave NW.</ns1:Line1>
|
16
|
+
<ns1:City>Seattle</ns1:City>
|
17
|
+
<ns1:StateOrProvinceCode>WA</ns1:StateOrProvinceCode>
|
18
|
+
<ns1:CountryCode>US</ns1:CountryCode>
|
19
|
+
<ns1:PostalCode>98104</ns1:PostalCode>
|
20
|
+
<ns1:PhoneNumber>206-266-1000</ns1:PhoneNumber>
|
21
|
+
</ns1:DestinationAddress>
|
22
|
+
<ns1:FulfillmentOrderStatus>Complete</ns1:FulfillmentOrderStatus>
|
23
|
+
<ns1:StatusUpdatedDateTime>2007-08-03T16:00:00Z</ns1:StatusUpdatedDateTime>
|
24
|
+
</ns1:FulfillmentOrder>
|
25
|
+
<ns1:FulfillmentOrderItem>
|
26
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
27
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
28
|
+
<ns1:Quantity>2</ns1:Quantity>
|
29
|
+
<ns1:CancelledQuantity>0</ns1:CancelledQuantity>
|
30
|
+
<ns1:UnfulfillableQuantity>0</ns1:UnfulfillableQuantity>
|
31
|
+
</ns1:FulfillmentOrderItem>
|
32
|
+
</ns1:GetFulfillmentOrderResult>
|
33
|
+
<ns1:ResponseMetadata>
|
34
|
+
<ns1:RequestId>963215ec-bec6-4ae0-84e0-19f5823ee33a</ns1:RequestId>
|
35
|
+
</ns1:ResponseMetadata>
|
36
|
+
</ns1:GetFulfillmentOrderResponse>
|
37
|
+
</soapenv:Body>
|
38
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
+
xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">
|
4
|
+
<env:Body>
|
5
|
+
<env:Fault>
|
6
|
+
<faultcode>aws:Client.UnknownError</faultcode>
|
7
|
+
<faultstring>Something bad happened!</faultstring>
|
8
|
+
<detail>
|
9
|
+
<aws:RequestId xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">145b969c-23ec-41e4-a552-30e57fc2684f</aws:RequestId>
|
10
|
+
</detail>
|
11
|
+
</env:Fault>
|
12
|
+
</env:Body>
|
13
|
+
</env:Envelope>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
+
xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">
|
4
|
+
<env:Body>
|
5
|
+
<env:Fault>
|
6
|
+
<faultcode>aws:Client.InvalidParameterValue</faultcode>
|
7
|
+
<faultstring>Value #1337-1 for parameter MerchantFulfillmentOrderId is invalid. Reason: requested order not found.</faultstring>
|
8
|
+
<detail>
|
9
|
+
<aws:RequestId xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">145b969c-23ec-41e4-a552-30e57fc2684f</aws:RequestId>
|
10
|
+
</detail>
|
11
|
+
</env:Fault>
|
12
|
+
</env:Body>
|
13
|
+
</env:Envelope>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Orders>
|
3
|
+
<Shipment>
|
4
|
+
<InvoiceNumber>AB12345</InvoiceNumber>
|
5
|
+
<WebgistixOrderNumber>67891</WebgistixOrderNumber>
|
6
|
+
<Method>UPS Ground</Method>
|
7
|
+
<DateShipped>10/25/2009</DateShipped>
|
8
|
+
<ShipmentTrackingNumber>1Z8E5A380396682872</ShipmentTrackingNumber>
|
9
|
+
</Shipment>
|
10
|
+
<Shipment>
|
11
|
+
<InvoiceNumber>XY4567</InvoiceNumber>
|
12
|
+
<ShipmentTrackingNumber>Not Shipped</ShipmentTrackingNumber>
|
13
|
+
</Shipment>
|
14
|
+
</Orders>
|
data/test/remote/amazon_test.rb
CHANGED
@@ -76,6 +76,18 @@ class RemoteAmazonTest < Test::Unit::TestCase
|
|
76
76
|
assert_equal 0, response.stock_levels['SETTLERS']
|
77
77
|
end
|
78
78
|
|
79
|
+
def test_fetch_tracking_numbers
|
80
|
+
response = @service.fetch_tracking_numbers(['123456']) # an actual order
|
81
|
+
assert response.success?
|
82
|
+
assert_equal Hash.new, response.tracking_numbers # no tracking numbers in testing
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_fetch_tracking_numbers_ignores_not_found
|
86
|
+
response = @service.fetch_tracking_numbers(['#1337-1'])
|
87
|
+
assert response.success?
|
88
|
+
assert_equal Hash.new, response.tracking_numbers
|
89
|
+
end
|
90
|
+
|
79
91
|
def test_valid_credentials
|
80
92
|
assert @service.valid_credentials?
|
81
93
|
end
|
@@ -125,10 +125,10 @@ class RemoteShipwireTest < Test::Unit::TestCase
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def test_fetch_tracking_numbers
|
128
|
-
response = @shipwire.fetch_tracking_numbers
|
128
|
+
response = @shipwire.fetch_tracking_numbers(['123456'])
|
129
129
|
assert response.success?
|
130
130
|
assert response.test?
|
131
|
-
assert_equal Hash.new, response.tracking_numbers
|
131
|
+
assert_equal Hash.new, response.tracking_numbers # no tracking numbers in testing
|
132
132
|
end
|
133
133
|
|
134
134
|
def test_valid_credentials
|
@@ -63,15 +63,25 @@ class RemoteWebgistixTest < Test::Unit::TestCase
|
|
63
63
|
response = service.fulfill('123456', @address, @line_items, @options)
|
64
64
|
assert !response.success?
|
65
65
|
assert response.test?
|
66
|
-
assert_equal "
|
66
|
+
assert_equal "Invalid Credentials", response.message
|
67
67
|
end
|
68
68
|
|
69
69
|
def test_get_inventory
|
70
70
|
response = @service.fetch_stock_levels
|
71
71
|
assert response.success?
|
72
72
|
assert response.test?
|
73
|
-
assert_equal
|
74
|
-
assert_equal
|
73
|
+
assert_equal 90, response.stock_levels['WX-01-3022']
|
74
|
+
assert_equal 140, response.stock_levels['WX-04-1080']
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_fetch_tracking_numbers
|
78
|
+
response = @service.fetch_tracking_numbers([
|
79
|
+
'1254658', 'FAItest123', 'Flat Rate Test Order 4'
|
80
|
+
])
|
81
|
+
assert response.success?
|
82
|
+
assert_equal '4209073191018052136352154', response.tracking_numbers['1254658']
|
83
|
+
assert_equal '9101805213907472080032', response.tracking_numbers['Flat Rate Test Order 4']
|
84
|
+
assert_nil response.tracking_numbers['FAItest123'] # 'Not Shipped'
|
75
85
|
end
|
76
86
|
|
77
87
|
def test_valid_credentials
|
@@ -90,6 +90,49 @@ class AmazonTest < Test::Unit::TestCase
|
|
90
90
|
assert_equal 555, response.stock_levels['GN-02-02A']
|
91
91
|
end
|
92
92
|
|
93
|
+
def test_fetch_tracking_numbers
|
94
|
+
@service.expects(:ssl_post).twice.returns(
|
95
|
+
xml_fixture('amazon/tracking_response_1'),
|
96
|
+
xml_fixture('amazon/tracking_response_2')
|
97
|
+
)
|
98
|
+
|
99
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', 'TEST-00000002'])
|
100
|
+
assert response.success?
|
101
|
+
assert_equal 'UPS00000001', response.tracking_numbers['TEST-00000001']
|
102
|
+
assert_nil response.tracking_numbers['TEST-00000002']
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_fetch_tracking_numbers_ignores_not_found
|
106
|
+
response = mock('response')
|
107
|
+
response.stubs(:code).returns(500)
|
108
|
+
response.stubs(:message).returns('Internal Server Error')
|
109
|
+
response.stubs(:body).returns(xml_fixture('amazon/tracking_response_not_found'))
|
110
|
+
|
111
|
+
@service.expects(:ssl_post).times(3).
|
112
|
+
returns(xml_fixture('amazon/tracking_response_1')).
|
113
|
+
raises(ActiveMerchant::ResponseError.new(response)).
|
114
|
+
returns(xml_fixture('amazon/tracking_response_2'))
|
115
|
+
|
116
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', '#1337-1', 'TEST-00000002'])
|
117
|
+
assert response.success?
|
118
|
+
assert_equal 'UPS00000001', response.tracking_numbers['TEST-00000001']
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_fetch_tracking_numbers_aborts_on_error
|
122
|
+
response = mock('response')
|
123
|
+
response.stubs(:code).returns(500)
|
124
|
+
response.stubs(:message).returns('Internal Server Error')
|
125
|
+
response.stubs(:body).returns(xml_fixture('amazon/tracking_response_error'))
|
126
|
+
|
127
|
+
@service.expects(:ssl_post).twice.
|
128
|
+
returns(xml_fixture('amazon/tracking_response_1')).
|
129
|
+
raises(ActiveMerchant::ResponseError.new(response))
|
130
|
+
|
131
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', 'ERROR', 'TEST-00000002'])
|
132
|
+
assert !response.success?
|
133
|
+
assert_equal 'Something bad happened!', response.faultstring
|
134
|
+
end
|
135
|
+
|
93
136
|
def test_404_error
|
94
137
|
http_response = build_mock_response(response_from_404, "Not Found", "404")
|
95
138
|
@service.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(http_response))
|
@@ -62,10 +62,9 @@ class ShipwireTest < Test::Unit::TestCase
|
|
62
62
|
|
63
63
|
def test_no_tracking_numbers_available
|
64
64
|
@shipwire.expects(:ssl_post).returns(successful_empty_tracking_response)
|
65
|
-
response = @shipwire.fetch_tracking_numbers
|
65
|
+
response = @shipwire.fetch_tracking_numbers(['1234'])
|
66
66
|
assert response.success?
|
67
67
|
assert_equal Hash.new, response.tracking_numbers
|
68
|
-
|
69
68
|
end
|
70
69
|
|
71
70
|
def test_successful_tracking
|
@@ -73,7 +72,7 @@ class ShipwireTest < Test::Unit::TestCase
|
|
73
72
|
"2987" => "1ZW682E90326795080" }
|
74
73
|
|
75
74
|
@shipwire.expects(:ssl_post).returns(successful_tracking_response)
|
76
|
-
response = @shipwire.fetch_tracking_numbers
|
75
|
+
response = @shipwire.fetch_tracking_numbers(["2986", "2987"])
|
77
76
|
assert response.success?
|
78
77
|
assert_equal "3", response.params["total_orders"]
|
79
78
|
assert_equal "Test", response.params["status"]
|
@@ -84,7 +83,11 @@ class ShipwireTest < Test::Unit::TestCase
|
|
84
83
|
|
85
84
|
def test_successful_tracking_with_live_data
|
86
85
|
@shipwire.expects(:ssl_post).returns(successful_live_tracking_response)
|
87
|
-
response = @shipwire.fetch_tracking_numbers
|
86
|
+
response = @shipwire.fetch_tracking_numbers([
|
87
|
+
'21', '22', '23', '24', '25',
|
88
|
+
'26', '2581', '2576', '2593', '2598',
|
89
|
+
'2610', '2611', '2613', '2616', '2631'
|
90
|
+
])
|
88
91
|
assert response.success?
|
89
92
|
assert_equal "15", response.params["total_orders"]
|
90
93
|
assert_equal "0", response.params["status"]
|
@@ -99,6 +99,16 @@ class WebgistixTest < Test::Unit::TestCase
|
|
99
99
|
assert_equal 202, response.stock_levels['GN-00-01A']
|
100
100
|
assert_equal 199, response.stock_levels['GN-00-02A']
|
101
101
|
end
|
102
|
+
|
103
|
+
def test_tracking_numbers
|
104
|
+
@service.expects(:ssl_post).returns(xml_fixture('webgistix/tracking_response'))
|
105
|
+
|
106
|
+
response = @service.fetch_tracking_numbers(['AB12345', 'XY4567'])
|
107
|
+
assert response.success?
|
108
|
+
assert_equal WebgistixService::SUCCESS_MESSAGE, response.message
|
109
|
+
assert_equal '1Z8E5A380396682872', response.tracking_numbers['AB12345']
|
110
|
+
assert_nil response.tracking_numbers['XY4567']
|
111
|
+
end
|
102
112
|
|
103
113
|
def test_failed_login
|
104
114
|
@service.expects(:ssl_post).returns(invalid_login_response)
|
@@ -106,10 +116,10 @@ class WebgistixTest < Test::Unit::TestCase
|
|
106
116
|
response = @service.fulfill('123456', @address, @line_items, @options)
|
107
117
|
assert !response.success?
|
108
118
|
assert response.test?
|
109
|
-
assert_equal '
|
119
|
+
assert_equal 'Invalid Credentials', response.message
|
110
120
|
assert_nil response.params['order_id']
|
111
121
|
|
112
|
-
assert_equal '
|
122
|
+
assert_equal 'Invalid Credentials', response.params['error_0']
|
113
123
|
end
|
114
124
|
|
115
125
|
def test_garbage_response
|
@@ -132,6 +142,22 @@ class WebgistixTest < Test::Unit::TestCase
|
|
132
142
|
assert !@service.valid_credentials?
|
133
143
|
end
|
134
144
|
|
145
|
+
def test_duplicate_response_is_treated_as_success
|
146
|
+
response = stub(:code => 200, :body => duplicate_response, :message => '')
|
147
|
+
Net::HTTP.any_instance.stubs(:post).raises(ActiveMerchant::ConnectionError).returns(response)
|
148
|
+
|
149
|
+
response = @service.fulfill('123456', @address, @line_items, @options)
|
150
|
+
assert response.success?
|
151
|
+
assert response.test?
|
152
|
+
assert_equal WebgistixService::DUPLICATE_MESSAGE, response.message
|
153
|
+
assert response.params['duplicate']
|
154
|
+
assert_nil response.params['order_id']
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_ensure_gateway_uses_safe_retry
|
158
|
+
assert @service.retry_safe
|
159
|
+
end
|
160
|
+
|
135
161
|
private
|
136
162
|
def minimal_successful_response
|
137
163
|
'<Completed><Success>True</Success></Completed>'
|
@@ -142,11 +168,11 @@ class WebgistixTest < Test::Unit::TestCase
|
|
142
168
|
end
|
143
169
|
|
144
170
|
def invalid_login_response
|
145
|
-
'<Error>
|
171
|
+
'<Errors><Error>Invalid Credentials</Error></Errors>'
|
146
172
|
end
|
147
173
|
|
148
174
|
def failure_response
|
149
|
-
'<Error>No Address Line 1</Error><Error>Unknown ItemID: testitem</Error><Error>Unknown ItemID: WX-01-1000</Error>'
|
175
|
+
'<Errors><Error>No Address Line 1</Error><Error>Unknown ItemID: testitem</Error><Error>Unknown ItemID: WX-01-1000</Error></Errors>'
|
150
176
|
end
|
151
177
|
|
152
178
|
def garbage_response
|
@@ -159,4 +185,8 @@ class WebgistixTest < Test::Unit::TestCase
|
|
159
185
|
'<Item><ItemID>GN-00-02A</ItemID><ItemQty>199</ItemQty></Item>' +
|
160
186
|
'</InventoryXML>'
|
161
187
|
end
|
188
|
+
|
189
|
+
def duplicate_response
|
190
|
+
'<Completed><Success>Duplicate</Success></Completed>'
|
191
|
+
end
|
162
192
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_fulfillment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Cody Fauser
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-12-13 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
hash: 7
|
31
31
|
segments:
|
@@ -88,6 +88,11 @@ files:
|
|
88
88
|
- test/fixtures/xml/amazon/inventory_list_response.xml
|
89
89
|
- test/fixtures/xml/amazon/inventory_list_response_with_next_1.xml
|
90
90
|
- test/fixtures/xml/amazon/inventory_list_response_with_next_2.xml
|
91
|
+
- test/fixtures/xml/amazon/tracking_response_1.xml
|
92
|
+
- test/fixtures/xml/amazon/tracking_response_2.xml
|
93
|
+
- test/fixtures/xml/amazon/tracking_response_error.xml
|
94
|
+
- test/fixtures/xml/amazon/tracking_response_not_found.xml
|
95
|
+
- test/fixtures/xml/webgistix/tracking_response.xml
|
91
96
|
- test/remote/amazon_test.rb
|
92
97
|
- test/remote/shipwire_test.rb
|
93
98
|
- test/remote/webgistix_test.rb
|
@@ -101,8 +106,8 @@ homepage: http://github.com/shopify/active_fulfillment
|
|
101
106
|
licenses: []
|
102
107
|
|
103
108
|
post_install_message:
|
104
|
-
rdoc_options:
|
105
|
-
|
109
|
+
rdoc_options: []
|
110
|
+
|
106
111
|
require_paths:
|
107
112
|
- lib
|
108
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|