bcarpenter-active_shipping 0.0.2

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.
Files changed (63) hide show
  1. data/CHANGELOG +23 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.markdown +173 -0
  4. data/Rakefile +52 -0
  5. data/VERSION +1 -0
  6. data/lib/active_shipping.rb +50 -0
  7. data/lib/active_shipping/lib/connection.rb +170 -0
  8. data/lib/active_shipping/lib/country.rb +319 -0
  9. data/lib/active_shipping/lib/error.rb +4 -0
  10. data/lib/active_shipping/lib/post_data.rb +22 -0
  11. data/lib/active_shipping/lib/posts_data.rb +47 -0
  12. data/lib/active_shipping/lib/requires_parameters.rb +16 -0
  13. data/lib/active_shipping/lib/utils.rb +18 -0
  14. data/lib/active_shipping/lib/validateable.rb +76 -0
  15. data/lib/active_shipping/shipping/base.rb +15 -0
  16. data/lib/active_shipping/shipping/carrier.rb +70 -0
  17. data/lib/active_shipping/shipping/carriers.rb +17 -0
  18. data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +16 -0
  19. data/lib/active_shipping/shipping/carriers/fedex.rb +315 -0
  20. data/lib/active_shipping/shipping/carriers/shipwire.rb +167 -0
  21. data/lib/active_shipping/shipping/carriers/ups.rb +368 -0
  22. data/lib/active_shipping/shipping/carriers/usps.rb +420 -0
  23. data/lib/active_shipping/shipping/location.rb +100 -0
  24. data/lib/active_shipping/shipping/package.rb +144 -0
  25. data/lib/active_shipping/shipping/rate_estimate.rb +54 -0
  26. data/lib/active_shipping/shipping/rate_response.rb +19 -0
  27. data/lib/active_shipping/shipping/response.rb +49 -0
  28. data/lib/active_shipping/shipping/shipment_event.rb +14 -0
  29. data/lib/active_shipping/shipping/tracking_response.rb +22 -0
  30. data/lib/certs/cacert.pem +7815 -0
  31. data/lib/vendor/quantified/MIT-LICENSE +22 -0
  32. data/lib/vendor/quantified/README.markdown +49 -0
  33. data/lib/vendor/quantified/Rakefile +21 -0
  34. data/lib/vendor/quantified/init.rb +0 -0
  35. data/lib/vendor/quantified/lib/quantified.rb +6 -0
  36. data/lib/vendor/quantified/lib/quantified/attribute.rb +208 -0
  37. data/lib/vendor/quantified/lib/quantified/length.rb +20 -0
  38. data/lib/vendor/quantified/lib/quantified/mass.rb +19 -0
  39. data/lib/vendor/quantified/test/length_test.rb +92 -0
  40. data/lib/vendor/quantified/test/mass_test.rb +88 -0
  41. data/lib/vendor/quantified/test/test_helper.rb +2 -0
  42. data/lib/vendor/test_helper.rb +13 -0
  43. data/lib/vendor/xml_node/README +36 -0
  44. data/lib/vendor/xml_node/Rakefile +21 -0
  45. data/lib/vendor/xml_node/benchmark/bench_generation.rb +32 -0
  46. data/lib/vendor/xml_node/init.rb +1 -0
  47. data/lib/vendor/xml_node/lib/xml_node.rb +222 -0
  48. data/lib/vendor/xml_node/test/test_generating.rb +94 -0
  49. data/lib/vendor/xml_node/test/test_parsing.rb +43 -0
  50. data/test/remote/fedex_test.rb +140 -0
  51. data/test/remote/shipwire_test.rb +88 -0
  52. data/test/remote/ups_test.rb +187 -0
  53. data/test/remote/usps_test.rb +184 -0
  54. data/test/test_helper.rb +167 -0
  55. data/test/unit/base_test.rb +18 -0
  56. data/test/unit/carriers/fedex_test.rb +78 -0
  57. data/test/unit/carriers/shipwire_test.rb +130 -0
  58. data/test/unit/carriers/ups_test.rb +81 -0
  59. data/test/unit/carriers/usps_test.rb +170 -0
  60. data/test/unit/location_test.rb +46 -0
  61. data/test/unit/package_test.rb +65 -0
  62. data/test/unit/response_test.rb +10 -0
  63. metadata +123 -0
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require "test/unit"
4
+
5
+ require File.dirname(__FILE__) + "/../lib/xml_node"
6
+
7
+ class TestXmlNode < Test::Unit::TestCase
8
+
9
+ def test_parse_sanity
10
+ assert_raise(ArgumentError) { XmlNode.parse }
11
+ assert_nothing_raised { XmlNode.parse('<feed/>') }
12
+ end
13
+
14
+
15
+ def test_parse_attributes
16
+ node = XmlNode.parse('<feed attr="1"/>')
17
+ assert_equal '1', node['attr']
18
+ assert_equal nil, node['attr2']
19
+ end
20
+
21
+ def test_parse_children
22
+ node = XmlNode.parse('<feed><element>text</element></feed>')
23
+ assert_equal XmlNode, node.children['element'].class
24
+ assert_equal 'text', node.children['element'].text
25
+ end
26
+
27
+ def test_enumerate_children
28
+ count = 0
29
+ XmlNode.parse('<feed><element>text</element><element>text</element></feed>').children.each { count += 1 }
30
+ assert_equal 2, count
31
+ end
32
+
33
+ def test_find_first
34
+ xml = XmlNode.parse('<feed><elem>1</elem><elem>2</elem><elem>3</elem></feed>')
35
+ assert_equal '1', xml.find(:first, '//elem').text
36
+ end
37
+
38
+ def test_find_all
39
+ xml = XmlNode.parse('<feed><elem>1</elem><elem>2</elem><elem>3</elem></feed>')
40
+ assert_equal ['1', '2', '3'], xml.find(:all, '//elem').collect(&:text)
41
+ end
42
+
43
+ end
@@ -0,0 +1,140 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class FedExTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @packages = TestFixtures.packages
7
+ @locations = TestFixtures.locations
8
+ @carrier = FedEx.new(fixtures(:fedex))
9
+ FedEx.logger = Logger.new('/Users/james/.active_merchant/fedex.log')
10
+ end
11
+
12
+ def test_us_to_canada
13
+ response = nil
14
+ assert_nothing_raised do
15
+ response = @carrier.find_rates(
16
+ @locations[:beverly_hills],
17
+ @locations[:ottawa],
18
+ @packages.values_at(:wii),
19
+ :test => true
20
+ )
21
+ assert !response.rates.blank?
22
+ response.rates.each do |rate|
23
+ assert_instance_of String, rate.service_name
24
+ assert_instance_of Fixnum, rate.price
25
+ end
26
+ end
27
+ end
28
+
29
+ def test_zip_to_zip_fails
30
+ begin
31
+ @carrier.find_rates(
32
+ Location.new(:zip => 40524),
33
+ Location.new(:zip => 40515),
34
+ @packages[:wii],
35
+ :test => true
36
+ )
37
+ rescue ResponseError => e
38
+ assert_match /country\s?code/i, e.message
39
+ assert_match /(missing|invalid)/, e.message
40
+ end
41
+ end
42
+
43
+ # FedEx requires a valid origin and destination postal code
44
+ def test_rates_for_locations_with_only_zip_and_country
45
+ response = @carrier.find_rates(
46
+ @locations[:bare_beverly_hills],
47
+ @locations[:bare_ottawa],
48
+ @packages.values_at(:wii),
49
+ :test => true
50
+ )
51
+
52
+ assert response.rates.size > 0
53
+ end
54
+
55
+ def test_rates_for_location_with_only_country_code
56
+ begin
57
+ response = @carrier.find_rates(
58
+ @locations[:bare_beverly_hills],
59
+ Location.new(:country => 'CA'),
60
+ @packages.values_at(:wii),
61
+ :test => true
62
+ )
63
+ rescue ResponseError => e
64
+ assert_match /postal code/i, e.message
65
+ assert_match /(missing|invalid)/i, e.message
66
+ end
67
+ end
68
+
69
+ def test_invalid_recipient_country
70
+ begin
71
+ response = @carrier.find_rates(
72
+ @locations[:bare_beverly_hills],
73
+ Location.new(:country => 'JP', :zip => '108-8361'),
74
+ @packages.values_at(:wii),
75
+ :test => true
76
+ )
77
+ rescue ResponseError => e
78
+ assert_match /postal code/i, e.message
79
+ assert_match /(missing|invalid)/i, e.message
80
+ end
81
+ end
82
+
83
+ def test_ottawa_to_beverly_hills
84
+ response = nil
85
+ assert_nothing_raised do
86
+ response = @carrier.find_rates(
87
+ @locations[:ottawa],
88
+ @locations[:beverly_hills],
89
+ @packages.values_at(:book, :wii),
90
+ :test => true
91
+ )
92
+ assert !response.rates.blank?
93
+ response.rates.each do |rate|
94
+ assert_instance_of String, rate.service_name
95
+ assert_instance_of Fixnum, rate.price
96
+ end
97
+ end
98
+ end
99
+
100
+ def test_ottawa_to_london
101
+ response = nil
102
+ assert_nothing_raised do
103
+ response = @carrier.find_rates(
104
+ @locations[:ottawa],
105
+ @locations[:london],
106
+ @packages.values_at(:book, :wii),
107
+ :test => true
108
+ )
109
+ assert !response.rates.blank?
110
+ response.rates.each do |rate|
111
+ assert_instance_of String, rate.service_name
112
+ assert_instance_of Fixnum, rate.price
113
+ end
114
+ end
115
+ end
116
+
117
+ def test_beverly_hills_to_london
118
+ response = nil
119
+ assert_nothing_raised do
120
+ response = @carrier.find_rates(
121
+ @locations[:beverly_hills],
122
+ @locations[:london],
123
+ @packages.values_at(:book, :wii),
124
+ :test => true
125
+ )
126
+ assert !response.rates.blank?
127
+ response.rates.each do |rate|
128
+ assert_instance_of String, rate.service_name
129
+ assert_instance_of Fixnum, rate.price
130
+ end
131
+ end
132
+ end
133
+
134
+ def test_tracking
135
+ assert_nothing_raised do
136
+ @carrier.find_tracking_info('077973360403984', :test => true)
137
+ end
138
+ end
139
+
140
+ end
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class RemoteShipwireTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @packages = TestFixtures.packages
7
+ @locations = TestFixtures.locations
8
+ @carrier = Shipwire.new(fixtures(:shipwire))
9
+ @item1 = { :sku => 'AF0001', :quantity => 2 }
10
+ @item2 = { :sku => 'AF0002', :quantity => 1 }
11
+ @items = [@item1, @item2]
12
+ end
13
+
14
+ def test_successful_domestic_rates_request_for_single_line_item
15
+ response = @carrier.find_rates(
16
+ @locations[:ottawa],
17
+ @locations[:beverly_hills],
18
+ @packages.values_at(:book, :wii),
19
+ :items => [@item1],
20
+ :order_id => '#1000'
21
+ )
22
+
23
+ assert response.success?
24
+ assert_equal 3, response.rates.size
25
+ assert_equal ['1D', '2D', 'GD'], response.rates.collect(&:service_code).sort
26
+ end
27
+
28
+ def test_successful_domestic_rates_request_for_multiple_line_items
29
+ response = @carrier.find_rates(
30
+ @locations[:ottawa],
31
+ @locations[:beverly_hills],
32
+ @packages.values_at(:book, :wii),
33
+ :items => @items,
34
+ :order_id => '#1000'
35
+ )
36
+
37
+ assert response.success?
38
+ assert_equal 3, response.rates.size
39
+ assert_equal ['1D', '2D', 'GD'], response.rates.collect(&:service_code).sort
40
+ end
41
+
42
+ def test_successful_international_rates_request_for_single_line_item
43
+ response = @carrier.find_rates(
44
+ @locations[:ottawa],
45
+ @locations[:london],
46
+ @packages.values_at(:book, :wii),
47
+ :items => [@item1],
48
+ :order_id => '#1000'
49
+ )
50
+
51
+ assert response.success?
52
+ assert_equal 1, response.rates.size
53
+ assert_equal ['INTL'], response.rates.collect(&:service_code)
54
+ end
55
+
56
+ def test_invalid_credentials
57
+ shipwire = Shipwire.new(
58
+ :login => 'your@email.com',
59
+ :password => 'password'
60
+ )
61
+
62
+ begin
63
+ assert_raises(ActiveMerchant::Shipping::ResponseError) do
64
+ shipwire.find_rates(
65
+ @locations[:ottawa],
66
+ @locations[:beverly_hills],
67
+ @packages.values_at(:book, :wii),
68
+ :items => @items,
69
+ :order_id => '#1000'
70
+ )
71
+ end
72
+ rescue ResponseError => e
73
+ assert_equal "Could not verify e-mail/password combination", response.message
74
+ end
75
+ end
76
+
77
+ def test_validate_credentials_with_valid_credentials
78
+ assert @carrier.valid_credentials?
79
+ end
80
+
81
+ def test_validate_credentials_with_invalid_credentials
82
+ shipwire = Shipwire.new(
83
+ :login => 'your@email.com',
84
+ :password => 'password'
85
+ )
86
+ assert !shipwire.valid_credentials?
87
+ end
88
+ end
@@ -0,0 +1,187 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class UPSTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @packages = TestFixtures.packages
7
+ @locations = TestFixtures.locations
8
+ @carrier = UPS.new(fixtures(:ups))
9
+ end
10
+
11
+ def test_tracking
12
+ assert_nothing_raised do
13
+ response = @carrier.find_tracking_info('1Z5FX0076803466397')
14
+ end
15
+ end
16
+
17
+ def test_tracking_with_bad_number
18
+ assert_raises ResponseError do
19
+ response = @carrier.find_tracking_info('1Z12345')
20
+ end
21
+ end
22
+
23
+ def test_tracking_with_another_number
24
+ assert_nothing_raised do
25
+ response = @carrier.find_tracking_info('1Z67Y4260390005815')
26
+ end
27
+ end
28
+
29
+ def test_us_to_uk
30
+ response = nil
31
+ assert_nothing_raised do
32
+ response = @carrier.find_rates(
33
+ @locations[:beverly_hills],
34
+ @locations[:london],
35
+ @packages.values_at(:big_half_pound),
36
+ :test => true
37
+ )
38
+ end
39
+ end
40
+
41
+ def test_puerto_rico
42
+ response = nil
43
+ assert_nothing_raised do
44
+ response = @carrier.find_rates(
45
+ @locations[:beverly_hills],
46
+ Location.new(:city => 'Ponce', :country => 'US', :state => 'PR', :zip => '00733-1283'),
47
+ @packages.values_at(:big_half_pound),
48
+ :test => true
49
+ )
50
+ end
51
+ end
52
+
53
+ def test_just_country_given
54
+ response = @carrier.find_rates(
55
+ @locations[:beverly_hills],
56
+ Location.new(:country => 'CA'),
57
+ Package.new(100, [5,10,20])
58
+ )
59
+ assert_not_equal [], response.rates
60
+ end
61
+
62
+ def test_ottawa_to_beverly_hills
63
+ response = nil
64
+ assert_nothing_raised do
65
+ response = @carrier.find_rates(
66
+ @locations[:ottawa],
67
+ @locations[:beverly_hills],
68
+ @packages.values_at(:book, :wii),
69
+ :test => true
70
+ )
71
+ end
72
+
73
+ assert response.success?, response.message
74
+ assert_instance_of Hash, response.params
75
+ assert_instance_of String, response.xml
76
+ assert_instance_of Array, response.rates
77
+ assert_not_equal [], response.rates
78
+
79
+ rate = response.rates.first
80
+ assert_equal 'UPS', rate.carrier
81
+ assert_equal 'CAD', rate.currency
82
+ assert_instance_of Fixnum, rate.total_price
83
+ assert_instance_of Fixnum, rate.price
84
+ assert_instance_of String, rate.service_name
85
+ assert_instance_of String, rate.service_code
86
+ assert_instance_of Array, rate.package_rates
87
+ assert_equal @packages.values_at(:book, :wii), rate.packages
88
+
89
+ package_rate = rate.package_rates.first
90
+ assert_instance_of Hash, package_rate
91
+ assert_instance_of Package, package_rate[:package]
92
+ assert_nil package_rate[:rate]
93
+ end
94
+
95
+ def test_ottawa_to_us_fails_without_zip
96
+ assert_raises ResponseError do
97
+ @carrier.find_rates(
98
+ @locations[:ottawa],
99
+ Location.new(:country => 'US'),
100
+ @packages.values_at(:book, :wii),
101
+ :test => true
102
+ )
103
+ end
104
+ end
105
+
106
+ def test_ottawa_to_us_succeeds_with_only_zip
107
+ assert_nothing_raised do
108
+ @carrier.find_rates(
109
+ @locations[:ottawa],
110
+ Location.new(:country => 'US', :zip => 90210),
111
+ @packages.values_at(:book, :wii),
112
+ :test => true
113
+ )
114
+ end
115
+ end
116
+
117
+ def test_bare_packages
118
+ response = nil
119
+ p = Package.new(0,0)
120
+ assert_nothing_raised do
121
+ response = @carrier.find_rates(
122
+ @locations[:beverly_hills], # imperial (U.S. origin)
123
+ @locations[:ottawa],
124
+ p,
125
+ :test => true
126
+ )
127
+ end
128
+ assert response.success?, response.message
129
+ assert_nothing_raised do
130
+ response = @carrier.find_rates(
131
+ @locations[:ottawa],
132
+ @locations[:beverly_hills], # metric
133
+ p,
134
+ :test => true
135
+ )
136
+ end
137
+ assert response.success?, response.message
138
+ end
139
+
140
+ def test_different_rates_for_residential_and_commercial_destinations
141
+ responses = {}
142
+ locations = [
143
+ :real_home_as_residential, :real_home_as_commercial,
144
+ :fake_home_as_residential, :fake_home_as_commercial,
145
+ :real_google_as_residential, :real_google_as_commercial,
146
+ :fake_google_as_residential, :fake_google_as_commercial
147
+ ]
148
+
149
+ locations.each do |location|
150
+ responses[location] = @carrier.find_rates(
151
+ @locations[:beverly_hills],
152
+ @locations[location],
153
+ @packages.values_at(:chocolate_stuff)
154
+ )
155
+ end
156
+
157
+ prices_of = lambda {|sym| responses[sym].rates.map(&:price)}
158
+
159
+ # this is how UPS does things...
160
+ # if it's a real residential address and UPS knows it, then they return
161
+ # residential rates whether or not we have the ResidentialAddressIndicator:
162
+ assert_equal prices_of.call(:real_home_as_residential), prices_of.call(:real_home_as_commercial)
163
+
164
+ # if UPS doesn't know about the address, and we HAVE the ResidentialAddressIndicator,
165
+ # then UPS will default to residential rates:
166
+ assert_equal prices_of.call(:real_home_as_residential), prices_of.call(:fake_home_as_residential)
167
+
168
+ # if UPS doesn't know about the address, and we DON'T have the ResidentialAddressIndicator,
169
+ # then UPS will default to commercial rates:
170
+ assert_not_equal prices_of.call(:fake_home_as_residential), prices_of.call(:fake_home_as_commercial)
171
+ assert prices_of.call(:fake_home_as_residential).first > prices_of.call(:fake_home_as_commercial).first
172
+
173
+
174
+ # if it's a real commercial address and UPS knows it, then they return
175
+ # commercial rates whether or not we have the ResidentialAddressIndicator:
176
+ assert_equal prices_of.call(:real_google_as_commercial), prices_of.call(:real_google_as_residential)
177
+
178
+ # if UPS doesn't know about the address, and we DON'T have the ResidentialAddressIndicator,
179
+ # then UPS will default to commercial rates:
180
+ assert_equal prices_of.call(:real_google_as_commercial), prices_of.call(:fake_google_as_commercial)
181
+
182
+ # if UPS doesn't know about the address, and we HAVE the ResidentialAddressIndicator,
183
+ # then UPS will default to residential rates:
184
+ assert_not_equal prices_of.call(:fake_google_as_commercial), prices_of.call(:fake_google_as_residential)
185
+ assert prices_of.call(:fake_home_as_residential).first > prices_of.call(:fake_home_as_commercial).first
186
+ end
187
+ end