Skip to content

Commit

Permalink
add Australia Post carrier
Browse files Browse the repository at this point in the history
- move fixture data from test_helper into its own file
  • Loading branch information
Khoa Nguyen committed Mar 29, 2011
1 parent b3894d0 commit 4f98eb3
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 129 deletions.
5 changes: 3 additions & 2 deletions lib/active_shipping/shipping/carriers.rb
Expand Up @@ -6,15 +6,16 @@
require 'active_shipping/shipping/carriers/kunaki'
require 'active_shipping/shipping/carriers/canada_post'
require 'active_shipping/shipping/carriers/new_zealand_post'
require 'active_shipping/shipping/carriers/australia_post'

module ActiveMerchant
module Shipping
module Carriers
class <<self
def all
[BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki, CanadaPost, NewZealandPost]
[BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki, CanadaPost, NewZealandPost, AustraliaPost]
end
end
end
end
end
end
80 changes: 80 additions & 0 deletions lib/active_shipping/shipping/carriers/australia_post.rb
@@ -0,0 +1,80 @@
module ActiveMerchant
module Shipping
class AustraliaPost < Carrier

cattr_reader :name, :api_url
cattr_writer :default_location

@@name = "Australia Post"
@@default_location = Location.new(:postal_code => '2000', :country => 'Australia')
@@api_url = "http://drc.edeliver.com.au/ratecalc.asp"

def find_rates(origin, destination, package, options = {})
rates = []

origin = self.class.default_location unless origin.is_a?(Location)

options[:service_type] = Array(options[:service_type]).flatten
if options[:service_type].empty?
if destination.country.to_s == 'Australia'
options[:service_type] = %w[STANDARD EXPRESS]
else
options[:service_type] = %w[AIR SEA]
end
end

options[:service_type].each do |service_type|
rate_request_url = build_rate_request(origin, destination, package, {:service_type => service_type})
response = ssl_get(rate_request_url)
rates << parse_rate_response(origin, destination, package, response, {:service_type => service_type})
end

rates
end

protected

def self.default_location
@@default_location
end

private

def build_rate_request(origin, destination, package, options)
self.class.api_url + "?" + {
Pickup_Postcode: destination.postal_code,
Destination_Postcode: origin.postal_code,
Country: destination.country.code(:alpha2),
Service_Type: options[:service_type],
Weight: package.grams,
Length: package.centimetres(:length) * 10,
Width: package.centimetres(:width) * 10,
Height: package.centimetres(:height) * 10,
Quantity: 1
}.to_param
end

def parse_rate_response(origin, destination, package, response, options)
price = nil, delivery_date = nil

response.scan( /(\w+)=(.+)/ ).each do |key, value|
value.strip!

case key
when 'charge'
price = value.to_f
when 'days'
delivery_date = value.to_i.days.from_now
when 'err_msg'
raise "Error: #{value}" unless value == "OK"
else
raise "Unknown response from #{self.class.api_url}: #{key} => #{value}"
end
end

RateEstimate.new(origin, destination, self.class.name, options[:service_type],
:total_price => price, :currency => 'AUD', :package => package, :delivery_date => delivery_date)
end
end
end
end
129 changes: 129 additions & 0 deletions test/fixture_helper.rb
@@ -0,0 +1,129 @@
module ActiveMerchant
module Shipping
module TestFixtures

mattr_reader :packages, :locations

@@packages = {
:just_ounces => Package.new(16, nil, :units => :imperial),
:just_grams => Package.new(1000, nil),
:all_imperial => Package.new(16, [1,8,12], :units => :imperial),
:all_metric => Package.new(1000, [2,20,40]),
:book => Package.new(250, [14, 19, 2]),
:wii => Package.new((7.5 * 16), [15, 10, 4.5], :units => :imperial, :value => 269.99, :currency => 'GBP'),
:american_wii => Package.new((7.5 * 16), [15, 10, 4.5], :units => :imperial, :value => 269.99, :currency => 'USD'),
:worthless_wii => Package.new((7.5 * 16), [15, 10, 4.5], :units => :imperial, :value => 0.0, :currency => 'USD'),
:poster => Package.new(100, [93,10], :cylinder => true),
:small_half_pound => Package.new(8, [1,1,1], :units => :imperial),
:big_half_pound => Package.new((16 * 50), [24,24,36], :units => :imperial),
:chocolate_stuff => Package.new(80, [2,6,12], :units => :imperial),
:shipping_container => Package.new(2200000, [2440, 2600, 6058], :description => '20 ft Standard Container', :units => :metric)
}

@@locations = {
:bare_ottawa => Location.new(:country => 'CA', :postal_code => 'K1P 1J1'),
:bare_beverly_hills => Location.new(:country => 'US', :zip => '90210'),
:ottawa => Location.new(:country => 'CA', :province => 'ON', :city => 'Ottawa',
:address1 => '110 Laurier Avenue West', :postal_code => 'K1P 1J1',
:phone => '1-613-580-2400', :fax => '1-613-580-2495'),
:beverly_hills => Location.new(:country => 'US', :state => 'CA', :city => 'Beverly Hills',
:address1 => '455 N. Rexford Dr.', :address2 => '3rd Floor', :zip => '90210',
:phone => '1-310-285-1013', :fax => '1-310-275-8159'),
:real_home_as_commercial => Location.new(
:country => 'US',
:city => 'Tampa',
:state => 'FL',
:address1 => '7926 Woodvale Circle',
:zip => '33615',
:address_type => 'commercial'), # means that UPS will default to commercial if it doesn't know
:fake_home_as_commercial => Location.new(
:country => 'US',
:state => 'FL',
:address1 => '123 fake st.',
:zip => '33615',
:address_type => 'commercial'),
:real_google_as_commercial => Location.new(
:country => 'US',
:city => 'Mountain View',
:state => 'CA',
:address1 => '1600 Amphitheatre Parkway',
:zip => '94043',
:address_type => 'commercial'),
:real_google_as_residential => Location.new(
:country => 'US',
:city => 'Mountain View',
:state => 'CA',
:address1 => '1600 Amphitheatre Parkway',
:zip => '94043',
:address_type => 'residential'), # means that will default to residential if it doesn't know
:fake_google_as_commercial => Location.new(
:country => 'US',
:city => 'Mountain View',
:state => 'CA',
:address1 => '123 bogusland dr.',
:zip => '94043',
:address_type => 'commercial'),
:fake_google_as_residential => Location.new(
:country => 'US',
:city => 'Mountain View',
:state => 'CA',
:address1 => '123 bogusland dr.',
:zip => '94043',
:address_type => 'residential'), # means that will default to residential if it doesn't know
:fake_home_as_residential => Location.new(
:country => 'US',
:state => 'FL',
:address1 => '123 fake st.',
:zip => '33615',
:address_type => 'residential'),
:real_home_as_residential => Location.new(
:country => 'US',
:city => 'Tampa',
:state => 'FL',
:address1 => '7926 Woodvale Circle',
:zip => '33615',
:address_type => 'residential'),
:london => Location.new(
:country => 'GB',
:city => 'London',
:address1 => '170 Westminster Bridge Rd.',
:zip => 'SE1 7RW'),
:new_york => Location.new(
:country => 'US',
:city => 'New York',
:state => 'NY',
:address1 => '780 3rd Avenue',
:address2 => 'Suite 2601',
:zip => '10017'),
:new_york_with_name => Location.new(
:name => "Bob Bobsen",
:country => 'US',
:city => 'New York',
:state => 'NY',
:address1 => '780 3rd Avenue',
:address2 => 'Suite 2601',
:zip => '10017'),
:wellington => Location.new(
:country => 'NZ',
:city => 'Wellington',
:address1 => '85 Victoria St',
:address2 => 'Te Aro',
:postal_code => '6011'),
:sydney => Location.new(
:country => 'Australia',
:city => 'Sydney',
:address1 => '1 Regent St',
:address2 => 'Suite 101',
:postal_code => '2000'),
:melbourne => Location.new(
:country => 'Australia',
:city => 'Melbourne',
:address1 => '1 Collins St',
:address2 => 'Suite 101',
:postal_code => '3000')
}

end
end
end

54 changes: 54 additions & 0 deletions test/remote/australia_post_test.rb
@@ -0,0 +1,54 @@
require 'test_helper'

class AustraliaPostTest < Test::Unit::TestCase

def setup
@packages = TestFixtures.packages
@locations = TestFixtures.locations
@carrier = AustraliaPost.new
end

def test_successful_rate_request
# local postage
%w[STANDARD EXPRESS].each do |service_type|
rates = @carrier.find_rates(@locations[:sydney], @locations[:melbourne], @packages[:book], :service_type => service_type)
assert rates.any?
assert rates.first.is_a? RateEstimate
assert_equal rates.size, 1
end

@carrier.find_rates(@locations[:sydney], @locations[:melbourne], @packages[:book]).each do |rate|
assert rate.service_name =~ /STANDARD|EXPRESS/
end

# international postage
%w[AIR SEA].each do |service_type|
rates = @carrier.find_rates(@locations[:sydney], @locations[:beverly_hills], @packages[:book], :service_type => service_type)
assert rates.any?
assert rates.first.is_a? RateEstimate
assert_equal rates.size, 1
end

@carrier.find_rates(@locations[:sydney], @locations[:beverly_hills], @packages[:book]).each do |rate|
assert rate.service_name =~ /AIR|SEA/
end
end

def test_failure_rate_request
begin
# can't use air service for local
@carrier.find_rates(@locations[:sydney], @locations[:melbourne], @packages.values_at(:book), 'AIR')

flunk "expected an ActiveMerchant::Shipping::ResponseError to be raised"
rescue => exception
end

begin
# economy no longer available
@carrier.find_rates(@locations[:sydney], @locations[:wellington], @packages.values_at(:book), 'ECONOMY')

flunk "expected an ActiveMerchant::Shipping::ResponseError to be raised"
rescue => exception
end
end
end

0 comments on commit 4f98eb3

Please sign in to comment.