ups-ruby 0.8.3

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.hound.yml +2 -0
  4. data/.rubocop.yml +1064 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +46 -0
  8. data/LICENSE.txt +14 -0
  9. data/README.md +78 -0
  10. data/Rakefile +17 -0
  11. data/lib/ups-ruby.rb +2 -0
  12. data/lib/ups.rb +33 -0
  13. data/lib/ups/builders/address_builder.rb +135 -0
  14. data/lib/ups/builders/builder_base.rb +216 -0
  15. data/lib/ups/builders/organisation_builder.rb +74 -0
  16. data/lib/ups/builders/rate_builder.rb +21 -0
  17. data/lib/ups/builders/ship_accept_builder.rb +30 -0
  18. data/lib/ups/builders/ship_confirm_builder.rb +103 -0
  19. data/lib/ups/builders/shipper_builder.rb +88 -0
  20. data/lib/ups/connection.rb +124 -0
  21. data/lib/ups/data.rb +50 -0
  22. data/lib/ups/data/canadian_states.rb +21 -0
  23. data/lib/ups/data/ie_counties.rb +10 -0
  24. data/lib/ups/data/ie_county_prefixes.rb +15 -0
  25. data/lib/ups/data/us_states.rb +59 -0
  26. data/lib/ups/exceptions.rb +7 -0
  27. data/lib/ups/packaging.rb +27 -0
  28. data/lib/ups/parsers/parser_base.rb +48 -0
  29. data/lib/ups/parsers/rates_parser.rb +60 -0
  30. data/lib/ups/parsers/ship_accept_parser.rb +52 -0
  31. data/lib/ups/parsers/ship_confirm_parser.rb +16 -0
  32. data/lib/ups/services.rb +21 -0
  33. data/lib/ups/version.rb +10 -0
  34. data/spec/spec_helper.rb +18 -0
  35. data/spec/stubs/rates_negotiated_success.xml +227 -0
  36. data/spec/stubs/rates_success.xml +196 -0
  37. data/spec/stubs/ship_accept_failure.xml +12 -0
  38. data/spec/stubs/ship_accept_success.xml +56 -0
  39. data/spec/stubs/ship_confirm_failure.xml +12 -0
  40. data/spec/stubs/ship_confirm_success.xml +50 -0
  41. data/spec/support/RateRequest.xsd +1 -0
  42. data/spec/support/ShipAcceptRequest.xsd +36 -0
  43. data/spec/support/ShipConfirmRequest.xsd +996 -0
  44. data/spec/support/schema_path.rb +5 -0
  45. data/spec/support/shipping_options.rb +48 -0
  46. data/spec/support/xsd_validator.rb +11 -0
  47. data/spec/ups/builders/address_builder_spec.rb +97 -0
  48. data/spec/ups/builders/rate_builder_spec.rb +20 -0
  49. data/spec/ups/builders/ship_accept_builder_spec.rb +16 -0
  50. data/spec/ups/builders/ship_confirm_builder_spec.rb +23 -0
  51. data/spec/ups/connection/rates_negotiated_spec.rb +69 -0
  52. data/spec/ups/connection/rates_standard_spec.rb +71 -0
  53. data/spec/ups/connection/ship_spec.rb +111 -0
  54. data/spec/ups/connection_spec.rb +20 -0
  55. data/ups.gemspec +24 -0
  56. metadata +166 -0
@@ -0,0 +1,5 @@
1
+ module SchemaPath
2
+ def schema_path(schema)
3
+ File.expand_path(File.join('spec', 'support', schema))
4
+ end
5
+ end
@@ -0,0 +1,48 @@
1
+ module ShippingOptions
2
+ def shipper
3
+ {
4
+ company_name: 'Veeqo Limited',
5
+ attention_name: 'Walter White',
6
+ phone_number: '01792 123456',
7
+ address_line_1: '11 Wind Street',
8
+ city: 'Swansea',
9
+ state: 'Wales',
10
+ postal_code: 'SA1 1DA',
11
+ country: 'GB',
12
+ shipper_number: ENV['UPS_ACCOUNT_NUMBER']
13
+ }
14
+ end
15
+
16
+ def ship_to
17
+ {
18
+ company_name: 'Google Inc.',
19
+ attention_name: 'Sergie Bryn',
20
+ phone_number: '0207 031 3000',
21
+ address_line_1: '1 St Giles High Street',
22
+ city: 'London',
23
+ state: 'England',
24
+ postal_code: 'WC2H 8AG',
25
+ country: 'GB'
26
+ }
27
+ end
28
+
29
+ def package
30
+ {
31
+ weight: '0.5',
32
+ unit: 'KGS',
33
+ dimensions: {
34
+ length: 40.0,
35
+ width: 30.0,
36
+ height: 20.0,
37
+ unit: 'CM'
38
+ }
39
+ }
40
+ end
41
+
42
+ def reference_number
43
+ {
44
+ code: 'IK',
45
+ value: '1234567890'
46
+ }
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ require 'minitest/assertions'
2
+
3
+ module Minitest::Assertions
4
+ def assert_passes_validation(schema_path, xml_to_validate)
5
+ schema = Nokogiri::XML::Schema(File.read(schema_path))
6
+ document = Nokogiri::XML::Document.parse(xml_to_validate)
7
+ schema.validate(document)
8
+ end
9
+ end
10
+
11
+ String.infect_an_assertion :assert_passes_validation, :must_pass_validation
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+
3
+ describe UPS::Builders::AddressBuilder do
4
+ describe "when passed a US Address" do
5
+ let(:address_hash) { {
6
+ address_line_1: 'Googleplex',
7
+ address_line_2: '1600 Amphitheatre Parkway',
8
+ city: 'Mountain View',
9
+ state: 'California',
10
+ postal_code: '94043',
11
+ country: 'US',
12
+ } }
13
+
14
+ describe "with a non-abbreviated state" do
15
+ subject { UPS::Builders::AddressBuilder.new address_hash }
16
+
17
+ it "should change the state to be the abbreviated state name" do
18
+ subject.opts[:state].must_equal 'CA'
19
+ end
20
+ end
21
+
22
+ describe "with a non-abbreviated state with mixed casing" do
23
+ subject { UPS::Builders::AddressBuilder.new address_hash.merge({ state: 'CaLiFoRnIa' }) }
24
+
25
+ it "should change the state to be the abbreviated state name" do
26
+ subject.opts[:state].must_equal 'CA'
27
+ end
28
+ end
29
+
30
+ describe "with an abbreviated state" do
31
+ subject { UPS::Builders::AddressBuilder.new address_hash.merge({ state: 'ca' }) }
32
+
33
+ it "should retrun the abbreviated state" do
34
+ subject.opts[:state].must_equal 'CA'
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "when passed a Canadian Address" do
40
+ let(:address_hash) { {
41
+ address_line_1: '1253 McGill College',
42
+ city: 'Montreal',
43
+ state: 'Quebec',
44
+ postal_code: 'H3B 2Y5',
45
+ country: 'CA',
46
+ } }
47
+
48
+ describe "with a non-abbreviated state" do
49
+ subject { UPS::Builders::AddressBuilder.new address_hash }
50
+
51
+ it "should change the state to be the abbreviated state name" do
52
+ subject.opts[:state].must_equal 'QC'
53
+ end
54
+ end
55
+
56
+ describe "with a non-abbreviated state with mixed casing" do
57
+ subject { UPS::Builders::AddressBuilder.new address_hash.merge({ state: 'QuEbEc' }) }
58
+
59
+ it "should change the state to be the abbreviated state name" do
60
+ subject.opts[:state].must_equal 'QC'
61
+ end
62
+ end
63
+
64
+ describe "with an abbreviated state" do
65
+ subject { UPS::Builders::AddressBuilder.new address_hash.merge({ state: 'qc' }) }
66
+
67
+ it "should retrun the abbreviated state" do
68
+ subject.opts[:state].must_equal 'QC'
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "when passed a IE address" do
74
+ let(:address_hash) { {
75
+ address_line_1: 'Barrow Street',
76
+ city: 'Dublin 4',
77
+ state: 'County Dublin',
78
+ postal_code: '',
79
+ country: 'IE',
80
+ } }
81
+
82
+ describe "normalizes the state field" do
83
+ subject { UPS::Builders::AddressBuilder.new address_hash }
84
+
85
+ it "should change the state to be the abbreviated state name" do
86
+ subject.opts[:state].must_equal 'Dublin'
87
+ end
88
+ end
89
+
90
+ describe "when passed a empty state" do
91
+ subject { UPS::Builders::AddressBuilder.new address_hash.merge({ state: '' }) }
92
+ it "should throw an exception" do
93
+ proc { subject }.must_raise UPS::Exceptions::InvalidAttributeError
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ class UPS::Builders::TestRateBuilder < Minitest::Test
4
+ include SchemaPath
5
+ include ShippingOptions
6
+
7
+ def setup
8
+ @rate_builder = UPS::Builders::RateBuilder.new do |builder|
9
+ builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
10
+ builder.add_shipper shipper
11
+ builder.add_ship_to ship_to
12
+ builder.add_ship_from shipper
13
+ builder.add_package package
14
+ end
15
+ end
16
+
17
+ def test_validates_against_xsd
18
+ assert_passes_validation schema_path('RateRequest.xsd'), @rate_builder.to_xml
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ class UPS::Builders::TestShipAcceptBuilder < Minitest::Test
4
+ include SchemaPath
5
+
6
+ def setup
7
+ @ship_accept_builder = UPS::Builders::ShipAcceptBuilder.new do |builder|
8
+ builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
9
+ builder.add_shipment_digest "rO0ABXNy...HB4cA=="
10
+ end
11
+ end
12
+
13
+ def test_validates_against_xsd
14
+ assert_passes_validation schema_path('ShipAcceptRequest.xsd'), @ship_accept_builder.to_xml
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ class UPS::Builders::TestShipConfirmBuilder < Minitest::Test
4
+ include SchemaPath
5
+ include ShippingOptions
6
+
7
+ def setup
8
+ @ship_confirm_builder = UPS::Builders::ShipConfirmBuilder.new do |builder|
9
+ builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
10
+ builder.add_shipper shipper
11
+ builder.add_ship_to ship_to
12
+ builder.add_ship_from shipper
13
+ builder.add_package package
14
+ builder.add_label_specification 'gif', { height: '100', width: '100' }
15
+ builder.add_description 'Los Pollo Hermanos'
16
+ builder.add_reference_number reference_number
17
+ end
18
+ end
19
+
20
+ def test_validates_against_xsd
21
+ assert_passes_validation schema_path('ShipConfirmRequest.xsd'), @ship_confirm_builder.to_xml
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe UPS::Connection do
4
+ include ShippingOptions
5
+
6
+ before do
7
+ Excon.defaults[:mock] = true
8
+ end
9
+
10
+ after do
11
+ Excon.stubs.clear
12
+ end
13
+
14
+ let(:stub_path) { File.expand_path("../../../stubs", __FILE__) }
15
+ let(:server) { UPS::Connection.new(test_mode: true) }
16
+
17
+ describe "if requesting rates" do
18
+ before do
19
+ Excon.stub({:method => :post}) do |params|
20
+ case params[:path]
21
+ when UPS::Connection::RATE_PATH
22
+ {body: File.read("#{stub_path}/rates_negotiated_success.xml"), status: 200}
23
+ end
24
+ end
25
+ end
26
+
27
+ subject do
28
+ server.rates do |rate_builder|
29
+ rate_builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
30
+ rate_builder.add_shipper shipper
31
+ rate_builder.add_ship_from shipper
32
+ rate_builder.add_ship_to ship_to
33
+ rate_builder.add_package package
34
+ rate_builder.add_rate_information
35
+ end
36
+ end
37
+
38
+ it "should return neotiated rates" do
39
+ expect(subject.rated_shipments).wont_be_empty
40
+ expect(subject.rated_shipments).must_equal [
41
+ {
42
+ :service_code=>"11",
43
+ :service_name=>"UPS Standard",
44
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
45
+ :total=>"24.78"
46
+
47
+ },
48
+ {
49
+ :service_code=>"65",
50
+ :service_name=>"UPS Saver",
51
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
52
+ :total=>"45.15"
53
+ },
54
+ {
55
+ :service_code=>"54",
56
+ :service_name=>"Express Plus",
57
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
58
+ :total=>"80.89"
59
+ },
60
+ {
61
+ :service_code=>"07",
62
+ :service_name=>"Express",
63
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
64
+ :total=>"47.08"
65
+ }
66
+ ]
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'support/shipping_options'
3
+
4
+ describe UPS::Connection do
5
+ include ShippingOptions
6
+
7
+ before do
8
+ Excon.defaults[:mock] = true
9
+ end
10
+
11
+ after do
12
+ Excon.stubs.clear
13
+ end
14
+
15
+ let(:stub_path) { File.expand_path("../../../stubs", __FILE__) }
16
+ let(:server) { UPS::Connection.new(test_mode: true) }
17
+
18
+ describe "if requesting rates" do
19
+ before do
20
+ Excon.stub({:method => :post}) do |params|
21
+ case params[:path]
22
+ when UPS::Connection::RATE_PATH
23
+ {body: File.read("#{stub_path}/rates_success.xml"), status: 200}
24
+ end
25
+ end
26
+ end
27
+
28
+ subject do
29
+ server.rates do |rate_builder|
30
+ rate_builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
31
+ rate_builder.add_shipper shipper
32
+ rate_builder.add_ship_from shipper
33
+ rate_builder.add_ship_to ship_to
34
+ rate_builder.add_package package
35
+ end
36
+ end
37
+
38
+ it "should return standard rates" do
39
+ expect(subject.rated_shipments).wont_be_empty
40
+ expect(subject.rated_shipments).must_equal [
41
+ {
42
+ :service_code=>"11",
43
+ :service_name=>"UPS Standard",
44
+ :warnings=>[
45
+ "Your invoice may vary from the displayed reference rates",
46
+ "Ship To Address Classification is changed from Commercial to Residential"
47
+ ],
48
+ :total=>"25.03"
49
+ },
50
+ {
51
+ :service_code=>"65",
52
+ :service_name=>"UPS Saver",
53
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
54
+ :total=>"45.82"
55
+ },
56
+ {
57
+ :service_code=>"54",
58
+ :service_name=>"Express Plus",
59
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
60
+ :total=>"82.08"
61
+ },
62
+ {
63
+ :service_code=>"07",
64
+ :service_name=>"Express",
65
+ :warnings=>["Your invoice may vary from the displayed reference rates"],
66
+ :total=>"47.77"
67
+ }
68
+ ]
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+ require 'support/shipping_options'
4
+
5
+ describe UPS::Connection do
6
+ include ShippingOptions
7
+
8
+ before do
9
+ Excon.defaults[:mock] = true
10
+ end
11
+
12
+ after do
13
+ Excon.stubs.clear
14
+ end
15
+
16
+ let(:stub_path) { File.expand_path("../../../stubs", __FILE__) }
17
+ let(:server) { UPS::Connection.new(test_mode: true) }
18
+
19
+ describe "if requesting a shipment" do
20
+ before do
21
+ Excon.stub({:method => :post}) do |params|
22
+ case params[:path]
23
+ when UPS::Connection::SHIP_CONFIRM_PATH
24
+ {body: File.read("#{stub_path}/ship_confirm_success.xml"), status: 200}
25
+ when UPS::Connection::SHIP_ACCEPT_PATH
26
+ {body: File.read("#{stub_path}/ship_accept_success.xml"), status: 200}
27
+ end
28
+ end
29
+ end
30
+
31
+ subject do
32
+ server.ship do |shipment_builder|
33
+ shipment_builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
34
+ shipment_builder.add_shipper shipper
35
+ shipment_builder.add_ship_from shipper
36
+ shipment_builder.add_ship_to ship_to
37
+ shipment_builder.add_package package
38
+ shipment_builder.add_payment_information ENV['UPS_ACCOUNT_NUMBER']
39
+ shipment_builder.add_service '07'
40
+ end
41
+ end
42
+
43
+ it "should do what ever it takes to get that shipment shipped!" do
44
+ subject.wont_equal false
45
+ subject.success?.must_equal true
46
+ subject.graphic_image.must_be_kind_of File
47
+ subject.html_image.must_be_kind_of File
48
+ subject.tracking_number.must_equal '1Z2220060292353829'
49
+ end
50
+ end
51
+
52
+ describe "ups returns an error during ship confirm" do
53
+ before do
54
+ Excon.stub({:method => :post}) do |params|
55
+ case params[:path]
56
+ when UPS::Connection::SHIP_CONFIRM_PATH
57
+ {body: File.read("#{stub_path}/ship_confirm_failure.xml"), status: 200}
58
+ end
59
+ end
60
+ end
61
+
62
+ subject do
63
+ server.ship do |shipment_builder|
64
+ shipment_builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
65
+ shipment_builder.add_shipper shipper
66
+ shipment_builder.add_ship_from shipper
67
+ shipment_builder.add_ship_to ship_to
68
+ shipment_builder.add_package package
69
+ shipment_builder.add_payment_information ENV['UPS_ACCOUNT_NUMBER']
70
+ shipment_builder.add_service '07'
71
+ end
72
+ end
73
+
74
+ it "should return a Parsed response with an error code and error description" do
75
+ subject.wont_equal false
76
+ subject.success?.must_equal false
77
+ subject.error_description.must_equal "Missing or invalid shipper number"
78
+ end
79
+ end
80
+
81
+ describe "ups returns an error during ship accept" do
82
+ before do
83
+ Excon.stub({:method => :post}) do |params|
84
+ case params[:path]
85
+ when UPS::Connection::SHIP_CONFIRM_PATH
86
+ {body: File.read("#{stub_path}/ship_confirm_success.xml"), status: 200}
87
+ when UPS::Connection::SHIP_ACCEPT_PATH
88
+ {body: File.read("#{stub_path}/ship_accept_failure.xml"), status: 200}
89
+ end
90
+ end
91
+ end
92
+
93
+ subject do
94
+ server.ship do |shipment_builder|
95
+ shipment_builder.add_access_request ENV['UPS_LICENSE_NUMBER'], ENV['UPS_USER_ID'], ENV['UPS_PASSWORD']
96
+ shipment_builder.add_shipper shipper
97
+ shipment_builder.add_ship_from shipper
98
+ shipment_builder.add_ship_to ship_to
99
+ shipment_builder.add_package package
100
+ shipment_builder.add_payment_information ENV['UPS_ACCOUNT_NUMBER']
101
+ shipment_builder.add_service '07'
102
+ end
103
+ end
104
+
105
+ it "should return a Parsed response with an error code and error description" do
106
+ subject.wont_equal false
107
+ subject.success?.must_equal false
108
+ subject.error_description.must_equal "Missing or invalid shipper number"
109
+ end
110
+ end
111
+ end