trackerific 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/Gemfile.lock +43 -1
  4. data/README.rdoc +58 -60
  5. data/lib/trackerific.rb +17 -20
  6. data/lib/trackerific/builders/base/soap.rb +21 -0
  7. data/lib/trackerific/builders/base/xml.rb +38 -0
  8. data/lib/trackerific/builders/fedex.rb +46 -0
  9. data/lib/trackerific/builders/ups.rb +32 -0
  10. data/lib/trackerific/builders/usps.rb +19 -0
  11. data/lib/trackerific/environment.rb +11 -0
  12. data/lib/trackerific/error.rb +3 -1
  13. data/lib/trackerific/parsers/base.rb +35 -0
  14. data/lib/trackerific/parsers/fedex.rb +59 -0
  15. data/lib/trackerific/parsers/ups.rb +66 -0
  16. data/lib/trackerific/parsers/usps.rb +51 -0
  17. data/lib/trackerific/services/base.rb +23 -10
  18. data/lib/trackerific/services/concerns/soap.rb +45 -0
  19. data/lib/trackerific/services/concerns/xml.rb +44 -0
  20. data/lib/trackerific/services/fedex.rb +9 -79
  21. data/lib/trackerific/services/mock_service.rb +4 -12
  22. data/lib/trackerific/services/ups.rb +11 -95
  23. data/lib/trackerific/services/usps.rb +21 -181
  24. data/lib/trackerific/soap/wsdl.rb +17 -0
  25. data/lib/trackerific/version.rb +1 -1
  26. data/spec/fixtures/fedex/error.xml +1 -10
  27. data/spec/fixtures/fedex/success.xml +1 -74
  28. data/spec/fixtures/ups/malformed.xml +10 -0
  29. data/spec/fixtures/ups/request.xml +1 -0
  30. data/spec/fixtures/usps/malformed.xml +2 -0
  31. data/spec/fixtures/usps/request.xml +1 -0
  32. data/spec/lib/trackerific/builders/base/soap_spec.rb +29 -0
  33. data/spec/lib/trackerific/builders/base/xml_spec.rb +35 -0
  34. data/spec/lib/trackerific/builders/fedex_spec.rb +70 -0
  35. data/spec/lib/trackerific/builders/ups_spec.rb +11 -0
  36. data/spec/lib/trackerific/builders/usps_spec.rb +11 -0
  37. data/spec/lib/trackerific/environment_spec.rb +45 -0
  38. data/spec/lib/trackerific/parsers/base_spec.rb +62 -0
  39. data/spec/lib/trackerific/parsers/ups_spec.rb +71 -0
  40. data/spec/lib/trackerific/parsers/usps_spec.rb +77 -0
  41. data/spec/lib/trackerific/services/base_spec.rb +56 -0
  42. data/spec/lib/trackerific/services/concerns/soap_spec.rb +71 -0
  43. data/spec/lib/trackerific/services/concerns/xml_spec.rb +65 -0
  44. data/spec/lib/trackerific/services/fedex_spec.rb +43 -45
  45. data/spec/lib/trackerific/services/ups_spec.rb +23 -2
  46. data/spec/lib/trackerific/services/usps_spec.rb +44 -34
  47. data/spec/lib/trackerific/services_spec.rb +7 -0
  48. data/spec/lib/trackerific/soap/wsdl_spec.rb +29 -0
  49. data/spec/lib/trackerific/version_spec.rb +1 -1
  50. data/spec/lib/trackerific_spec.rb +2 -11
  51. data/spec/spec_helper.rb +17 -1
  52. data/spec/support/reload.rb +6 -0
  53. data/spec/support/trackerific.rb +7 -0
  54. data/trackerific.gemspec +2 -0
  55. data/vendor/wsdl/fedex/TrackService_v8.wsdl +2284 -0
  56. metadata +81 -7
  57. data/lib/trackerific/configuration.rb +0 -7
  58. data/spec/fixtures/usps/city_state_lookup.xml +0 -8
  59. data/spec/lib/trackerific/configuration_spec.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6ebc05677cc3553211222baad840e0a77f75e0d
4
- data.tar.gz: e2f65f8425c2e70a7a6b56c71946b1174337dc5d
3
+ metadata.gz: 1310f1dbf143518a58178390a664b23b697cadba
4
+ data.tar.gz: 709ab9cdaa8df43975eff61b797b98586fab4e34
5
5
  SHA512:
6
- metadata.gz: a789ef97d405deac2bfdfa850cd7a39719a7f6ac64f1e16297098f1e48ed18385bedda51154acdc7a44e3ac6ca4093a3acf543d8d426a062861142d14748cae2
7
- data.tar.gz: 532c75fddf2c6b8e4c34abe4822edf52ac41b1e70952cc0cfda368d7ad5869ff32e416a83a2a2ae8a6b31abb9abf09cb342012c6ea3ef73c3e73c6f3c8837485
6
+ metadata.gz: b398a2bfaab2602d8cb0624d48f7936750abb13bdfb36828a27cd4ec1f4b0a5a0763996de30edf2aa38a4270fecb31e5158a77a2d242542a3c3be6d1094b0158
7
+ data.tar.gz: dfe45ddfe2c76098a2e9b6c917f6b825fb91d993f92236f9b5b28595f539b48b13d758bae1dbe1fd6ede6928ea202b95638d010ac0cf6e5b06ef81e930781ded
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trackerific (0.7.1)
4
+ trackerific (0.7.2)
5
5
  activesupport
6
6
  builder (>= 3.1.4)
7
7
  httparty (>= 0.12.0)
8
+ savon (~> 2.3.0)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -15,19 +16,39 @@ GEM
15
16
  multi_json (~> 1.3)
16
17
  thread_safe (~> 0.1)
17
18
  tzinfo (~> 0.3.37)
19
+ akami (1.2.0)
20
+ gyoku (>= 0.4.0)
21
+ nokogiri (>= 1.4.0)
18
22
  atomic (1.1.14)
19
23
  builder (3.2.2)
24
+ coveralls (0.7.0)
25
+ multi_json (~> 1.3)
26
+ rest-client
27
+ simplecov (>= 0.7)
28
+ term-ansicolor
29
+ thor
20
30
  diff-lcs (1.1.3)
21
31
  fakeweb (1.3.0)
32
+ gyoku (1.1.0)
33
+ builder (>= 2.1.2)
22
34
  httparty (0.12.0)
23
35
  json (~> 1.8)
24
36
  multi_xml (>= 0.5.2)
37
+ httpi (2.1.0)
38
+ rack
39
+ rubyntlm (~> 0.3.2)
25
40
  i18n (0.6.5)
26
41
  json (1.8.0)
42
+ mime-types (1.25)
27
43
  minitest (4.7.5)
28
44
  multi_json (1.8.2)
29
45
  multi_xml (0.5.5)
46
+ nokogiri (1.5.10)
47
+ nori (2.3.0)
48
+ rack (1.5.2)
30
49
  rake (10.1.0)
50
+ rest-client (1.6.7)
51
+ mime-types (>= 1.16)
31
52
  rspec (2.6.0)
32
53
  rspec-core (~> 2.6.0)
33
54
  rspec-expectations (~> 2.6.0)
@@ -36,15 +57,36 @@ GEM
36
57
  rspec-expectations (2.6.0)
37
58
  diff-lcs (~> 1.1.2)
38
59
  rspec-mocks (2.6.0)
60
+ rubyntlm (0.3.4)
61
+ savon (2.3.0)
62
+ akami (~> 1.2.0)
63
+ builder (>= 2.1.2)
64
+ gyoku (~> 1.1.0)
65
+ httpi (~> 2.1.0)
66
+ nokogiri (>= 1.4.0, < 1.6)
67
+ nori (~> 2.3.0)
68
+ wasabi (~> 3.2.0)
69
+ simplecov (0.7.1)
70
+ multi_json (~> 1.0)
71
+ simplecov-html (~> 0.7.1)
72
+ simplecov-html (0.7.1)
73
+ term-ansicolor (1.2.2)
74
+ tins (~> 0.8)
75
+ thor (0.18.1)
39
76
  thread_safe (0.1.3)
40
77
  atomic
78
+ tins (0.12.0)
41
79
  tzinfo (0.3.38)
80
+ wasabi (3.2.0)
81
+ httpi (~> 2.0)
82
+ nokogiri (>= 1.4.0, < 1.6)
42
83
 
43
84
  PLATFORMS
44
85
  ruby
45
86
 
46
87
  DEPENDENCIES
47
88
  bundler (>= 1.3.5)
89
+ coveralls (~> 0.7.0)
48
90
  fakeweb (~> 1.3.0)
49
91
  rake
50
92
  rspec (~> 2.6.0)
data/README.rdoc CHANGED
@@ -1,3 +1,25 @@
1
+ = Trackerific {<img src="https://badge.fury.io/rb/trackerific.png" alt="Gem Version" />}[http://badge.fury.io/rb/trackerific] {<img src="https://travis-ci.org/travishaynes/trackerific.png" />}[https://travis-ci.org/travishaynes/trackerific] {<img src="https://coveralls.io/repos/travishaynes/trackerific/badge.png" alt="Coverage Status" />}[https://coveralls.io/r/travishaynes/trackerific]
2
+
3
+ Package tracking in a gem. Currently supported carriers are:
4
+
5
+ * FedEx
6
+ * UPS
7
+ * USPS
8
+
9
+ == Prerequisites
10
+
11
+ You will need to sign up to each carrier you wish to utilize. They each have
12
+ their own requirements and license agreements, so it's up to you to make sure
13
+ you follow their terms of agreement. For example, at the time this was written
14
+ UPS requires that you include their logo on your website when you use their
15
+ API.
16
+
17
+ You'll also need the proper credentials from each carrier, which requires
18
+ signing up through their individual websites, and is not always free, depending
19
+ on which portion of their API you plan on using. Trackerific focuses primarily
20
+ on the tracking APIs, so that's all you'll need to use this gem, unless you
21
+ plan on implementing additional features.
22
+
1
23
  == Installation
2
24
 
3
25
  To use this gem, add this line to your Gemfile
@@ -7,24 +29,15 @@ and then run
7
29
 
8
30
  === Configuration
9
31
 
10
- You will need to configure your credentials for each service:
32
+ You will need to configure the credentials for each service you're utilizing.
33
+ Services without credentials will not be accessed by the gem.
11
34
 
12
35
  Trackerific.configure do |config|
13
- config.fedex :account => 'account',
14
- :meter => '123456789'
15
-
16
- config.ups :key => 'key',
17
- :user_id => 'userid',
18
- :password => 'secret'
19
-
20
- config.usps :user_id => 'userid',
21
- :use_city_state_lookup => true
36
+ config.fedex = { account: 'account', meter: '123456789' }
37
+ config.ups = { key: 'key', user_id: 'userid', password: 'secret' }
38
+ config.usps = { user_id: 'userid' }
22
39
  end
23
40
 
24
- For USPS packages, the option :use_city_state_lookup defaults to false, and will
25
- only work if you have access to USPS's CityStateLookup API. If you can enable
26
- it, this feature will provide the location for USPS package events.
27
-
28
41
  === Tracking with Automatic Service Discovery
29
42
 
30
43
  Once you configured the services, tracking a package is as easy as
@@ -36,64 +49,47 @@ Once you configured the services, tracking a package is as easy as
36
49
  If you do not know the tracking service provider of a package id you can use
37
50
  Trackerific::Services.find_by_tracking_id:
38
51
 
39
- Trackerific::Services.find_by_tracking_id("183689015000001") # => Trackerific::Services::FedEx
40
- Trackerific::Services.find_by_tracking_id("1Z12345E0291980793") # => Trackerific::Services::UPS
41
- Trackerific::Services.find_by_tracking_id("EJ958083578US") # => Trackerific::Services::USPS
42
- Trackerific::Services.find_by_tracking_id("unknown package id") # => nil
52
+ Trackerific::Services.find_by_tracking_id("123456789012")
53
+ Trackerific::Services.find_by_tracking_id("1Z12345E0291980793")
54
+ Trackerific::Services.find_by_tracking_id("EJ958083578US")
55
+
56
+ Each of the above examples will return an Array of
57
+ Trackerific::Service::Base subclasses that are capable of tracking the given
58
+ package ID.
43
59
 
44
60
  === Tracking a Package with a Specific Service
45
61
 
46
62
  Use this method if you need to specify exactly which service to track a package.
47
63
 
48
- # Track a FedEx package:
49
- details = Trackerific::Services::FedEx.track('183689015000001')
50
-
51
- # Track a USPS package:
52
- details = Trackerific::Services::USPS.track('EJ958083578US')
64
+ details = Trackerific::Services::FedEx.track('123456789012')
53
65
 
54
- # Track a UPS package:
55
- details = Trackerific::Services::UPS.track('1Z12345E0291980793')
66
+ Using #track will automatically read the credentials from Trackerific.config.
67
+ If you need to assign them manually, use #new:
56
68
 
57
- Using #track will automatically read the credentials from
58
- `Trackerific.configuration`. If you need to assign them manually, use #new:
59
-
60
- fedex = Trackerific::Services::FedEx.new account: "account", meter: "123456789"
69
+ fedex = Trackerific::Services::FedEx.new(
70
+ :account => "account",
71
+ :meter => "123456789"
72
+ )
61
73
  details = fedex.track('183689015000001')
62
74
 
63
75
  === Tracking Details
64
76
 
65
77
  The tracking information is returned in a Trackerific::Details instance.
66
78
 
67
- details.summary # => a summary of the tracking events
68
- details.events # => an Array of Trackerific::Events
69
-
70
- You can easily print out the tracking events just by doing:
71
-
72
- puts details.events # for all the events
73
- puts details.events.first # for just one event
74
-
75
- Or, if you need specific information about an event:
76
-
77
- details.events.last.date # => the date the package was shipped
78
- details.events.first.date # => the last date the package was updated
79
- details.events.first.description # => a description of an event
80
- details.events.first.location # => the location of the package during that event
81
-
82
- location will not work for USPS packages, because USPS does not provide that
83
- information seperately from the description. So for USPS packages, the location
84
- will always be at the end of the description.
79
+ details.summary - Summary of the tracking events
80
+ details.events - Array of Trackerific::Events
85
81
 
86
- Note that events.last will return the first event the tracking provider
87
- supplied. This is because the events are listed in LIFO order, so the most
88
- recent events will always be at the top of the list.
82
+ === Tracking Events
89
83
 
90
- === City / State Lookup Via USPS
84
+ Tracking::Details has an events Array with the following properties:
91
85
 
92
- If you have access to the USPS CityStateLookup API, you can use Trackerific to
93
- look up the city and state of a zipcode.
86
+ event.date - The date the package was shipped.
87
+ event.date - The date/time of the event.
88
+ event.description - Description of an event.
89
+ event.location - The location of the package during that event.
94
90
 
95
- usps = Trackerific::Services::USPS.new :user_id => 'userid'
96
- usps.city_state_lookup "90210" # => { :city => 'BEVERLY HILLS', :state => 'CA', :zip => '90210' }
91
+ Note that events are in last-in-first-out order, so the last event will always
92
+ be the first event the carrier supplied.
97
93
 
98
94
  === Exception handling
99
95
 
@@ -115,13 +111,15 @@ Trackerific provides a mocked service you can use in your unit tests of your
115
111
  application. You must require the service manually.
116
112
 
117
113
  require 'trackerific/services/mock_service'
118
- details = track_package("XXXXXXXXXX") # => returns a populated Trackerific::Details
119
- details = track_package("XXXxxxxxxx") # => throws a Trackerific::Error exception
114
+ # Get a populated Trackerific::Details
115
+ details = Trackerific.track("XXXXXXXXXX")
116
+ # Throw a Trackerific::Error exception
117
+ details = Trackerific.track("XXXxxxxxxx")
120
118
 
121
119
  == Contributing
122
120
 
123
121
  1. Fork it
124
- 2. Create your feature branch (`git checkout -b my-new-feature`)
125
- 3. Commit your changes (`git commit -am 'Add some feature'`)
126
- 4. Push to the branch (`git push origin my-new-feature`)
122
+ 2. Create your feature branch (git checkout -b my-new-feature)
123
+ 3. Commit your changes (git commit -am 'Add some feature')
124
+ 4. Push to the branch (git push origin my-new-feature)
127
125
  5. Create new Pull Request
data/lib/trackerific.rb CHANGED
@@ -1,8 +1,21 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/object/to_query'
3
+ require 'securerandom'
4
+ require 'date'
5
+ require 'savon'
6
+ require 'httparty'
7
+ require 'builder'
1
8
  require 'trackerific/version'
2
- require 'trackerific/configuration'
9
+ require 'trackerific/environment'
3
10
  require 'trackerific/error'
4
11
  require 'trackerific/details'
5
12
  require 'trackerific/event'
13
+ require 'trackerific/soap/wsdl'
14
+ require 'trackerific/builders/base/soap'
15
+ require 'trackerific/builders/base/xml'
16
+ require 'trackerific/parsers/base'
17
+ require 'trackerific/services/concerns/soap'
18
+ require 'trackerific/services/concerns/xml'
6
19
  require 'trackerific/services'
7
20
  require 'trackerific/services/base'
8
21
 
@@ -12,32 +25,16 @@ require 'trackerific/services/ups'
12
25
  require 'trackerific/services/usps'
13
26
 
14
27
  module Trackerific
15
- class << self
16
- # Used to access the Trackerific service credentials
17
- # @api public
18
- def configuration
19
- Trackerific::Configuration.config
20
- end
21
-
22
- # Use to configure Trackerific service credentials
23
- # @example Configure FedEx credentials
24
- # Trackerific.configure do |config|
25
- # config.fedex account: 'account', meter: '123456789'
26
- # end
27
- # @api public
28
- def configure(&block)
29
- Trackerific::Configuration.configure {|config| yield(config) }
30
- end
28
+ include ActiveSupport::Configurable
31
29
 
30
+ class << self
32
31
  # Looks up which service(s) can track the given ID and tracks it.
33
32
  # @param [String] id The package identifier
34
33
  # @return [Array, Trackerific::Details] The tracking results
35
34
  # @raise [Trackerific::Error] Raised when the server returns an error
36
35
  # @api public
37
36
  def track(id)
38
- Trackerific::Services.find_by_package_id(id).map do |service|
39
- service.new.track(id)
40
- end
37
+ Trackerific::Services.find_by_package_id(id).map {|s| s.track(id) }
41
38
  end
42
39
  end
43
40
  end
@@ -0,0 +1,21 @@
1
+ module Trackerific
2
+ module Builders
3
+ module Base
4
+ class SOAP < Struct
5
+ attr_reader :hash
6
+
7
+ def initialize(*args)
8
+ super(*args)
9
+ @hash = build
10
+ end
11
+
12
+ protected
13
+
14
+ def build
15
+ raise NotImplementedError,
16
+ "Implement this method in your builder subclass", caller
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ module Trackerific
2
+ module Builders
3
+ module Base
4
+ class XML < Struct
5
+ @xml_version = "1.0"
6
+
7
+ class << self
8
+ attr_accessor :xml_version
9
+ end
10
+
11
+ attr_reader :xml
12
+
13
+ def initialize(*args)
14
+ super(*args)
15
+ @xml = ""
16
+ build
17
+ end
18
+
19
+ protected
20
+
21
+ def build
22
+ raise NotImplementedError,
23
+ "Implement this method in your builder subclass", caller
24
+ end
25
+
26
+ private
27
+
28
+ def builder
29
+ @builder ||= begin
30
+ builder = Builder::XmlMarkup.new(target: @xml)
31
+ builder.instruct! :xml, version: self.class.xml_version
32
+ builder
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ module Trackerific
2
+ module Builders
3
+ class FedEx < Base::SOAP.new(:key, :password, :account_number, :meter_number, :package_id)
4
+ protected
5
+
6
+ def build
7
+ root_elements.inject({}) {|r, k| r[k] = send(k); r }
8
+ end
9
+
10
+ private
11
+
12
+ def root_elements
13
+ [ :web_authentication_detail, :client_detail, :transaction_detail,
14
+ :version, :selection_details, :processing_options ]
15
+ end
16
+
17
+ def web_authentication_detail
18
+ { user_credential: { key: key, password: password } }
19
+ end
20
+
21
+ def client_detail
22
+ { account_number: account_number, meter_number: meter_number }
23
+ end
24
+
25
+ def transaction_detail
26
+ { customer_transaction_id: "Trackerific" }
27
+ end
28
+
29
+ def version
30
+ { service_id: 'trck', major: '8', intermediate: '0', minor: '0' }
31
+ end
32
+
33
+ def selection_details
34
+ { carrier_code: 'FDXE', package_identifier: package_identifier }
35
+ end
36
+
37
+ def package_identifier
38
+ { type: 'TRACKING_NUMBER_OR_DOORTAG', value: package_id }
39
+ end
40
+
41
+ def processing_options
42
+ 'INCLUDE_DETAILED_SCANS'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ module Trackerific
2
+ module Builders
3
+ class UPS < Base::XML.new(:key, :user_id, :password, :package_id)
4
+ protected
5
+
6
+ def build
7
+ add_access_request
8
+ add_track_request
9
+ end
10
+
11
+ private
12
+
13
+ def add_access_request
14
+ builder.AccessRequest do |ar|
15
+ ar.AccessLicenseNumber key
16
+ ar.UserId user_id
17
+ ar.Password password
18
+ end
19
+ end
20
+
21
+ def add_track_request
22
+ builder.TrackRequest do |tr|
23
+ tr.Request do |r|
24
+ r.RequestAction 'Track'
25
+ r.RequestOption 'activity'
26
+ end
27
+ tr.TrackingNumber package_id
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end