Permalink
Browse files

Merge pull request #85 from jnormore/canada_post_pws

Canada Post Platform Web Service + updates
  • Loading branch information...
2 parents ba97251 + a1c38cf commit 2d6133dea253ce5b1f94f215f70d444b4edebb9f @jnormore jnormore committed May 15, 2013
View
1 .gitignore
@@ -6,4 +6,5 @@ pkg
.dotest
Gemfile.lock
test/fixtures/live_credentials.yml
+.rbenv-version
View
1 .rbenv-version
@@ -1 +0,0 @@
-ree-1.8.7-2011.03
View
4 Gemfile
@@ -1,7 +1,3 @@
source :rubygems
gemspec
-
-group :test do
- gem 'ruby-debug'
-end
View
134 lib/active_shipping/shipping/carriers/canada_post_pws.rb
@@ -64,32 +64,6 @@ def initialize(options = {})
def requirements
[:api_key, :secret]
end
-
- def find_services(country = nil, options = {})
- url = endpoint + "rs/ship/service"
- url += "?country=#{country}" if country
- response = ssl_get(url, headers(options, RATE_MIMETYPE))
- parse_services_response(response)
- rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
- error_response(e.response.body, CPPWSRateResponse)
- end
-
- def find_service_options(service_code, country, options = {})
- url = endpoint + "rs/ship/service/#{service_code}"
- url += "?country=#{country}" if country
- response = ssl_get(url, headers(options, RATE_MIMETYPE))
- parse_service_options_response(response)
- rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
- error_response(e.response.body, CPPWSRateResponse)
- end
-
- def find_option_details(option_code, options = {})
- url = endpoint + "rs/ship/option/#{option_code}"
- response = ssl_get(url, headers(options, RATE_MIMETYPE))
- parse_option_response(response)
- rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
- error_response(e.response.body, CPPWSRateResponse)
- end
def find_rates(origin, destination, line_items = [], options = {}, package = nil, services = [])
url = endpoint + "rs/ship/price"
@@ -101,16 +75,7 @@ def find_rates(origin, destination, line_items = [], options = {}, package = nil
end
def find_tracking_info(pin, options = {})
- url = case pin.length
- when 12,13,16
- endpoint + "vis/track/pin/%s/detail" % pin
- when 15
- endpoint + "vis/track/dnc/%s/detail" % pin
- else
- raise InvalidPinFormatError
- end
-
- response = ssl_get(url, headers(options, TRACK_MIMETYPE))
+ response = ssl_get(tracking_url(pin), headers(options, TRACK_MIMETYPE))
parse_tracking_response(response)
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
error_response(e.response.body, CPPWSTrackingResponse)
@@ -120,16 +85,8 @@ def find_tracking_info(pin, options = {})
# line_items should be a list of PackageItem's
def create_shipment(origin, destination, package, line_items = [], options = {})
- raise MissingCustomerNumberError unless customer_number = options[:customer_number]
- if @platform_id.present?
- url = endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment"
- else
- url = endpoint + "rs/#{customer_number}/ncshipment"
- end
-
request_body = build_shipment_request(origin, destination, package, line_items, options)
-
- response = ssl_post(url, request_body, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
+ response = ssl_post(create_shipment_url(options), request_body, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
parse_shipment_response(response)
rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
error_response(e.response.body, CPPWSShippingResponse)
@@ -138,24 +95,12 @@ def create_shipment(origin, destination, package, line_items = [], options = {})
end
def retrieve_shipment(shipping_id, options = {})
- raise MissingCustomerNumberError unless customer_number = options[:customer_number]
- if @platform_id.present?
- url = endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}"
- else
- url = endpoint + "rs/#{customer_number}/ncshipment/#{shipping_id}"
- end
- response = ssl_post(url, nil, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
+ response = ssl_post(shipment_url(shipping_id, options), nil, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
shipping_response = parse_shipment_response(response)
end
def find_shipment_receipt(shipping_id, options = {})
- raise MissingCustomerNumberError unless customer_number = options[:customer_number]
- if @platform_id.present?
- url = endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}/receipt"
- else
- url = endpoint + "rs/#{customer_number}/ncshipment/#{shipping_id}/receipt"
- end
- response = ssl_get(url, headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
+ response = ssl_get(shipment_receipt_url(shipping_id, options), headers(options, SHIPMENT_MIMETYPE, SHIPMENT_MIMETYPE))
shipping_response = parse_shipment_receipt_response(response)
end
@@ -182,6 +127,28 @@ def retrieve_merchant_details(options = {})
rescue Exception => e
raise ResponseError.new(e.message)
end
+
+ def find_services(country = nil, options = {})
+ response = ssl_get(services_url(country), headers(options, RATE_MIMETYPE))
+ parse_services_response(response)
+ rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
+ error_response(e.response.body, CPPWSRateResponse)
+ end
+
+ def find_service_options(service_code, country, options = {})
+ response = ssl_get(services_url(country, service_code), headers(options, RATE_MIMETYPE))
+ parse_service_options_response(response)
+ rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
+ error_response(e.response.body, CPPWSRateResponse)
+ end
+
+ def find_option_details(option_code, options = {})
+ url = endpoint + "rs/ship/option/#{option_code}"
+ response = ssl_get(url, headers(options, RATE_MIMETYPE))
+ parse_option_response(response)
+ rescue ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError => e
+ error_response(e.response.body, CPPWSRateResponse)
+ end
def maximum_weight
Mass.new(MAX_WEIGHT, :kilograms)
@@ -527,7 +494,7 @@ def parse_merchant_details_response(response)
:contract_number => root_node.get_text('contract-number').to_s,
:username => root_node.get_text('merchant-username').to_s,
:password => root_node.get_text('merchant-password').to_s,
- :has_default_credit_card => root_node.get_text('has-default-credit-card') == 'true' ? true : false
+ :has_default_credit_card => root_node.get_text('has-default-credit-card') == 'true'
}
CPPWSMerchantDetailsResponse.new(true, "", {}, options)
end
@@ -582,6 +549,50 @@ def log(msg)
private
+ def tracking_url(pin)
+ case pin.length
+ when 12,13,16
+ endpoint + "vis/track/pin/%s/detail" % pin
+ when 15
+ endpoint + "vis/track/dnc/%s/detail" % pin
+ else
+ raise InvalidPinFormatError
+ end
+ end
+
+ def create_shipment_url(options)
+ raise MissingCustomerNumberError unless customer_number = options[:customer_number]
+ if @platform_id.present?
+ endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment"
+ else
+ endpoint + "rs/#{customer_number}/ncshipment"
+ end
+ end
+
+ def shipment_url(shipping_id, options={})
+ raise MissingCustomerNumberError unless customer_number = options[:customer_number]
+ if @platform_id.present?
+ endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}"
+ else
+ endpoint + "rs/#{customer_number}/ncshipment/#{shipping_id}"
+ end
+ end
+
+ def shipment_receipt_url(shipping_id, options={})
+ raise MissingCustomerNumberError unless customer_number = options[:customer_number]
+ if @platform_id.present?
+ endpoint + "rs/#{customer_number}-#{@platform_id}/ncshipment/#{shipping_id}/receipt"
+ else
+ endpoint + "rs/#{customer_number}/ncshipment/#{shipping_id}/receipt"
+ end
+ end
+
+ def services_url(country=nil, service_code=nil)
+ url = endpoint + "rs/ship/service"
+ url += "/#{service_code}" if service_code
+ url += "?country=#{country}" if country
+ end
+
def customer_credentials_valid?(credentials)
(credentials.keys & [:customer_api_key, :customer_secret]).any?
end
@@ -710,8 +721,6 @@ def shipping_options_node(available_options, options = {})
end
end
end
-
-
def expected_date_from_node(node)
if service = node.elements['service-standard']
@@ -810,7 +819,6 @@ def initialize(success, message, params = {}, options = {})
end
end
- # custom errors
class InvalidPinFormatError < StandardError; end
class MissingCustomerNumberError < StandardError; end
class MissingShippingNumberError < StandardError; end
View
35 test.rb
@@ -1,35 +0,0 @@
-require 'rubygems'
-require 'active_shipping'
-include ActiveMerchant::Shipping
-
-XmlNode
-
-# Package up a poster and a Wii for your nephew.
-packages = [
- Package.new( 100, # 100 grams
- [93,10], # 93 cm long, 10 cm diameterf
- :cylinder => true), # cylinders have different volume calculations
-
- Package.new( (7.5 * 16), # 7.5 lbs, times 16 oz/lb.
- [15, 10, 4.5], # 15x10x4.5 inches
- :units => :imperial) # not grams, not centimetres
-]
-
-
-# You live in Beverly Hills, he lives in Ottawa
-dest = Location.new(:country => 'US', :state => 'CA', :city => 'Beverly Hills', :zip => '90210')
-src = Location.new(:country => 'CA', :province => 'ON', :city => 'Ottawa', :postal_code => 'K1P 1J1')
-
-# Find out how much it'll be.
-cp = CanadaPostPWS.new(:api_key => 'c70da5ed5a0d2c32', :secret => 'b438ff7d9e581cd0d2edbe', :language => 'fr')
-response = cp.find_tracking_info('1371134583769923', {})
-
-response.shipment_events.reverse.map {|e| puts "#{e.name}: #{e.time.to_s(:short)} #{e.location} #{e.message}"}
-
-p response.tracking_number
-p response.service_name
-p response.expected_date
-p response.changed_date
-p response.change_reason
-
-
View
6 test/fixtures.yml
@@ -14,4 +14,8 @@ shipwire:
canada_post:
login: CPC_DEMO_XML
new_zealand_post:
- key: '4d9dc0f0-dda0-012e-066f-000c29b44ac0'
+ key: '4d9dc0f0-dda0-012e-066f-000c29b44ac0'
+canada_post_pws:
+ platform_id: 12345678
+ api_key: 1234789
+ secret: 1245743
View
51 test/performance/canada_post_pws.rb
@@ -1,51 +0,0 @@
-require 'test_helper'
-
-class CanadaPostPWSTest < Test::Unit::TestCase
-
- def setup
-
- @login = fixtures(:canada_post_pws)
-
- @cp = CanadaPostPWS.new(login.merge(:endpoint => "https://ct.soa-gw.canadapost.ca/"))
- # @cp.logger = Logger.new(STDOUT)
-
- @home_params = {
- :name => "John Smith",
- :company => "test",
- :phone => "613-555-1212",
- :address1 => "123 Elm St.",
- :city => 'Ottawa',
- :province => 'ON',
- :country => 'CA',
- :postal_code => 'K1P 1J1'
- }
-
- @dom_params = {
- :name => "John Smith Sr.",
- :company => "",
- :phone => '123-123-1234',
- :address1 => "5500 Oak Ave",
- :city => 'Vancouver',
- :province => 'BC',
- :country => 'CA',
- :postal_code => 'V5J 2T4'
- }
-
- @pkg1 = Package.new(1000, nil, :value => 10.00)
-
- @line_item1 = TestFixtures.line_items1
-
- end
-
- def test_generate_and_retrieve_shipping_label
- time = Benchmark.measure do
- 10.times do
- opts = {:customer_number => @login[:customer_number], :service => "DOM.XP"}
- response = @cp.create_shipment(@home_params, @dom_params, @pkg1, @line_item1, opts)
- response = @cp.retrieve_shipping_label(response)
- end
- end
- puts time
- end
-
-end
View
3 test/remote/canada_post_pws_platform_test.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'test_helper'
# All remote tests require Canada Post development environment credentials
@@ -126,7 +128,6 @@ def test_rates_USA_returns_small_packet_rates
rates = @cp.find_rates(@home_params, @usa_params, [@pkg1], build_options, @pkg2, ['USA.SP.AIR'])
assert_equal CPPWSRateResponse, rates.class
assert_equal RateEstimate, rates.rates.first.class
- puts rates.rates.map{|r| r.service_code}
assert rates.rates.map{|r| r.service_code}.include? "USA.SP.AIR"
end
View
1 test/test_helper.rb
@@ -10,7 +10,6 @@
require 'mocha'
require 'timecop'
require 'nokogiri'
-require 'ruby-debug'
XmlNode # trigger autorequire
View
10 test/unit/carriers/canada_post_pws_rating_test.rb
@@ -1,5 +1,4 @@
require 'test_helper'
-require 'pp'
class CanadaPostPwsRatingTest < Test::Unit::TestCase
def setup
@@ -53,13 +52,12 @@ def test_language_header
def test_find_rates
response = xml_fixture('canadapost_pws/rates_info')
expected_headers = {
- 'Authorization' => "Basic YzcwZGE1ZWQ1YTBkMmMzMjpiNDM4ZmY3ZDllNTgxY2QwZDJlZGJl\n",
+ 'Authorization' => "#{@cp.send(:encoded_authorization)}",
'Accept-Language' => 'en-CA',
'Accept' => 'application/vnd.cpc.ship.rate+xml',
'Content-Type' => 'application/vnd.cpc.ship.rate+xml'
}
- # TODO: with(anything, anything, expected_headers) won't pass for some reason... how does .with do equality?
- CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, anything).returns(response)
+ CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, expected_headers).returns(response)
rates_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
@@ -241,8 +239,8 @@ def test_parse_services_response
response = @cp.parse_services_response(body)
assert_equal 6, response.size
service = response.first
- assert_equal "INT.XP", service[0]
- assert_equal "Xpresspost International", service[1][:name]
+ assert_equal "INT.PW.ENV", service[0]
+ assert_equal "Priority Worldwide envelope INT'L", service[1][:name]
end
def test_parse_find_service_options_response
View
1 test/unit/carriers/canada_post_pws_register_test.rb
@@ -1,5 +1,4 @@
require 'test_helper'
-require 'pp'
class CanadaPostPwsRegisterTest < Test::Unit::TestCase
def setup
View
1 test/unit/carriers/canada_post_pws_shipping_test.rb
@@ -1,5 +1,4 @@
require 'test_helper'
-require 'pp'
class CanadaPostPwsShippingTest < Test::Unit::TestCase
def setup
View
1 test/unit/carriers/canada_post_pws_tracking_test.rb
@@ -1,5 +1,4 @@
require 'test_helper'
-require 'pp'
class CanadaPostPwsTrackingTest < Test::Unit::TestCase
def setup

0 comments on commit 2d6133d

Please sign in to comment.