active_fulfillment 2.1.9 → 3.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/lib/active_fulfillment.rb +5 -5
  4. data/lib/active_fulfillment/base.rb +10 -0
  5. data/lib/active_fulfillment/response.rb +26 -0
  6. data/lib/active_fulfillment/service.rb +56 -0
  7. data/lib/active_fulfillment/services.rb +5 -0
  8. data/lib/active_fulfillment/services/amazon_mws.rb +473 -0
  9. data/lib/active_fulfillment/services/james_and_james.rb +122 -0
  10. data/lib/active_fulfillment/services/shipwire.rb +266 -0
  11. data/lib/active_fulfillment/services/shopify_api.rb +125 -0
  12. data/lib/active_fulfillment/services/webgistix.rb +334 -0
  13. data/lib/active_fulfillment/version.rb +4 -0
  14. data/test/remote/amazon_mws_test.rb +20 -17
  15. data/test/remote/james_and_james_test.rb +77 -0
  16. data/test/remote/shipwire_test.rb +25 -25
  17. data/test/remote/webgistix_test.rb +21 -21
  18. data/test/test_helper.rb +27 -52
  19. data/test/unit/base_test.rb +4 -4
  20. data/test/unit/services/amazon_mws_test.rb +56 -26
  21. data/test/unit/services/james_and_james_test.rb +90 -0
  22. data/test/unit/services/shipwire_test.rb +18 -18
  23. data/test/unit/services/shopify_api_test.rb +7 -20
  24. data/test/unit/services/webgistix_test.rb +35 -35
  25. metadata +32 -114
  26. data/CHANGELOG +0 -62
  27. data/lib/active_fulfillment/fulfillment/base.rb +0 -12
  28. data/lib/active_fulfillment/fulfillment/response.rb +0 -28
  29. data/lib/active_fulfillment/fulfillment/service.rb +0 -58
  30. data/lib/active_fulfillment/fulfillment/services.rb +0 -5
  31. data/lib/active_fulfillment/fulfillment/services/amazon.rb +0 -389
  32. data/lib/active_fulfillment/fulfillment/services/amazon_mws.rb +0 -454
  33. data/lib/active_fulfillment/fulfillment/services/shipwire.rb +0 -268
  34. data/lib/active_fulfillment/fulfillment/services/shopify_api.rb +0 -125
  35. data/lib/active_fulfillment/fulfillment/services/webgistix.rb +0 -338
  36. data/lib/active_fulfillment/fulfillment/version.rb +0 -6
  37. data/test/fixtures.yml +0 -16
  38. data/test/fixtures/xml/amazon/inventory_get_response.xml +0 -17
  39. data/test/fixtures/xml/amazon/inventory_list_response.xml +0 -29
  40. data/test/fixtures/xml/amazon/inventory_list_response_with_next_1.xml +0 -30
  41. data/test/fixtures/xml/amazon/inventory_list_response_with_next_2.xml +0 -29
  42. data/test/fixtures/xml/amazon/tracking_response_1.xml +0 -56
  43. data/test/fixtures/xml/amazon/tracking_response_2.xml +0 -38
  44. data/test/fixtures/xml/amazon/tracking_response_error.xml +0 -13
  45. data/test/fixtures/xml/amazon/tracking_response_not_found.xml +0 -13
  46. data/test/fixtures/xml/amazon_mws/fulfillment_get_fulfillment_order.xml +0 -114
  47. data/test/fixtures/xml/amazon_mws/fulfillment_get_fulfillment_order_2.xml +0 -90
  48. data/test/fixtures/xml/amazon_mws/fulfillment_get_fullfillment_order_with_multiple_tracking_numbers.xml +0 -121
  49. data/test/fixtures/xml/amazon_mws/fulfillment_list_all_fulfillment_orders.xml +0 -70
  50. data/test/fixtures/xml/amazon_mws/inventory_list_inventory_item_supply.xml +0 -32
  51. data/test/fixtures/xml/amazon_mws/inventory_list_inventory_supply.xml +0 -75
  52. data/test/fixtures/xml/amazon_mws/inventory_list_inventory_supply_by_next_token.xml +0 -38
  53. data/test/fixtures/xml/amazon_mws/tracking_response_error.xml +0 -9
  54. data/test/fixtures/xml/amazon_mws/tracking_response_not_found.xml +0 -9
  55. data/test/fixtures/xml/shipwire/fulfillment_failure_response.xml +0 -7
  56. data/test/fixtures/xml/shipwire/invalid_login_response.xml +0 -7
  57. data/test/fixtures/xml/shipwire/inventory_get_response.xml +0 -44
  58. data/test/fixtures/xml/shipwire/successful_empty_tracking_response.xml +0 -8
  59. data/test/fixtures/xml/shipwire/successful_live_tracking_response.xml +0 -53
  60. data/test/fixtures/xml/shipwire/successful_tracking_response.xml +0 -16
  61. data/test/fixtures/xml/shipwire/successful_tracking_response_with_tracking_urls.xml +0 -31
  62. data/test/fixtures/xml/webgistix/multiple_tracking_response.xml +0 -21
  63. data/test/fixtures/xml/webgistix/tracking_response.xml +0 -14
  64. data/test/remote/amazon_test.rb +0 -124
  65. data/test/unit/services/amazon_test.rb +0 -271
@@ -0,0 +1,334 @@
1
+ module ActiveFulfillment
2
+ class WebgistixService < Service
3
+ SERVICE_URLS = {
4
+ :fulfillment => 'https://www.webgistix.com/XML/CreateOrder.asp',
5
+ :inventory => 'https://www.webgistix.com/XML/GetInventory.asp',
6
+ :tracking => 'https://www.webgistix.com/XML/GetTracking.asp'
7
+ }
8
+ TEST_URLS = SERVICE_URLS.merge({
9
+ :fulfillment => 'https://www.webgistix.com/XML/CreateOrderTest.asp'
10
+ })
11
+
12
+ SUCCESS, DUPLICATE, FAILURE = 'True', 'Duplicate', 'False'
13
+
14
+ SUCCESS_MESSAGE = 'Successfully submitted the order'
15
+ FAILURE_MESSAGE = 'Failed to submit the order'
16
+ DUPLICATE_MESSAGE = 'This order has already been successfully submitted'
17
+
18
+ INVALID_LOGIN = 'Invalid Credentials'
19
+ NOT_SHIPPED = 'Not Shipped'
20
+
21
+ TRACKING_COMPANIES = %w(UPS FedEx USPS)
22
+
23
+ # If a request is detected as a duplicate only the original data will be
24
+ # used by Webgistix, and the subsequent responses will have a
25
+ # :duplicate parameter set in the params hash.
26
+ self.retry_safe = true
27
+
28
+ # The first is the label, and the last is the code
29
+ def self.shipping_methods
30
+ [
31
+ ["UPS Ground Shipping", "Ground"],
32
+ ["UPS Ground", "Ground"],
33
+ ["UPS Standard Shipping (Canada Only)", "Standard"],
34
+ ["UPS Standard Shipping (CA & MX Only)", "Standard"],
35
+ ["UPS 3-Business Day", "3-Day Select"],
36
+ ["UPS 2-Business Day", "2nd Day Air"],
37
+ ["UPS 2-Business Day AM", "2nd Day Air AM"],
38
+ ["UPS Next Day", "Next Day Air"],
39
+ ["UPS Next Day Saver", "Next Day Air Saver"],
40
+ ["UPS Next Day Early AM", "Next Day Air Early AM"],
41
+ ["UPS Worldwide Express (Next Day)", "Worldwide Express"],
42
+ ["UPS Worldwide Expedited (2nd Day)", "Worldwide Expedited"],
43
+ ["UPS Worldwide Express Saver", "Worldwide Express Saver"],
44
+ ["FedEx Priority Overnight", "FedEx Priority Overnight"],
45
+ ["FedEx Standard Overnight", "FedEx Standard Overnight"],
46
+ ["FedEx First Overnight", "FedEx First Overnight"],
47
+ ["FedEx 2nd Day", "FedEx 2nd Day"],
48
+ ["FedEx Express Saver", "FedEx Express Saver"],
49
+ ["FedEx International Priority", "FedEx International Priority"],
50
+ ["FedEx International Economy", "FedEx International Economy"],
51
+ ["FedEx International First", "FedEx International First"],
52
+ ["FedEx Ground", "FedEx Ground"],
53
+ ["USPS Priority Mail", "Priority Mail"],
54
+ ["USPS Priority Mail International", "Priority Mail International"],
55
+ ["USPS Priority Mail Small Flat Rate Box", "Priority Mail Small Flat Rate Box"],
56
+ ["USPS Priority Mail Medium Flat Rate Box", "Priority Mail Medium Flat Rate Box"],
57
+ ["USPS Priority Mail Large Flat Rate Box", "Priority Mail Large Flat Rate Box"],
58
+ ["USPS Priority Mail Flat Rate Envelope", "Priority Mail Flat Rate Envelope"],
59
+ ["USPS First Class Mail", "First Class"],
60
+ ["USPS First Class International", "First Class International"],
61
+ ["USPS Express Mail", "Express"],
62
+ ["USPS Express Mail International", "Express Mail International"],
63
+ ["USPS Parcel Post", "Parcel"],
64
+ ["USPS Media Mail", "Media Mail"]
65
+ ].inject({}){|h, (k,v)| h[k] = v; h}
66
+ end
67
+
68
+ # Pass in the login and password for the shipwire account.
69
+ # Optionally pass in the :test => true to force test mode
70
+ def initialize(options = {})
71
+ requires!(options, :login, :password)
72
+ super
73
+ end
74
+
75
+ def fulfill(order_id, shipping_address, line_items, options = {})
76
+ requires!(options, :shipping_method)
77
+ commit :fulfillment, build_fulfillment_request(order_id, shipping_address, line_items, options)
78
+ end
79
+
80
+ def fetch_stock_levels(options = {})
81
+ commit :inventory, build_inventory_request(options)
82
+ end
83
+
84
+ def fetch_tracking_data(order_ids, options = {})
85
+ commit :tracking, build_tracking_request(order_ids, options)
86
+ end
87
+
88
+ def valid_credentials?
89
+ response = fulfill('', {}, [], :shipping_method => '')
90
+ response.message != INVALID_LOGIN
91
+ end
92
+
93
+ def test_mode?
94
+ true
95
+ end
96
+
97
+ private
98
+ #<?xml version="1.0"?>
99
+ # <OrderXML>
100
+ # <Password>Webgistix</Password>
101
+ # <CustomerID>3</CustomerID>
102
+ # <Order>
103
+ # <ReferenceNumber></ReferenceNumber>
104
+ # <Company>Test Company</Company>
105
+ # <Name>Joe Smith</Name>
106
+ # <Address1>123 Main St.</Address1>
107
+ # <Address2></Address2>
108
+ # <Address3></Address3>
109
+ # <City>Olean</City>
110
+ # <State>NY</State>
111
+ # <ZipCode>14760</ZipCode>
112
+ # <Country>United States</Country>
113
+ # <Email>info@webgistix.com</Email>
114
+ # <Phone>1-123-456-7890</Phone>
115
+ # <ShippingInstructions>Ground</ShippingInstructions>
116
+ # <OrderComments>Test Order</OrderComments>
117
+ # <Approve>0</Approve>
118
+ # <Item>
119
+ # <ItemID>testitem</ItemID>
120
+ # <ItemQty>2</ItemQty>
121
+ # </Item>
122
+ # </Order>
123
+ # </OrderXML>
124
+ def build_fulfillment_request(order_id, shipping_address, line_items, options)
125
+ xml = Builder::XmlMarkup.new :indent => 2
126
+ xml.instruct!
127
+ xml.tag! 'OrderXML' do
128
+ add_credentials(xml)
129
+ add_order(xml, order_id, shipping_address, line_items, options)
130
+ end
131
+ xml.target!
132
+ end
133
+
134
+ #<?xml version="1.0"?>
135
+ # <InventoryXML>
136
+ # <Password>Webgistix</Password>
137
+ # <CustomerID>3</CustomerID>
138
+ # </InventoryXML>
139
+ def build_inventory_request(options)
140
+ xml = Builder::XmlMarkup.new :indent => 2
141
+ xml.instruct!
142
+ xml.tag! 'InventoryXML' do
143
+ add_credentials(xml)
144
+ end
145
+ end
146
+
147
+ #<?xml version="1.0"?>
148
+ # <TrackingXML>
149
+ # <Password>Webgistix</Password>
150
+ # <CustomerID>3</CustomerID>
151
+ # <Tracking>
152
+ # <Order>AB12345</Order>
153
+ # </Tracking>
154
+ # <Tracking>
155
+ # <Order>XY4567</Order>
156
+ # </Tracking>
157
+ # </TrackingXML>
158
+ def build_tracking_request(order_ids, options)
159
+ xml = Builder::XmlMarkup.new :indent => 2
160
+ xml.instruct!
161
+ xml.tag! 'TrackingXML' do
162
+ add_credentials(xml)
163
+
164
+ order_ids.each do |o_id|
165
+ xml.tag! 'Tracking' do
166
+ xml.tag! 'Order', o_id
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ def add_credentials(xml)
173
+ xml.tag! 'CustomerID', @options[:login]
174
+ xml.tag! 'Password', @options[:password]
175
+ end
176
+
177
+ def add_order(xml, order_id, shipping_address, line_items, options)
178
+ xml.tag! 'Order' do
179
+ xml.tag! 'ReferenceNumber', order_id
180
+ xml.tag! 'ShippingInstructions', options[:shipping_method]
181
+ xml.tag! 'Approve', 1
182
+ xml.tag! 'OrderComments', options[:comment] unless options[:comment].blank?
183
+
184
+ add_address(xml, shipping_address, options)
185
+
186
+ Array(line_items).each_with_index do |line_item, index|
187
+ add_item(xml, line_item, index)
188
+ end
189
+ end
190
+ end
191
+
192
+ def add_address(xml, address, options)
193
+ xml.tag! 'Name', address[:name]
194
+ xml.tag! 'Address1', address[:address1]
195
+ xml.tag! 'Address2', address[:address2] unless address[:address2].blank?
196
+ xml.tag! 'Address3', address[:address3] unless address[:address3].blank?
197
+ xml.tag! 'City', address[:city]
198
+ xml.tag! 'State', address[:state]
199
+ xml.tag! 'ZipCode', address[:zip]
200
+ xml.tag! 'Company', address[:company]
201
+
202
+ unless address[:country].blank?
203
+ country = ActiveUtils::Country.find(address[:country])
204
+ xml.tag! 'Country', country.name
205
+ end
206
+
207
+ xml.tag! 'Phone', address[:phone]
208
+ xml.tag! 'Email', options[:email] unless options[:email].blank?
209
+ end
210
+
211
+ def add_item(xml, item, index)
212
+ xml.tag! 'Item' do
213
+ xml.tag! 'ItemID', item[:sku] unless item[:sku].blank?
214
+ xml.tag! 'ItemQty', item[:quantity] unless item[:quantity].blank?
215
+ end
216
+ end
217
+
218
+ def commit(action, request)
219
+ url = test? ? TEST_URLS[action] : SERVICE_URLS[action]
220
+
221
+ data = ssl_post(url, request,
222
+ 'EndPointURL' => url,
223
+ 'Content-Type' => 'text/xml; charset="utf-8"'
224
+ )
225
+
226
+ response = parse_response(action, data)
227
+ Response.new(success?(response), message_from(response), response, :test => test?)
228
+ end
229
+
230
+ def success?(response)
231
+ response[:success] == SUCCESS || response[:success] == DUPLICATE
232
+ end
233
+
234
+ def message_from(response)
235
+ if response[:duplicate]
236
+ DUPLICATE_MESSAGE
237
+ elsif success?(response)
238
+ SUCCESS_MESSAGE
239
+ elsif response[:error_0] == INVALID_LOGIN
240
+ INVALID_LOGIN
241
+ else
242
+ FAILURE_MESSAGE
243
+ end
244
+ end
245
+
246
+ def parse_response(action, xml)
247
+ begin
248
+ document = REXML::Document.new("<response>#{xml}</response>")
249
+ rescue REXML::ParseException
250
+ return {:success => FAILURE}
251
+ end
252
+
253
+ case action
254
+ when :fulfillment
255
+ parse_fulfillment_response(document)
256
+ when :inventory
257
+ parse_inventory_response(document)
258
+ when :tracking
259
+ parse_tracking_response(document)
260
+ else
261
+ raise ArgumentError, "Unknown action #{action}"
262
+ end
263
+ end
264
+
265
+ def parse_fulfillment_response(document)
266
+ response = parse_errors(document)
267
+
268
+ # Check if completed
269
+ if completed = REXML::XPath.first(document, '//Completed')
270
+ completed.elements.each do |e|
271
+ response[e.name.underscore.to_sym] = e.text
272
+ end
273
+ else
274
+ response[:success] = FAILURE
275
+ end
276
+
277
+ response[:duplicate] = response[:success] == DUPLICATE
278
+
279
+ response
280
+ end
281
+
282
+ def parse_inventory_response(document)
283
+ response = parse_errors(document)
284
+ response[:stock_levels] = {}
285
+
286
+ document.root.each_element('//Item') do |node|
287
+ # {ItemID => 'SOME-ID', ItemQty => '101'}
288
+ params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
289
+
290
+ response[:stock_levels][params['ItemID']] = params['ItemQty'].to_i
291
+ end
292
+
293
+ response
294
+ end
295
+
296
+ def parse_tracking_response(document)
297
+ response = parse_errors(document)
298
+ response[:tracking_numbers] = {}
299
+ response[:tracking_companies] = {}
300
+ response[:tracking_urls] = {}
301
+
302
+ document.root.each_element('//Shipment') do |node|
303
+ # {InvoiceNumber => 'SOME-ID', ShipmentTrackingNumber => 'SOME-TRACKING-NUMBER'}
304
+ params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
305
+
306
+ tracking = params['ShipmentTrackingNumber']
307
+
308
+ unless tracking == NOT_SHIPPED
309
+ response[:tracking_numbers][params['InvoiceNumber']] ||= []
310
+ response[:tracking_numbers][params['InvoiceNumber']] << tracking
311
+ end
312
+
313
+ company = params['Method'].split[0] if params['Method']
314
+ if TRACKING_COMPANIES.include? company
315
+ response[:tracking_companies][params['InvoiceNumber']] ||= []
316
+ response[:tracking_companies][params['InvoiceNumber']] << company
317
+ end
318
+ end
319
+
320
+ response
321
+ end
322
+
323
+ def parse_errors(document)
324
+ response = {}
325
+
326
+ REXML::XPath.match(document, "//Errors/Error").to_a.each_with_index do |e, i|
327
+ response["error_#{i}".to_sym] = e.text
328
+ end
329
+
330
+ response[:success] = response.empty? ? SUCCESS : FAILURE
331
+ response
332
+ end
333
+ end
334
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module ActiveFulfillment
3
+ VERSION = "3.0.0.pre2"
4
+ end
@@ -1,9 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
- class RemoteAmazonMarketplaceWebservicesTest < Test::Unit::TestCase
3
+ class RemoteAmazonMarketplaceWebservicesTest < Minitest::Test
4
+ include ActiveFulfillment::Test::Fixtures
4
5
 
5
6
  def setup
6
- @service = AmazonMarketplaceWebService.new( fixtures(:amazon_mws) )
7
+ @service = ActiveFulfillment::AmazonMarketplaceWebService.new(fixtures(:amazon_mws))
7
8
 
8
9
  @options = {
9
10
  :shipping_method => 'Standard',
@@ -30,9 +31,9 @@ class RemoteAmazonMarketplaceWebservicesTest < Test::Unit::TestCase
30
31
  end
31
32
 
32
33
  def test_successful_order_submission
33
- response = @service.fulfill(ActiveMerchant::Utils.generate_unique_id, @address, @line_items, @options)
34
+ response = @service.fulfill(SecureRandom.uuid, @address, @line_items, @options)
34
35
  assert response.success?
35
- assert !response.test?
36
+ refute response.test?
36
37
  end
37
38
 
38
39
  def test_order_multiple_line_items
@@ -41,17 +42,17 @@ class RemoteAmazonMarketplaceWebservicesTest < Test::Unit::TestCase
41
42
  :quantity => 2
42
43
  })
43
44
 
44
- response = @service.fulfill(ActiveMerchant::Utils.generate_unique_id, @address, @line_items, @options)
45
+ response = @service.fulfill(SecureRandom.uuid, @address, @line_items, @options)
45
46
  assert response.success?
46
47
  end
47
48
 
48
49
  def test_invalid_credentials_during_fulfillment
49
- service = AmazonMarketplaceWebService.new(
50
+ service = ActiveFulfillment::AmazonMarketplaceWebService.new(
50
51
  :login => 'y',
51
52
  :password => 'p',
52
53
  :seller_id => 'o')
53
54
 
54
- response = service.fulfill(ActiveMerchant::Utils.generate_unique_id, @address, @line_items, @options)
55
+ response = service.fulfill(SecureRandom.uuid, @address, @line_items, @options)
55
56
  assert !response.success?
56
57
 
57
58
  assert_equal "InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.", response.response_comment
@@ -98,23 +99,25 @@ class RemoteAmazonMarketplaceWebservicesTest < Test::Unit::TestCase
98
99
  end
99
100
 
100
101
  def test_invalid_credentials
101
- service = AmazonMarketplaceWebService.new(
102
+ service = ActiveFulfillment::AmazonMarketplaceWebService.new(
102
103
  :login => 'your@email.com',
103
- :password => 'password',
104
+ :password => 'wrong',
104
105
  :seller_id => 'SellerNumber1')
105
- assert !service.valid_credentials?
106
+ refute service.valid_credentials?
106
107
  end
107
108
 
108
- def test_get_status_does_not_require_valid_credentials
109
- service = AmazonMarketplaceWebService.new(
110
- :login => 'your@email.com',
111
- :password => 'password')
112
- response = service.status
109
+ def test_get_status
110
+ response = @service.status
113
111
  assert response.success?
114
112
  end
115
113
 
116
- def test_get_status
117
- service = AmazonMarketplaceWebService.new(fixtures(:amazon))
114
+ def test_get_status_does_not_require_valid_credentials
115
+ service = ActiveFulfillment::AmazonMarketplaceWebService.new(
116
+ :login => 'your@email.com',
117
+ :password => 'wrong',
118
+ :seller_id => 'SellerNumber1'
119
+ )
120
+
118
121
  response = service.status
119
122
  assert response.success?
120
123
  end
@@ -0,0 +1,77 @@
1
+ require 'test_helper'
2
+
3
+ class RemoteJamesAndJamesTest < Minitest::Test
4
+ include ActiveFulfillment::Test::Fixtures
5
+
6
+ def setup
7
+ ActiveFulfillment::Base.mode = :test
8
+
9
+ @service = ActiveFulfillment::JamesAndJamesService.new(fixtures(:james_and_james))
10
+
11
+ @options = {
12
+ shipping_method: 'Ground',
13
+ email: 'buyer@jadedpallet.com'
14
+ }
15
+
16
+ @address = {
17
+ name: 'Fred Brooks',
18
+ address1: '1234 Penny Lane',
19
+ city: 'Jonsetown',
20
+ state: 'NC',
21
+ country: 'US',
22
+ zip: '23456'
23
+ }
24
+
25
+ @line_items = [
26
+ {
27
+ sku: 'SBLK8',
28
+ quantity: 2,
29
+ price: 10
30
+ }
31
+ ]
32
+
33
+ end
34
+
35
+ def test_successful_order_submission
36
+ @options[:billing_address] = @address
37
+ response = @service.fulfill('123456', @address, @line_items, @options)
38
+ assert response.success?
39
+ assert response.test?
40
+ end
41
+
42
+ def test_order_multiple_line_items
43
+ @line_items.push({
44
+ sku: 'SWHT8',
45
+ quantity: 3,
46
+ price: 10
47
+ })
48
+ @options[:billing_address] = @address
49
+ response = @service.fulfill('123456', @address, @line_items, @options)
50
+ assert response.success?
51
+ assert response.test?
52
+ end
53
+
54
+ def test_invalid_sku_during_fulfillment
55
+ line_items = [{sku: 'invalid', quantity: 1}]
56
+ @options[:billing_address] = @address
57
+ response = @service.fulfill('123456', @address, line_items, @options)
58
+ assert !response.success?
59
+ assert response.test?
60
+ end
61
+
62
+ def test_invalid_credentials_during_fulfillment
63
+ service = ActiveFulfillment::JamesAndJamesService.new(subdomain: 'test', key: 'test')
64
+ @options[:billing_address] = @address
65
+ response = service.fulfill('123456', @address, @line_items, @options)
66
+ refute response.success?
67
+ assert_equal "Not Found", response.message
68
+ end
69
+
70
+ def test_get_inventory
71
+ response = @service.fetch_stock_levels
72
+ assert response.success?
73
+ assert response.test?
74
+ assert_equal 99, response.stock['SBLK8']
75
+ end
76
+
77
+ end