Skip to content

Commit

Permalink
nzpost now supports tubes. Refactored multiple package support. Added…
Browse files Browse the repository at this point in the history
… tests
  • Loading branch information
Cameron Fowler committed Nov 29, 2010
1 parent 345f981 commit dd153cc
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 26 deletions.
25 changes: 18 additions & 7 deletions lib/active_shipping/shipping/carriers/new_zealand_post.rb
Expand Up @@ -21,7 +21,11 @@ def find_rates(origin, destination, packages, options = {})
packages = Array(packages)
rate_responses = []
packages.each do |package|
request_hash = build_rectangular_request_params(origin, destination, package, options)
if package.tube?
request_hash = build_tube_request_params(origin, destination, package, options)
else
request_hash = build_rectangular_request_params(origin, destination, package, options)
end
url = URL + '?' + request_hash.to_param
response = ssl_get(url)
rate_responses << parse_rate_response(origin, destination, package, response, options)
Expand Down Expand Up @@ -54,7 +58,18 @@ def build_rectangular_request_params(origin, destination, package, options = {}
}
end

def parse_rate_response(origin, destination, packages, response, options={})
def build_tube_request_params(origin, destination, package, options = {})
params = {
:postcode_src => origin.postal_code,
:postcode_dest => destination.postal_code,
:api_key => @options[:api_key],
:diameter => "#{package.centimetres(:width) * 10}",
:length => "#{package.centimetres(:length) * 10}",
:weight => "%.1f" % (package.weight.amount / 1000.0)
}
end

def parse_rate_response(origin, destination, package, response, options={})
xml = REXML::Document.new(response)
if response_success?(xml)
rate_estimates = []
Expand All @@ -66,7 +81,7 @@ def parse_rate_response(origin, destination, packages, response, options={})
:total_price => prod.get_text('cost').to_s.to_f,
:currency => 'NZD',
:service_code => prod.get_text('service').to_s,
:packages => packages)
:package => package)
end

RateResponse.new(true, "Success", Hash.from_xml(response), :rates => rate_estimates, :xml => response)
Expand All @@ -77,13 +92,11 @@ def parse_rate_response(origin, destination, packages, response, options={})
end

def combine_rate_responses(rate_responses, packages)

#if there are any failed responses, return on that response
rate_responses.each do |r|
return r if !r.success?
end


#group rate estimates by delivery type so that we can exclude any incomplete delviery types
rate_estimate_delivery_types = {}
rate_responses.each do |rr|
Expand All @@ -105,9 +118,7 @@ def combine_rate_responses(rate_responses, packages)
:service_code => r.service_code,
:packages => packages)
end

RateResponse.new(true, "Success", {}, :rates => combined_rate_estimates)

end

def response_success?(xml)
Expand Down
35 changes: 35 additions & 0 deletions test/remote/new_zealand_post_test.rb
Expand Up @@ -35,4 +35,39 @@ def test_failure_rates_request
assert_equal 'length Value is too large', e.message
end
end

def test_multiple_packages_are_combined_correctly
response_wii = @carrier.find_rates(@locations[:wellington],
@locations[:wellington],
@packages.values_at(:wii))
response_book = @carrier.find_rates(@locations[:wellington],
@locations[:wellington],
@packages.values_at(:book))
response_combined = @carrier.find_rates(@locations[:wellington],
@locations[:wellington],
@packages.values_at(:book, :wii))


wii_rates, book_rates, combined_rates = {}, {}, {}
response_wii.rate_estimates.each{ |r| wii_rates[r.service_name] = r.total_price }
response_book.rate_estimates.each{ |r| book_rates[r.service_name] = r.total_price }
response_combined.rate_estimates.each{ |r| combined_rates[r.service_name] = r.total_price }

# every item in combined rates is made up of entries from the other two rates
combined_rates.each do |service_name, total_price|
assert_equal (wii_rates[service_name] + book_rates[service_name]), total_price
end

# the size of the elements common between wii and book rates is the size of the
# combined rates hash.
assert_equal (wii_rates.keys & book_rates.keys).count, combined_rates.size

# uncomment this test for visual display of combining rates
#puts "\nWii:"
#response_wii.rate_estimates.each{ |r| puts "\nTotal Price: #{r.total_price}\nService Name: #{r.service_name}" }
#puts "\nBook:"
#response_book.rate_estimates.each{ |r| puts "\nTotal Price: #{r.total_price}\nService Name: #{r.service_name}" }
#puts "\nCombined"
#response_combined.rate_estimates.each{ |r| puts "\nTotal Price: #{r.total_price}\nService Name: #{r.service_name}" }
end
end
49 changes: 30 additions & 19 deletions test/unit/carriers/new_zealand_post_test.rb
Expand Up @@ -15,11 +15,16 @@ def setup
@line_items = [Package.new(400,
[25, 15, 2],
:description => "Edmonds Cookbook",
:units => :metric),
Package.new(300,
[85, 55],
:cylinder => true,
:description => "Movie Poster",
:units => :metric)]
end

def test_build_request_rectangular
params = @carrier.send(:build_rectangular_request_params, @origin, @destination, @line_items.first)
params = @carrier.send(:build_rectangular_request_params, @origin, @destination, @line_items[0])

assert_equal '123', params[:api_key]
assert_equal '250', params[:length]
Expand All @@ -30,29 +35,35 @@ def test_build_request_rectangular
assert_equal '6012', params[:postcode_dest]
end

def test_build_request_cyclinder
end
def test_build_request_cylinder
params = @carrier.send(:build_tube_request_params, @origin, @destination, @line_items[1])

def test_build_request_multiple_rectangular
assert_equal '123', params[:api_key]
assert_equal '850', params[:length]
assert_equal '550', params[:diameter]
assert_equal '0.3', params[:weight]
assert_equal '6011', params[:postcode_src]
assert_equal '6012', params[:postcode_dest]
end

#def test_parse_response
#rate_response = @carrier.send(:parse_rate_response, @origin, @destination, @line_items, @response)
#assert_not_nil rate_response
#assert_equal 13, rate_response.rates.size

def test_parse_response
rate_response = @carrier.send(:parse_rate_response, @origin, @destination, @line_items, @response)
assert_not_nil rate_response
assert_equal 13, rate_response.rates.size

## test first element
#first_element = rate_response.rates.first
#assert_equal 420, first_element.price
#assert_equal 'parcel_post', first_element.service_code
#assert_equal 'Parcel Post', first_element.service_name
# test first element
first_element = rate_response.rates.first
assert_equal 420, first_element.price
assert_equal 'parcel_post', first_element.service_code
assert_equal 'Parcel Post', first_element.service_name

## test last element
#last_element = rate_response.rates.last
#assert_equal 400, last_element.price
#assert_equal 'parcel_post_po_box_priority', last_element.service_code
#assert_equal 'Parcel Post Po Box Priority', last_element.service_name
#end
# test last element
last_element = rate_response.rates.last
assert_equal 400, last_element.price
assert_equal 'parcel_post_po_box_priority', last_element.service_code
assert_equal 'Parcel Post Po Box Priority', last_element.service_name
end

def test_response_success_with_successful_response
xml = REXML::Document.new(@response)
Expand Down

0 comments on commit dd153cc

Please sign in to comment.