trackerific 0.6.2 → 0.7.0
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -2
- data/Gemfile +3 -22
- data/Gemfile.lock +33 -107
- data/README.rdoc +35 -61
- data/Rakefile +10 -36
- data/lib/trackerific/configuration.rb +3 -46
- data/lib/trackerific/details.rb +2 -71
- data/lib/trackerific/event.rb +5 -49
- data/lib/trackerific/services/base.rb +45 -0
- data/lib/trackerific/services/fedex.rb +75 -85
- data/lib/trackerific/services/mock_service.rb +43 -54
- data/lib/trackerific/services/ups.rb +94 -103
- data/lib/trackerific/services/usps.rb +182 -186
- data/lib/trackerific/services.rb +41 -0
- data/lib/trackerific/version.rb +3 -0
- data/lib/trackerific.rb +30 -73
- data/spec/fixtures/{fedex_error_response.xml → fedex/error.xml} +0 -0
- data/spec/fixtures/{fedex_success_response.xml → fedex/success.xml} +0 -0
- data/spec/fixtures/{ups_error_response.xml → ups/error.xml} +0 -0
- data/spec/fixtures/{ups_success_response.xml → ups/success.xml} +0 -0
- data/spec/fixtures/{usps_city_state_lookup_response.xml → usps/city_state_lookup.xml} +0 -0
- data/spec/fixtures/{usps_error_response.xml → usps/error.xml} +0 -0
- data/spec/fixtures/{usps_success_response.xml → usps/success.xml} +0 -0
- data/spec/lib/trackerific/configuration_spec.rb +8 -39
- data/spec/lib/trackerific/details_spec.rb +13 -78
- data/spec/lib/trackerific/error_spec.rb +1 -5
- data/spec/lib/trackerific/event_spec.rb +14 -43
- data/spec/lib/trackerific/services/base_spec.rb +13 -0
- data/spec/lib/trackerific/services/fedex_spec.rb +59 -62
- data/spec/lib/trackerific/services/mock_service_spec.rb +33 -46
- data/spec/lib/trackerific/services/ups_spec.rb +46 -66
- data/spec/lib/trackerific/services/usps_spec.rb +80 -94
- data/spec/lib/trackerific/services_spec.rb +37 -0
- data/spec/lib/trackerific/version_spec.rb +5 -0
- data/spec/lib/trackerific_spec.rb +15 -53
- data/spec/spec_helper.rb +2 -9
- data/spec/support/fixtures.rb +4 -18
- data/spec/support/test_services.rb +23 -0
- data/trackerific.gemspec +24 -102
- metadata +151 -185
- data/VERSION +0 -1
- data/changelog +0 -9
- data/examples/custom_service_spec.rb +0 -44
- data/lib/helpers/options_helper.rb +0 -23
- data/lib/trackerific/service.rb +0 -100
- data/spec/lib/helpers/options_helper_spec.rb +0 -82
- data/spec/lib/trackerific/service_spec.rb +0 -44
- data/spec/support/trackerific.rb +0 -21
@@ -1,204 +1,200 @@
|
|
1
|
-
require 'date'
|
2
1
|
require 'active_support/core_ext/object/to_query'
|
2
|
+
require 'httparty'
|
3
|
+
require 'builder'
|
4
|
+
require 'date'
|
3
5
|
|
4
6
|
module Trackerific
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
module Services
|
8
|
+
# Provides package tracking support for USPS.
|
9
|
+
class USPS < Base
|
10
|
+
include HTTParty
|
11
|
+
format :xml
|
12
|
+
|
13
|
+
base_uri case (ENV['RAILS_ENV'] || 'production')
|
14
|
+
when 'production' then "http://production.shippingapis.com"
|
15
|
+
else "http://testing.shippingapis.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(options={})
|
19
|
+
@options = options
|
20
|
+
end
|
21
|
+
|
16
22
|
# An Array of Regexp that matches valid USPS package IDs
|
17
23
|
# @return [Array, Regexp] the regular expression
|
18
24
|
# @api private
|
19
|
-
def package_id_matchers
|
25
|
+
def self.package_id_matchers
|
20
26
|
[ /^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/ ]
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
# @
|
27
|
+
end
|
28
|
+
|
29
|
+
# Tracks a USPS package
|
30
|
+
# @param [String] package_id the package identifier
|
31
|
+
# @return [Trackerific::Details] the tracking details
|
32
|
+
# @raise [Trackerific::Error] raised when the server returns an error (invalid credentials, tracking package, etc.)
|
33
|
+
# @example Track a package
|
34
|
+
# usps = Trackerific::USPS.new user_id: 'user'
|
35
|
+
# details = ups.track_package("EJ958083578US")
|
36
|
+
# @api public
|
37
|
+
def track(id)
|
38
|
+
@package_id = id
|
39
|
+
# connect to the USPS shipping API via HTTParty
|
40
|
+
response = self.class.get(
|
41
|
+
env == 'production' ? "/ShippingAPI.dll" : "/ShippingAPITest.dll",
|
42
|
+
query: { :API => 'TrackV2', :XML => build_tracking_xml_request }.to_query
|
43
|
+
)
|
44
|
+
# raise any errors
|
45
|
+
error = check_response_for_errors(response, :TrackV2)
|
46
|
+
raise error unless error.nil?
|
47
|
+
# get the tracking information from the response
|
48
|
+
tracking_info = response['TrackResponse']['TrackInfo']
|
49
|
+
events = []
|
50
|
+
# parse the tracking events out of the USPS tracking info
|
51
|
+
tracking_info['TrackDetail'].each do |d|
|
52
|
+
events << Trackerific::Event.new(
|
53
|
+
date_of_event(d),
|
54
|
+
description_of_event(d),
|
55
|
+
location_of_event(d)
|
56
|
+
)
|
57
|
+
end unless tracking_info['TrackDetail'].nil?
|
58
|
+
# return the details
|
59
|
+
Trackerific::Details.new(
|
60
|
+
tracking_info['ID'],
|
61
|
+
tracking_info['TrackSummary'],
|
62
|
+
events
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Gets the city/state of a zipcode - requires access to USPS address APIs
|
67
|
+
# @param [String] zipcode The zipcode to find the city/state for
|
68
|
+
# @return [Hash] { zip: 'the zipcode, 'city: "the city", state: "the state" }
|
69
|
+
# @example Lookup zipcode for Beverly Hills, CA
|
70
|
+
# usps = Trackerific::USPS.new :user_id => 'youruserid'
|
71
|
+
# city_state = usps.city_state_lookup(90210)
|
72
|
+
# city_state[:city] # => BEVERLY HILLS
|
73
|
+
# city_state[:state] # => CA
|
74
|
+
# city_state[:zip] # => 90210
|
75
|
+
# @api public
|
76
|
+
def city_state_lookup(zipcode)
|
77
|
+
response = self.class.get(
|
78
|
+
env == 'production' ? "/ShippingAPI.dll" : "/ShippingAPITest.dll",
|
79
|
+
query: {
|
80
|
+
:API => 'CityStateLookup',
|
81
|
+
:XML => build_city_state_xml_request(zipcode)
|
82
|
+
}.to_query
|
83
|
+
)
|
84
|
+
# raise any errors
|
85
|
+
error = check_response_for_errors(response, :CityStateLookup)
|
86
|
+
raise error unless error.nil?
|
87
|
+
# return the city, state, and zip
|
88
|
+
response = response['CityStateLookupResponse']['ZipCode']
|
89
|
+
{
|
90
|
+
:city => response['City'],
|
91
|
+
:state => response['State'],
|
92
|
+
:zip => response['Zip5']
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def env
|
99
|
+
@rails_env ||= ENV['RAILS_ENV'] || 'production'
|
100
|
+
end
|
101
|
+
|
102
|
+
# Parses a USPS tracking event, and returns its date
|
103
|
+
# @param [String] event The tracking event to parse
|
104
|
+
# @return [DateTime] The date / time of the event
|
25
105
|
# @api private
|
26
|
-
def
|
27
|
-
|
106
|
+
def date_of_event(event)
|
107
|
+
# get the date out of
|
108
|
+
# Mon DD HH:MM am/pm THE DESCRIPTION CITY STATE ZIP.
|
109
|
+
d = event.split(" ")
|
110
|
+
DateTime.parse(d[0..3].join(" "))
|
28
111
|
end
|
29
|
-
|
30
|
-
#
|
31
|
-
# @
|
112
|
+
|
113
|
+
# Parses a USPS tracking event, and returns its description
|
114
|
+
# @param [String] event The tracking event to parse
|
115
|
+
# @return [DateTime] The description of the event
|
32
116
|
# @api private
|
33
|
-
def
|
34
|
-
|
117
|
+
def description_of_event(event)
|
118
|
+
# get the description out of
|
119
|
+
# Mon DD HH:MM am/pm THE DESCRIPTION CITY STATE ZIP.
|
120
|
+
d = event.split(" ")
|
121
|
+
d[4..d.length-4].join(" ").capitalize
|
35
122
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
tracking_info['TrackDetail'].each do |d|
|
61
|
-
events << Trackerific::Event.new(
|
62
|
-
:date => date_of_event(d),
|
63
|
-
:description => description_of_event(d).capitalize,
|
64
|
-
:location => location_of_event(d)
|
65
|
-
)
|
66
|
-
end unless tracking_info['TrackDetail'].nil?
|
67
|
-
# return the details
|
68
|
-
Trackerific::Details.new(
|
69
|
-
:package_id => tracking_info['ID'],
|
70
|
-
:summary => tracking_info['TrackSummary'],
|
71
|
-
:events => events
|
72
|
-
)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Gets the city/state of a zipcode - requires access to USPS address APIs
|
76
|
-
# @param [String] zipcode The zipcode to find the city/state for
|
77
|
-
# @return [Hash] { zip: 'the zipcode, 'city: "the city", state: "the state" }
|
78
|
-
# @example Lookup zipcode for Beverly Hills, CA
|
79
|
-
# usps = Trackerific::USPS.new :user_id => 'youruserid'
|
80
|
-
# city_state = usps.city_state_lookup(90210)
|
81
|
-
# city_state[:city] # => BEVERLY HILLS
|
82
|
-
# city_state[:state] # => CA
|
83
|
-
# city_state[:zip] # => 90210
|
84
|
-
# @api public
|
85
|
-
def city_state_lookup(zipcode)
|
86
|
-
response = self.class.get(
|
87
|
-
Rails.env.production? ? "/ShippingAPI.dll" : "/ShippingAPITest.dll",
|
88
|
-
:query => {
|
89
|
-
:API => 'CityStateLookup',
|
90
|
-
:XML => build_city_state_xml_request(zipcode)
|
91
|
-
}.to_query
|
92
|
-
)
|
93
|
-
# raise any errors
|
94
|
-
error = check_response_for_errors(response, :CityStateLookup)
|
95
|
-
raise error unless error.nil?
|
96
|
-
# return the city, state, and zip
|
97
|
-
response = response['CityStateLookupResponse']['ZipCode']
|
98
|
-
{
|
99
|
-
:city => response['City'],
|
100
|
-
:state => response['State'],
|
101
|
-
:zip => response['Zip5']
|
102
|
-
}
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
|
107
|
-
# Parses a USPS tracking event, and returns its date
|
108
|
-
# @param [String] event The tracking event to parse
|
109
|
-
# @return [DateTime] The date / time of the event
|
110
|
-
# @api private
|
111
|
-
def date_of_event(event)
|
112
|
-
# get the date out of
|
113
|
-
# Mon DD HH:MM am/pm THE DESCRIPTION CITY STATE ZIP.
|
114
|
-
d = event.split(" ")
|
115
|
-
DateTime.parse(d[0..3].join(" "))
|
116
|
-
end
|
117
|
-
|
118
|
-
# Parses a USPS tracking event, and returns its description
|
119
|
-
# @param [String] event The tracking event to parse
|
120
|
-
# @return [DateTime] The description of the event
|
121
|
-
# @api private
|
122
|
-
def description_of_event(event)
|
123
|
-
# get the description out of
|
124
|
-
# Mon DD HH:MM am/pm THE DESCRIPTION CITY STATE ZIP.
|
125
|
-
d = event.split(" ")
|
126
|
-
d[4..d.length-4].join(" ").capitalize
|
127
|
-
end
|
128
|
-
|
129
|
-
# Parses a USPS tracking event, and returns its location
|
130
|
-
# @param [String] event The tracking event to parse
|
131
|
-
# @return The location of the event
|
132
|
-
# @api private
|
133
|
-
def location_of_event(event)
|
134
|
-
# remove periods, and split by spaces
|
135
|
-
d = event.gsub(".", "").split(" ")
|
136
|
-
l = d[d.length-3, d.length] # => ['city', 'state', 'zip']
|
137
|
-
# this is the location from the USPS tracking XML. it is not guaranteed
|
138
|
-
# to be completely accurate, since there's no way to know if it will
|
139
|
-
# always be the last 3 words.
|
140
|
-
city = l[0]
|
141
|
-
state = l[1]
|
142
|
-
zip = l[2]
|
143
|
-
# for greater accuracy, we can use the city/state lookup API from USPS
|
144
|
-
if @options[:use_city_state_lookup]
|
145
|
-
l = city_state_lookup(zip)
|
146
|
-
# these will be nil if USPS does not have the zipcode in their database
|
147
|
-
city = l[:city] unless l[:city].nil?
|
148
|
-
state = l[:state] unless l[:state].nil?
|
149
|
-
zip = l[:zip] unless l[:zip].nil?
|
123
|
+
|
124
|
+
# Parses a USPS tracking event, and returns its location
|
125
|
+
# @param [String] event The tracking event to parse
|
126
|
+
# @return The location of the event
|
127
|
+
# @api private
|
128
|
+
def location_of_event(event)
|
129
|
+
# remove periods, and split by spaces
|
130
|
+
d = event.gsub(".", "").split(" ")
|
131
|
+
l = d[d.length-3, d.length] # => ['city', 'state', 'zip']
|
132
|
+
# this is the location from the USPS tracking XML. it is not guaranteed
|
133
|
+
# to be completely accurate, since there's no way to know if it will
|
134
|
+
# always be the last 3 words.
|
135
|
+
city = l[0]
|
136
|
+
state = l[1]
|
137
|
+
zip = l[2]
|
138
|
+
# for greater accuracy, we can use the city/state lookup API from USPS
|
139
|
+
if @options[:use_city_state_lookup]
|
140
|
+
l = city_state_lookup(zip)
|
141
|
+
# these will be nil if USPS does not have the zipcode in their database
|
142
|
+
city = l[:city] unless l[:city].nil?
|
143
|
+
state = l[:state] unless l[:state].nil?
|
144
|
+
zip = l[:zip] unless l[:zip].nil?
|
145
|
+
end
|
146
|
+
"#{city}, #{state} #{zip}"
|
150
147
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
zip.Zip5 zipcode
|
148
|
+
|
149
|
+
# Checks a HTTParty response for USPS, or HTTP errors
|
150
|
+
# @param [HTTParty::Response] response The HTTParty response to check
|
151
|
+
# @return The exception to raise, or nil
|
152
|
+
# @api private
|
153
|
+
def check_response_for_errors(response, api)
|
154
|
+
# return any HTTP errors
|
155
|
+
return response.error unless response.code == 200
|
156
|
+
# return a Trackerific::Error if there is an error in the response, or if
|
157
|
+
# the tracking response is malformed
|
158
|
+
return Trackerific::Error.new(response['Error']['Description']) unless response['Error'].nil?
|
159
|
+
return Trackerific::Error.new("Tracking information not found in response from server.") if response['TrackResponse'].nil? && api == :TrackV2
|
160
|
+
return Trackerific::Error.new("City / state information not found in response from server.") if response['CityStateLookupResponse'].nil? && api == :CityStateLookup
|
161
|
+
return nil # no errors to report
|
162
|
+
end
|
163
|
+
|
164
|
+
# Builds an XML city/state lookup request
|
165
|
+
# @param [String] zipcode The zipcode to find the city/state for
|
166
|
+
# @return [String] the xml request
|
167
|
+
# @api private
|
168
|
+
def build_city_state_xml_request(zipcode)
|
169
|
+
xml = ""
|
170
|
+
# set up the Builder
|
171
|
+
builder = ::Builder::XmlMarkup.new(:target => xml)
|
172
|
+
# add the XML header
|
173
|
+
builder.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
|
174
|
+
# build the request
|
175
|
+
builder.CityStateLookupRequest(:USERID => @options[:user_id]) do |request|
|
176
|
+
request.ZipCode(:ID => "5") do |zip|
|
177
|
+
zip.Zip5 zipcode
|
178
|
+
end
|
183
179
|
end
|
184
180
|
end
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
181
|
+
|
182
|
+
# Builds an XML tracking request
|
183
|
+
# @return [String] the xml request
|
184
|
+
# @api private
|
185
|
+
def build_tracking_xml_request
|
186
|
+
xml = ""
|
187
|
+
# set up the Builder
|
188
|
+
builder = ::Builder::XmlMarkup.new(:target => xml)
|
189
|
+
# build the request
|
190
|
+
builder.TrackRequest(:USERID => @options[:user_id]) do |t|
|
191
|
+
t.TrackID(:ID => @package_id)
|
192
|
+
end
|
193
|
+
# return the XML
|
194
|
+
xml
|
197
195
|
end
|
198
|
-
|
199
|
-
xml
|
196
|
+
|
200
197
|
end
|
201
|
-
|
198
|
+
|
202
199
|
end
|
203
|
-
|
204
200
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Trackerific
|
2
|
+
module Services
|
3
|
+
@services = {}
|
4
|
+
|
5
|
+
class << self
|
6
|
+
# Finds a service by the given name
|
7
|
+
# @param [Symbol] name The name of the service
|
8
|
+
# @return A descendant of Trackerific::Services::Base or nil for no match
|
9
|
+
# @api public
|
10
|
+
def [](name)
|
11
|
+
@services[name]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Registers a service by the given name and class
|
15
|
+
# @param [Symbol] name The name of the service
|
16
|
+
# @param [Trackerific::Services::Base] _class The base class to register
|
17
|
+
# @api public
|
18
|
+
def []=(name, _class)
|
19
|
+
unless _class.superclass == Trackerific::Services::Base
|
20
|
+
raise ArgumentError,
|
21
|
+
"Expected a Trackerific::Services::Base, got #{_class.inspect}",
|
22
|
+
caller
|
23
|
+
end
|
24
|
+
|
25
|
+
@services[name] = _class
|
26
|
+
end
|
27
|
+
|
28
|
+
# Finds the tracking service(s) that are capable of tracking the given
|
29
|
+
# package ID
|
30
|
+
# @param [String] id The package identifier
|
31
|
+
# @return [Array, Trackerific::Services::Base] The services that are
|
32
|
+
# capable of tracking the given ID.
|
33
|
+
# @example Find out which service providers can track a FedEx ID
|
34
|
+
# Trackerific::Services.find_by_package_id "183689015000001"
|
35
|
+
# @api public
|
36
|
+
def find_by_package_id(id)
|
37
|
+
@services.map {|n,s| s if s.can_track?(id) }.compact
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/trackerific.rb
CHANGED
@@ -1,86 +1,43 @@
|
|
1
|
-
require '
|
2
|
-
require 'helpers/options_helper'
|
1
|
+
require 'trackerific/version'
|
3
2
|
require 'trackerific/configuration'
|
4
|
-
require 'trackerific/service'
|
5
3
|
require 'trackerific/error'
|
6
4
|
require 'trackerific/details'
|
7
5
|
require 'trackerific/event'
|
6
|
+
require 'trackerific/services'
|
7
|
+
require 'trackerific/services/base'
|
8
8
|
|
9
|
-
#
|
10
|
-
|
11
|
-
|
9
|
+
# add tracking services here
|
10
|
+
require 'trackerific/services/fedex'
|
11
|
+
require 'trackerific/services/ups'
|
12
|
+
require 'trackerific/services/usps'
|
12
13
|
|
13
|
-
# Trackerific provides package tracking to Rails apps.
|
14
14
|
module Trackerific
|
15
|
-
|
16
15
|
class << self
|
17
|
-
#
|
18
|
-
# @
|
19
|
-
|
20
|
-
|
21
|
-
# a service is any Trackerific class that descends from Trackerific::Service
|
22
|
-
# [:UPS, :FedEx, :USPS, :MockService]
|
23
|
-
@services ||= Trackerific.constants.reject { |const|
|
24
|
-
const unless Trackerific.const_get(const).superclass == Trackerific::Service
|
25
|
-
}
|
16
|
+
# Used to access the Trackerific service credentials
|
17
|
+
# @api public
|
18
|
+
def configuration
|
19
|
+
Trackerific::Configuration.config
|
26
20
|
end
|
27
|
-
|
28
|
-
#
|
29
|
-
# @
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
return nil
|
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) }
|
37
30
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def tracking_service(package_id)
|
49
|
-
# loop through all the services
|
50
|
-
Trackerific.services.each do |service|
|
51
|
-
# get the class associated with this service
|
52
|
-
cls = Trackerific.const_get(service)
|
53
|
-
# loop through all the packge id regular expressions
|
54
|
-
cls.package_id_matchers.each do |matcher|
|
55
|
-
# return this class if the regular expression matches
|
56
|
-
return cls if package_id =~ matcher
|
57
|
-
end unless cls.package_id_matchers.nil?
|
31
|
+
|
32
|
+
# Looks up which service(s) can track the given ID and tracks it.
|
33
|
+
# @param [String] id The package identifier
|
34
|
+
# @return [Array, Trackerific::Details] The tracking results
|
35
|
+
# @raise [Trackerific::Error] Raised when the server returns an error
|
36
|
+
# @api public
|
37
|
+
def track(id)
|
38
|
+
Trackerific::Services.find_by_package_id(id).map do |service|
|
39
|
+
service.new.track(id)
|
40
|
+
end
|
58
41
|
end
|
59
|
-
# if we've made it this far, nothing matched
|
60
|
-
nil
|
61
|
-
end
|
62
|
-
|
63
|
-
# Tracks a package by determining its service from the package id
|
64
|
-
# @param [String] package_id the package identifier
|
65
|
-
# @return [Trackerific::Details] the tracking results
|
66
|
-
# @raise [Trackerific::Error] raised when the server returns an error (invalid credentials, tracking package, etc.)
|
67
|
-
# @example Track a package
|
68
|
-
# include Trackerific
|
69
|
-
# # make sure to configure Trackerific before hand with the different services credentials
|
70
|
-
# Trackerific.config do |config|
|
71
|
-
# config.fedex :meter => '123456789', :account => '123456789'
|
72
|
-
# end
|
73
|
-
# details = track_package "183689015000001"
|
74
|
-
# @api public
|
75
|
-
def track_package(package_id)
|
76
|
-
# find the service that will be able to track this package
|
77
|
-
service = tracking_service package_id
|
78
|
-
raise Trackerific::Error, "Cannot find a service to track package id #{package_id}" if service.nil?
|
79
|
-
# get the name of the service
|
80
|
-
service_name = service.to_s.split('::')[1].downcase
|
81
|
-
# get the default configuration for the service
|
82
|
-
options = Trackerific.configuration.send service_name
|
83
|
-
# track the package
|
84
|
-
service.new(options).track_package package_id
|
85
42
|
end
|
86
43
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,44 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
it { should be_a Trackerific::Configuration }
|
8
|
-
|
9
|
-
context "with valid options" do
|
10
|
-
it "should not raise any errors" do
|
11
|
-
lambda {
|
12
|
-
Trackerific.configure do |config|
|
13
|
-
config.usps :user_id => 'userid'
|
14
|
-
end
|
15
|
-
}.should_not raise_error
|
16
|
-
end
|
17
|
-
it "should save a valid option" do
|
18
|
-
Trackerific.configure do |config|
|
19
|
-
config.usps :user_id => 'userid'
|
20
|
-
end
|
21
|
-
Trackerific.configuration.usps[:user_id].should eq 'userid'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context "with invalid options" do
|
26
|
-
it "should raise ArgumentError" do
|
27
|
-
lambda {
|
28
|
-
Trackerific.configure do |config|
|
29
|
-
config.usps :invalid => 'option'
|
30
|
-
end
|
31
|
-
}.should raise_error ArgumentError
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "with invalid configuration group - not a Trackerific:Service" do
|
36
|
-
it "should raise NoMethodError" do
|
37
|
-
lambda {
|
38
|
-
Trackerific.configure do |config|
|
39
|
-
config.qwertyuiop :invalid => 'group'
|
40
|
-
end
|
41
|
-
}.should raise_error(NoMethodError)
|
3
|
+
describe Trackerific::Configuration do
|
4
|
+
before do
|
5
|
+
Trackerific::Configuration.configure do |config|
|
6
|
+
config.hello = 'world'
|
42
7
|
end
|
43
8
|
end
|
9
|
+
|
10
|
+
subject { described_class.config }
|
11
|
+
|
12
|
+
its(:hello) { should eq 'world' }
|
44
13
|
end
|