active_shipping 1.8.5 → 1.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c7ade2aff35261434a4a9fcc35ad03cf7b9d077
4
- data.tar.gz: 321fa9f5911fa55e862413fc07280b7624563708
3
+ metadata.gz: a5f2cfecba695cbe25301c9243cef963e973709a
4
+ data.tar.gz: 918729e4323f336d6a8200756ddc139e1cd4e3e7
5
5
  SHA512:
6
- metadata.gz: 186c310a5a6bb1ddddd3394361f44049c8b6969d1043371ce0955f2c1e75e214f2b9a70b64bf114756679dc1e169d13dc4f8f8afbec1b2cb6741f7ed9fa55953
7
- data.tar.gz: bfb64ef1fd04b168e6a34cebfd448468dcb895fe9eb025c2203317a96166e5afe44c3fc81d5d47041eae54991ac9e00888b58de7ba3dd4cce4951125c8c640d4
6
+ metadata.gz: aaf1f5071b74e714997db24d095b38cd04dd92e06fe75ce6dbda35ec36b0c854a82c261fdd8a14b5578d64b562bf93a25cdf5ddce02654fdb947dab1ae10cf1c
7
+ data.tar.gz: eff96dd47c928524bd3f6d7e15617a04a6e30d10f79c684913d5a25d1e858f53cd3be81a61af8bc5a17bd53c2b8588851d3022d5317cffd8ca9c28e832369dc8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # ActiveShipping CHANGELOG
2
2
 
3
+ ### v1.8.6
4
+ - Fix UPS TrackResponse with no status code
5
+ - Stop FedEx from raising for successful responses with no statuses
6
+ - Raise appropriate exception response for FedEx errors
7
+
3
8
  ### v1.8.5
4
9
  - Fix UPS TrackResponse parsing for missing elements
5
10
 
@@ -137,7 +137,11 @@ module ActiveShipping
137
137
  DEFAULT_LABEL_STOCK_TYPE = 'PAPER_7X4.75'
138
138
 
139
139
  # Available return formats for image data when creating labels
140
- LABEL_FORMATS = ['DPL', 'EPL2', 'PDF', 'ZPLII', 'PNG']
140
+ LABEL_FORMATS = %w(DPL EPL2 PDF ZPLII PNG).freeze
141
+
142
+ TRANSIENT_TRACK_RESPONSE_CODES = %w(9035 9040 9041 9045 9050 9055 9060 9065 9070 9075 9085 9086 9090).freeze
143
+
144
+ UNRECOVERABLE_TRACK_RESPONSE_CODES = %w(9080 9081 9082 9095 9100).freeze
141
145
 
142
146
  def self.service_name_for_code(service_code)
143
147
  SERVICE_TYPES[service_code] || "FedEx #{service_code.titleize.sub(/Fedex /, '')}"
@@ -603,36 +607,31 @@ module ActiveShipping
603
607
 
604
608
 
605
609
  first_notification = tracking_details.at('Notification')
606
- if first_notification.at('Severity').text == 'ERROR'
607
- case first_notification.at('Code').text
608
- when '9040'
610
+ severity = first_notification.at('Severity').text
611
+ if severity == 'ERROR' || severity == 'FAILURE'
612
+ message = first_notification.try(:text)
613
+ code = first_notification.at('Code').try(:text)
614
+ case code
615
+ when *TRANSIENT_TRACK_RESPONSE_CODES
609
616
  raise ActiveShipping::ShipmentNotFound, first_notification.at('Message').text
610
617
  else
611
618
  raise ActiveShipping::ResponseContentError, StandardError.new(first_notification.at('Message').text)
612
619
  end
613
- elsif first_notification.at('Severity').text == 'FAILURE'
614
- case first_notification.at('Code').text
615
- when '9045'
616
- raise ActiveShipping::ResponseContentError, StandardError.new(first_notification.at('Message').text)
617
- end
618
620
  end
619
621
 
620
622
  tracking_number = tracking_details.at('TrackingNumber').text
621
623
  status_detail = tracking_details.at('StatusDetail')
622
- if status_detail.nil?
623
- raise ActiveShipping::Error, "Tracking response does not contain status information"
624
- end
625
-
626
- status_code = status_detail.at('Code').try(:text)
627
- if status_code.nil?
628
- raise ActiveShipping::Error, "Tracking response does not contain status code"
629
- end
624
+ if status_detail.blank?
625
+ status_code, status, status_description, delivery_signature = nil
626
+ else
627
+ status_code = status_detail.at('Code').try(:text)
628
+ status_description = status_detail.at('AncillaryDetails/ReasonDescription').try(:text) || status_detail.at('Description').try(:text)
630
629
 
631
- status_description = (status_detail.at('AncillaryDetails/ReasonDescription') || status_detail.at('Description')).text
632
- status = TRACKING_STATUS_CODES[status_code]
630
+ status = TRACKING_STATUS_CODES[status_code]
633
631
 
634
- if status_code == 'DL' && tracking_details.at('AvailableImages').try(:text) == 'SIGNATURE_PROOF_OF_DELIVERY'
635
- delivery_signature = tracking_details.at('DeliverySignatureName').text
632
+ if status_code == 'DL' && tracking_details.at('AvailableImages').try(:text) == 'SIGNATURE_PROOF_OF_DELIVERY'
633
+ delivery_signature = tracking_details.at('DeliverySignatureName').try(:text)
634
+ end
636
635
  end
637
636
 
638
637
  if origin_node = tracking_details.at('OriginLocationAddress')
@@ -816,16 +816,18 @@ module ActiveShipping
816
816
  # Build status hash
817
817
  status_nodes = first_package.css('Activity > Status > StatusType')
818
818
 
819
- # Prefer a delivery node
820
- status_node = status_nodes.detect { |x| x.at('Code').text == 'D' }
821
- status_node ||= status_nodes.first
819
+ if status_nodes.present?
820
+ # Prefer a delivery node
821
+ status_node = status_nodes.detect { |x| x.at('Code').text == 'D' }
822
+ status_node ||= status_nodes.first
822
823
 
823
- status_code = status_node.at('Code').text
824
- status_description = status_node.at('Description').text
825
- status = TRACKING_STATUS_CODES[status_code]
824
+ status_code = status_node.at('Code').try(:text)
825
+ status_description = status_node.at('Description').try(:text)
826
+ status = TRACKING_STATUS_CODES[status_code]
826
827
 
827
- if status_description =~ /out.*delivery/i
828
- status = :out_for_delivery
828
+ if status_description =~ /out.*delivery/i
829
+ status = :out_for_delivery
830
+ end
829
831
  end
830
832
 
831
833
  origin, destination = %w(Shipper ShipTo).map do |location|
@@ -6,21 +6,21 @@ module ActiveShipping
6
6
  # The origin of the shipment
7
7
  # @return [ActiveShipping::Location]
8
8
  #
9
- # @!attribute desination
10
- # The desination of the shipment
9
+ # @!attribute destination
10
+ # The destination of the shipment
11
11
  # @return [ActiveShipping::Location]
12
12
  #
13
13
  # @!attribute package_rates
14
- # A list of rates for all the packages in the shipment.
14
+ # A list of rates for all the packages in the shipment
15
15
  # @return [Array<{:rate => Integer, :package => ActiveShipping::Package}>]
16
16
  #
17
17
  # @!attribute carrier
18
- # The name of the carrier (i.e. , e.g. 'USPS', 'FedEx')
18
+ # The name of the carrier (e.g. 'USPS', 'FedEx')
19
19
  # @return [String]
20
20
  # @see ActiveShipping::Carrier.name
21
21
  #
22
22
  # @!attribute service_name
23
- # The name of the shipping service (e.g. `"First Class Ground"`)
23
+ # The name of the shipping service (e.g. 'First Class Ground')
24
24
  # @return [String]
25
25
  #
26
26
  # @!attribute service_code
@@ -28,26 +28,26 @@ module ActiveShipping
28
28
  # @return [String]
29
29
  #
30
30
  # @!attribute description
31
- # Public description of the shipping service (e.g. "2 days delivery")
31
+ # Public description of the shipping service (e.g. '2 days delivery')
32
32
  # @return [String]
33
33
  #
34
34
  # @!attribute shipping_date
35
35
  # The date on which the shipment will be expected. Normally, this means that the
36
- # delivery date range can only pe prmoised if the shipment is handed over on or
36
+ # delivery date range can only be promised if the shipment is handed over on or
37
37
  # before this date.
38
38
  # @return [Date]
39
39
  #
40
40
  # @!attribute delivery_date
41
- # The date on which the shipment will be delivered. This is usually only availablee
42
- # for express shipments; in order cases a {#delivery_range} is given instead.
41
+ # The date on which the shipment will be delivered. This is usually only available
42
+ # for express shipments; in other cases a {#delivery_range} is given instead.
43
43
  # @return [Date]
44
44
  #
45
45
  # @!attribute delivery_range
46
- # The minimum and maximum date of when the shipment is expected to be delivered.
46
+ # The minimum and maximum date of when the shipment is expected to be delivered
47
47
  # @return [Array<Date>]
48
48
  #
49
49
  # @!attribute currency
50
- # ISO4217 currency code of the quoted rate estimates, e.g. `CAD`, `EUR`, or `USD`.
50
+ # ISO4217 currency code of the quoted rate estimates (e.g. `CAD`, `EUR`, or `USD`)
51
51
  # @return [String]
52
52
  # @see http://en.wikipedia.org/wiki/ISO_4217
53
53
  #
@@ -60,11 +60,11 @@ module ActiveShipping
60
60
  # @return [Integer]
61
61
  #
62
62
  # @!attribute phone_required
63
- # Specifies if a phone number is required for the shipping rate.
63
+ # Specifies if a phone number is required for the shipping rate
64
64
  # @return [Boolean]
65
65
  #
66
66
  # @!attribute insurance_price
67
- # The price of insurance in cents.
67
+ # The price of insurance in cents
68
68
  # @return [Integer]
69
69
  #
70
70
  # @!attribute delivery_category
@@ -184,7 +184,7 @@ module ActiveShipping
184
184
  private
185
185
 
186
186
  # Returns a Date object for a given input
187
- # @param [String, Date, Time, DateTime, ...] The object to infer a date from.
187
+ # @param date [String, Date, Time, DateTime, ...] The object to infer a date from.
188
188
  # @return [Date, nil] The Date object absed on the input, or `nil` if no date
189
189
  # could be determined.
190
190
  def date_for(date)
@@ -2,9 +2,9 @@ module ActiveShipping
2
2
 
3
3
  # The `RateResponse` object is returned by the {ActiveShipping::Carrier#find_rates}
4
4
  # call. The most important method is {#rates}, which will return a list of possible
5
- # shipping options with ane stiated price.
5
+ # shipping options with an estimated price.
6
6
  #
7
- # @note Some carriers provide more information that others, so not all attributes
7
+ # @note Some carriers provide more information than others, so not all attributes
8
8
  # will be set, depending on what carrier you are using.
9
9
  #
10
10
  # @!attribute rates
@@ -1,3 +1,3 @@
1
1
  module ActiveShipping
2
- VERSION = "1.8.5"
2
+ VERSION = "1.8.6"
3
3
  end
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <TrackReply xmlns="http://fedex.com/ws/track/v7" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <HighestSeverity>SUCCESS</HighestSeverity>
4
+ <Notifications>
5
+ <Severity>SUCCESS</Severity>
6
+ <Source>trck</Source>
7
+ <Code>0</Code>
8
+ <Message>Request was successfully processed.</Message>
9
+ <LocalizedMessage>Request was successfully processed.</LocalizedMessage>
10
+ </Notifications>
11
+ <TransactionDetail>
12
+ <CustomerTransactionId>ActiveShipping</CustomerTransactionId>
13
+ </TransactionDetail>
14
+ <Version>
15
+ <ServiceId>trck</ServiceId>
16
+ <Major>7</Major>
17
+ <Intermediate>0</Intermediate>
18
+ <Minor>0</Minor>
19
+ </Version>
20
+ <CompletedTrackDetails>
21
+ <HighestSeverity>SUCCESS</HighestSeverity>
22
+ <Notifications>
23
+ <Severity>SUCCESS</Severity>
24
+ <Source>trck</Source>
25
+ <Code>0</Code>
26
+ <Message>Request was successfully processed.</Message>
27
+ <LocalizedMessage>Request was successfully processed.</LocalizedMessage>
28
+ </Notifications>
29
+ <DuplicateWaybill>false</DuplicateWaybill>
30
+ <MoreData>false</MoreData>
31
+ <TrackDetails>
32
+ <Notification>
33
+ <Severity>FAILURE</Severity>
34
+ <Source>trck</Source>
35
+ <Code>9080</Code>
36
+ <Message>Sorry, we are unable to process your tracking request. Please contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.</Message>
37
+ <LocalizedMessage>Sorry, we are unable to process your tracking request. Please contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.</LocalizedMessage>
38
+ </Notification>
39
+ <StatusDetail>
40
+ <Location>
41
+ <Residential>false</Residential>
42
+ </Location>
43
+ </StatusDetail>
44
+ <PackageSequenceNumber>0</PackageSequenceNumber>
45
+ <PackageCount>0</PackageCount>
46
+ <DeliveryAttempts>0</DeliveryAttempts>
47
+ <TotalUniqueAddressCountInConsolidation>0</TotalUniqueAddressCountInConsolidation>
48
+ <RedirectToHoldEligibility>INELIGIBLE</RedirectToHoldEligibility>
49
+ </TrackDetails>
50
+ </CompletedTrackDetails>
51
+ </TrackReply>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0"?>
2
+ <TrackResponse>
3
+ <Response>
4
+ <ResponseStatusCode>1</ResponseStatusCode>
5
+ <ResponseStatusDescription>Success</ResponseStatusDescription>
6
+ </Response>
7
+ <Shipment>
8
+ <Shipper/>
9
+ <ShipmentWeight>
10
+ <UnitOfMeasurement>
11
+ <Code>LBS</Code>
12
+ </UnitOfMeasurement>
13
+ <Weight>0.00</Weight>
14
+ </ShipmentWeight>
15
+ <Service>
16
+ <Code>YW</Code>
17
+ <Description>UPS SUREPOST</Description>
18
+ </Service>
19
+ <ShipmentIdentificationNumber>1Z5FX0076803466397</ShipmentIdentificationNumber>
20
+ <DeliveryDateUnavailable>
21
+ <Type>Scheduled Delivery</Type>
22
+ <Description>Scheduled Delivery Date is not currently available, please try back later</Description>
23
+ </DeliveryDateUnavailable>
24
+ <Package>
25
+ <TrackingNumber>1Z5FX0076803466397</TrackingNumber>
26
+ <PackageWeight>
27
+ <UnitOfMeasurement>
28
+ <Code>LBS</Code>
29
+ </UnitOfMeasurement>
30
+ <Weight>0.00</Weight>
31
+ </PackageWeight>
32
+ </Package>
33
+ </Shipment>
34
+ </TrackResponse>
@@ -327,11 +327,11 @@ class FedExTest < Minitest::Test
327
327
  end
328
328
  end
329
329
 
330
- def test_response_failure_code_9045
330
+ def test_response_transient_failure
331
331
  mock_response = xml_fixture('fedex/tracking_response_failure_code_9045')
332
332
  @carrier.expects(:commit).returns(mock_response)
333
333
 
334
- error = assert_raises(ActiveShipping::ResponseContentError) do
334
+ error = assert_raises(ActiveShipping::ShipmentNotFound) do
335
335
  @carrier.find_tracking_info('123456789013')
336
336
  end
337
337
 
@@ -339,6 +339,18 @@ class FedExTest < Minitest::Test
339
339
  assert_equal msg, error.message
340
340
  end
341
341
 
342
+ def test_response_terminal_failure
343
+ mock_response = xml_fixture('fedex/tracking_response_failure_code_9080')
344
+ @carrier.expects(:commit).returns(mock_response)
345
+
346
+ error = assert_raises(ActiveShipping::ResponseContentError) do
347
+ @carrier.find_tracking_info('123456789013')
348
+ end
349
+
350
+ msg = 'Sorry, we are unable to process your tracking request. Please contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.'
351
+ assert_equal msg, error.message
352
+ end
353
+
342
354
  def test_parsing_response_without_notifications
343
355
  mock_response = xml_fixture('fedex/reply_without_notifications')
344
356
 
@@ -539,25 +551,27 @@ class FedExTest < Minitest::Test
539
551
  def test_tracking_info_with_empty_status_detail
540
552
  mock_response = xml_fixture('fedex/tracking_response_empty_status_detail')
541
553
  @carrier.expects(:commit).returns(mock_response)
554
+ response = @carrier.find_tracking_info('123456789012')
542
555
 
543
- error = assert_raises(ActiveShipping::Error) do
544
- @carrier.find_tracking_info('123456789012')
545
- end
546
-
547
- msg = 'Tracking response does not contain status information'
548
- assert_equal msg, error.message
556
+ assert_equal '123456789012', response.tracking_number
557
+ assert_nil response.status_code
558
+ assert_nil response.status
559
+ assert_nil response.status_description
560
+ assert_nil response.delivery_signature
561
+ assert_empty response.shipment_events
549
562
  end
550
563
 
551
- def test_tracking_info_with_invalid_status_code
552
- mock_response = xml_fixture('fedex/tracking_response_invalid_status_code')
564
+ def test_tracking_info_with_missing_status_code
565
+ mock_response = xml_fixture('fedex/tracking_response_missing_status_code')
553
566
  @carrier.expects(:commit).returns(mock_response)
554
567
 
555
- error = assert_raises(ActiveShipping::Error) do
556
- @carrier.find_tracking_info('123456789012')
557
- end
558
-
559
- msg = 'Tracking response does not contain status code'
560
- assert_equal msg, error.message
568
+ response = @carrier.find_tracking_info('123456789012')
569
+ assert_equal '123456789012', response.tracking_number
570
+ assert_nil response.status_code
571
+ assert_nil response.status
572
+ assert_nil response.status_description
573
+ assert_nil response.delivery_signature
574
+ assert_empty response.shipment_events
561
575
  end
562
576
 
563
577
  def test_create_shipment
@@ -166,6 +166,13 @@ class UPSTest < Minitest::Test
166
166
  assert_equal Time.parse('2015-01-29 00:00:00 UTC'), response.scheduled_delivery_date
167
167
  end
168
168
 
169
+ def test_find_tracking_info_should_handle_no_status_node
170
+ @carrier.expects(:commit).returns(xml_fixture('ups/no_status_node_success'))
171
+ response = @carrier.find_tracking_info('1Z5FX0076803466397')
172
+ assert_equal 'Success', response.params.fetch("Response").fetch("ResponseStatusDescription")
173
+ assert_empty response.shipment_events
174
+ end
175
+
169
176
  def test_response_parsing_an_oversize_package
170
177
  mock_response = xml_fixture('ups/package_exceeds_maximum_length')
171
178
  @carrier.expects(:commit).returns(mock_response)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_shipping
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.5
4
+ version: 1.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - James MacAulay
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-11-18 00:00:00.000000000 Z
14
+ date: 2016-11-29 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: quantified
@@ -293,9 +293,10 @@ files:
293
293
  - test/fixtures/xml/fedex/tracking_response_delivered_with_signature.xml
294
294
  - test/fixtures/xml/fedex/tracking_response_empty_status_detail.xml
295
295
  - test/fixtures/xml/fedex/tracking_response_failure_code_9045.xml
296
+ - test/fixtures/xml/fedex/tracking_response_failure_code_9080.xml
296
297
  - test/fixtures/xml/fedex/tracking_response_in_transit.xml
297
- - test/fixtures/xml/fedex/tracking_response_invalid_status_code.xml
298
298
  - test/fixtures/xml/fedex/tracking_response_invalid_tracking_number.xml
299
+ - test/fixtures/xml/fedex/tracking_response_missing_status_code.xml
299
300
  - test/fixtures/xml/fedex/tracking_response_multiple_results.xml
300
301
  - test/fixtures/xml/fedex/tracking_response_not_found.xml
301
302
  - test/fixtures/xml/fedex/tracking_response_shipment_exception.xml
@@ -333,6 +334,7 @@ files:
333
334
  - test/fixtures/xml/ups/delivery_dates_response.xml
334
335
  - test/fixtures/xml/ups/example_tracking_response.xml
335
336
  - test/fixtures/xml/ups/in_transit_shipment.xml
337
+ - test/fixtures/xml/ups/no_status_node_success.xml
336
338
  - test/fixtures/xml/ups/out_for_delivery_shipment.xml
337
339
  - test/fixtures/xml/ups/package_exceeds_maximum_length.xml
338
340
  - test/fixtures/xml/ups/rate_single_service.xml
@@ -514,9 +516,10 @@ test_files:
514
516
  - test/fixtures/xml/fedex/tracking_response_delivered_with_signature.xml
515
517
  - test/fixtures/xml/fedex/tracking_response_empty_status_detail.xml
516
518
  - test/fixtures/xml/fedex/tracking_response_failure_code_9045.xml
519
+ - test/fixtures/xml/fedex/tracking_response_failure_code_9080.xml
517
520
  - test/fixtures/xml/fedex/tracking_response_in_transit.xml
518
- - test/fixtures/xml/fedex/tracking_response_invalid_status_code.xml
519
521
  - test/fixtures/xml/fedex/tracking_response_invalid_tracking_number.xml
522
+ - test/fixtures/xml/fedex/tracking_response_missing_status_code.xml
520
523
  - test/fixtures/xml/fedex/tracking_response_multiple_results.xml
521
524
  - test/fixtures/xml/fedex/tracking_response_not_found.xml
522
525
  - test/fixtures/xml/fedex/tracking_response_shipment_exception.xml
@@ -554,6 +557,7 @@ test_files:
554
557
  - test/fixtures/xml/ups/delivery_dates_response.xml
555
558
  - test/fixtures/xml/ups/example_tracking_response.xml
556
559
  - test/fixtures/xml/ups/in_transit_shipment.xml
560
+ - test/fixtures/xml/ups/no_status_node_success.xml
557
561
  - test/fixtures/xml/ups/out_for_delivery_shipment.xml
558
562
  - test/fixtures/xml/ups/package_exceeds_maximum_length.xml
559
563
  - test/fixtures/xml/ups/rate_single_service.xml