trackerific 0.7.2 → 0.7.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.rdoc +2 -1
  4. data/lib/dependencies.rb +9 -0
  5. data/lib/trackerific.rb +5 -19
  6. data/lib/trackerific/builders.rb +12 -0
  7. data/lib/trackerific/builders/base/soap.rb +14 -16
  8. data/lib/trackerific/builders/base/xml.rb +22 -28
  9. data/lib/trackerific/builders/fedex.rb +66 -44
  10. data/lib/trackerific/builders/ups.rb +28 -24
  11. data/lib/trackerific/builders/usps.rb +15 -13
  12. data/lib/trackerific/parsers.rb +8 -0
  13. data/lib/trackerific/parsers/base.rb +24 -28
  14. data/lib/trackerific/parsers/fedex.rb +43 -47
  15. data/lib/trackerific/parsers/ups.rb +49 -53
  16. data/lib/trackerific/parsers/usps.rb +44 -48
  17. data/lib/trackerific/services.rb +10 -0
  18. data/lib/trackerific/services/base.rb +82 -55
  19. data/lib/trackerific/services/concerns/soap.rb +10 -40
  20. data/lib/trackerific/services/concerns/xml.rb +15 -37
  21. data/lib/trackerific/services/fedex.rb +9 -19
  22. data/lib/trackerific/services/mock_service.rb +26 -37
  23. data/lib/trackerific/services/ups.rb +11 -24
  24. data/lib/trackerific/services/usps.rb +23 -35
  25. data/lib/trackerific/soap.rb +5 -0
  26. data/lib/trackerific/soap/wsdl.rb +8 -12
  27. data/lib/trackerific/version.rb +1 -1
  28. data/spec/lib/trackerific/services/base_spec.rb +21 -4
  29. data/spec/lib/trackerific/services/concerns/soap_spec.rb +6 -21
  30. data/spec/lib/trackerific/services/concerns/xml_spec.rb +5 -18
  31. data/spec/lib/trackerific/services/mock_service_spec.rb +12 -0
  32. data/spec/lib/trackerific/services/usps_spec.rb +4 -4
  33. data/spec/lib/trackerific/version_spec.rb +1 -1
  34. data/spec/support/test_concerns.rb +15 -0
  35. metadata +8 -2
@@ -1,45 +1,15 @@
1
- module Trackerific
2
- module Services
3
- module Concerns
4
- module SOAP
5
- extend ActiveSupport::Concern
1
+ module Trackerific::Services::Concerns::SOAP
2
+ extend ActiveSupport::Concern
6
3
 
7
- included do
8
- @soap_track_operation = :track
9
- @soap_builder = nil
10
- @soap_parser = nil
11
- @soap_wsdl = ""
12
- end
4
+ protected
13
5
 
14
- module ClassMethods
15
- attr_accessor :soap_track_operation
16
- attr_accessor :soap_builder
17
- attr_accessor :soap_parser
18
- attr_accessor :soap_wsdl
19
- end
20
-
21
- def track(id)
22
- operation = self.class.soap_track_operation
23
- request = client.call(operation, message: builder(id).hash)
24
- response = self.class.soap_parser.new(id, request).parse
25
- response.is_a?(Trackerific::Error) ? raise(response) : response
26
- end
27
-
28
- protected
29
-
30
- def builder(id)
31
- members = self.class.soap_builder.members - [:package_id]
32
- credentials = @credentials.values_at(*members)
33
- credentials << id
34
- self.class.soap_builder.new(*credentials)
35
- end
6
+ def request(id)
7
+ client.call(config.track_operation, message: builder(id).hash)
8
+ end
36
9
 
37
- def client
38
- @client ||= Savon.client(
39
- convert_request_keys_to: :camelcase,
40
- wsdl: Trackerific::SOAP::WSDL.path(self.class.soap_wsdl))
41
- end
42
- end
43
- end
10
+ def client
11
+ @client ||= Savon.client(
12
+ convert_request_keys_to: :camelcase,
13
+ wsdl: Trackerific::SOAP::WSDL.path(config.wsdl))
44
14
  end
45
15
  end
@@ -1,44 +1,22 @@
1
- module Trackerific
2
- module Services
3
- module Concerns
4
- module XML
5
- extend ActiveSupport::Concern
1
+ module Trackerific::Services::Concerns::XML
2
+ extend ActiveSupport::Concern
6
3
 
7
- included do
8
- @xml_endpoint = ""
9
- @xml_parser = nil
10
- @xml_builder = nil
11
- end
4
+ included do
5
+ include HTTParty
12
6
 
13
- module ClassMethods
14
- attr_accessor :xml_endpoint
15
- attr_accessor :xml_parser
16
- attr_accessor :xml_builder
17
- end
18
-
19
- # Gets the tracking information for the package from the server
20
- # @param [String] id The package identifier
21
- # @return [Trackerific::Details] The tracking details
22
- # @api semipublic
23
- def track(id)
24
- response = self.class.xml_parser.new(id, http_response(id)).parse
25
- raise(response) if response.is_a?(Trackerific::Error)
26
- return response
27
- end
7
+ format :xml
8
+ end
28
9
 
29
- protected
10
+ module ClassMethods
11
+ def configure(&block)
12
+ super
13
+ base_uri(config.base_uri)
14
+ end
15
+ end
30
16
 
31
- def http_response(id)
32
- self.class.post(self.class.xml_endpoint, body: builder(id).xml)
33
- end
17
+ protected
34
18
 
35
- def builder(id)
36
- members = self.class.xml_builder.members - [:package_id]
37
- credentials = @credentials.values_at(*members)
38
- credentials << id
39
- self.class.xml_builder.new(*credentials)
40
- end
41
- end
42
- end
19
+ def request(id)
20
+ self.class.post(config.endpoint, body: builder(id).xml)
43
21
  end
44
22
  end
@@ -1,21 +1,11 @@
1
- module Trackerific
2
- module Services
3
- class FedEx < Base
4
- require 'trackerific/builders/fedex'
5
- require 'trackerific/parsers/fedex'
6
-
7
- include Concerns::SOAP
8
-
9
- register :fedex
10
-
11
- self.soap_track_operation = :track
12
- self.soap_builder = Builders::FedEx
13
- self.soap_parser = Parsers::FedEx
14
- self.soap_wsdl = 'fedex/TrackService_v8'
15
-
16
- def self.package_id_matchers
17
- [ /^[0-9]{15}$/ ]
18
- end
19
- end
1
+ class Trackerific::Services::FedEx < Trackerific::Services::Base
2
+ register :fedex, as: :SOAP
3
+
4
+ configure do |config|
5
+ config.track_operation = :track
6
+ config.builder = Trackerific::Builders::FedEx
7
+ config.parser = Trackerific::Parsers::FedEx
8
+ config.wsdl = 'fedex/TrackService_v8'
9
+ config.package_id_matchers = [ /^[0-9]{15}$/ ]
20
10
  end
21
11
  end
@@ -1,44 +1,33 @@
1
- module Trackerific
2
- module Services
3
- # Provides a mock service for using in test and development
4
- class MockService < Base
5
- require 'date'
1
+ # Provides a mock service for using in test and development
2
+ class Trackerific::Services::MockService < Trackerific::Services::Base
3
+ require 'date'
6
4
 
7
- self.register :mock_service
5
+ register :mock_service
8
6
 
9
- def self.credentials
10
- {}
11
- end
7
+ configure do |config|
8
+ config.package_id_matchers = [ /XXXXXXXXXX/, /XXXxxxxxxx/ ]
9
+ end
10
+
11
+ def self.credentials
12
+ {}
13
+ end
14
+
15
+ def track(id)
16
+ if id == "XXXXXXXXXX"
17
+ Trackerific::Details.new(id, "Your package was delivered.", events)
18
+ else
19
+ raise Trackerific::Error, "Package not found."
20
+ end
21
+ end
12
22
 
13
- def self.package_id_matchers
14
- [ /XXXXXXXXXX/, /XXXxxxxxxx/ ]
15
- end
23
+ private
16
24
 
17
- def track(id)
18
- if id == "XXXXXXXXXX"
19
- Trackerific::Details.new(id, "Your package was delivered.",
20
- [
21
- Trackerific::Event.new(
22
- :date => Date.today,
23
- :description => "Package delivered.",
24
- :location => "SANTA MARIA, CA"
25
- ),
26
- Trackerific::Event.new(
27
- :date => Date.today - 1,
28
- :description => "Package scanned.",
29
- :location => "SANTA BARBARA, CA"
30
- ),
31
- Trackerific::Event.new(
32
- :date => Date.today - 2,
33
- :description => "Package picked up for delivery.",
34
- :location => "LOS ANGELES, CA"
35
- )
36
- ]
37
- )
38
- else
39
- raise Trackerific::Error, "Package not found."
40
- end
41
- end
25
+ def events
26
+ [ [Date.today, "Package delivered.", "SANTA MARIA, CA"],
27
+ [Date.today - 1, "Package scanned.", "SANTA BARBARA, CA"],
28
+ [Date.today - 2, "Package picked up for delivery.", "LOS ANGELES, CA"]
29
+ ].map do |event|
30
+ Trackerific::Event.new(*event)
42
31
  end
43
32
  end
44
33
  end
@@ -1,27 +1,14 @@
1
- module Trackerific
2
- module Services
3
- class UPS < Base
4
- require 'trackerific/builders/ups'
5
- require 'trackerific/parsers/ups'
6
-
7
- include Concerns::XML, HTTParty
8
-
9
- register :ups
10
-
11
- self.xml_endpoint = '/Track'
12
- self.xml_parser = Parsers::UPS
13
- self.xml_builder = Builders::UPS
14
-
15
- format :xml
16
-
17
- base_uri case Trackerific.env
18
- when 'production' then 'https://www.ups.com/ups.app/xml'
19
- else 'https://wwwcie.ups.com/ups.app/xml'
20
- end
21
-
22
- def self.package_id_matchers
23
- [ /^.Z/, /^[HK].{10}$/ ]
24
- end
1
+ class Trackerific::Services::UPS < Trackerific::Services::Base
2
+ register :ups, as: :XML
3
+
4
+ configure do |config|
5
+ config.endpoint = '/Track'
6
+ config.parser = Trackerific::Parsers::UPS
7
+ config.builder = Trackerific::Builders::UPS
8
+ config.package_id_matchers = [ /^.Z/, /^[HK].{10}$/ ]
9
+ config.base_uri = case Trackerific.env
10
+ when 'production' then 'https://www.ups.com/ups.app/xml'
11
+ else 'https://wwwcie.ups.com/ups.app/xml'
25
12
  end
26
13
  end
27
14
  end
@@ -1,40 +1,28 @@
1
- module Trackerific
2
- module Services
3
- class USPS < Base
4
- require 'trackerific/builders/usps'
5
- require 'trackerific/parsers/usps'
6
-
7
- include Concerns::XML, HTTParty
8
-
9
- register :usps
10
-
11
- self.xml_parser = Parsers::USPS
12
- self.xml_builder = Builders::USPS
13
-
14
- case Trackerific.env
15
- when 'production'
16
- self.xml_endpoint = '/ShippingAPI.dll'
17
- base_uri 'http://production.shippingapis.com'
18
- else
19
- self.xml_endpoint = '/ShippingAPITest.dll'
20
- base_uri 'http://testing.shippingapis.com'
21
- end
22
-
23
- format :xml
24
-
25
- def self.package_id_matchers
26
- [ /^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/ ]
27
- end
1
+ class Trackerific::Services::USPS < Trackerific::Services::Base
2
+ register :usps, as: :XML
3
+
4
+ configure do |config|
5
+ config.parser = Trackerific::Parsers::USPS
6
+ config.builder = Trackerific::Builders::USPS
7
+ config.package_id_matchers = [ /^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/ ]
8
+
9
+ case Trackerific.env
10
+ when 'production'
11
+ config.endpoint = '/ShippingAPI.dll'
12
+ config.base_uri = 'http://production.shippingapis.com'
13
+ else
14
+ config.endpoint = '/ShippingAPITest.dll'
15
+ config.base_uri = 'http://testing.shippingapis.com'
16
+ end
17
+ end
28
18
 
29
- protected
19
+ protected
30
20
 
31
- def http_response(id)
32
- http_response = self.class.get(self.class.xml_endpoint, http_query(id))
33
- end
21
+ def request(id)
22
+ self.class.get(config.endpoint, http_query(id))
23
+ end
34
24
 
35
- def http_query(id)
36
- { query: { :API => 'TrackV2', :XML => builder(id).xml }.to_query }
37
- end
38
- end
25
+ def http_query(id)
26
+ { query: { :API => 'TrackV2', :XML => builder(id).xml }.to_query }
39
27
  end
40
28
  end
@@ -0,0 +1,5 @@
1
+ module Trackerific
2
+ module SOAP
3
+ require 'trackerific/soap/wsdl'
4
+ end
5
+ end
@@ -1,17 +1,13 @@
1
- module Trackerific
2
- module SOAP
3
- module WSDL
4
- ROOT = File.expand_path("../../../../vendor/wsdl", __FILE__)
1
+ module Trackerific::SOAP::WSDL
2
+ ROOT = File.expand_path("../../../../vendor/wsdl", __FILE__)
5
3
 
6
- def self.path(name)
7
- path = File.join(ROOT, "#{name}.wsdl")
4
+ def self.path(name)
5
+ path = File.join(ROOT, "#{name}.wsdl")
8
6
 
9
- unless File.exists?(path)
10
- raise IOError, "WSDL not found #{name}", caller
11
- end
12
-
13
- path
14
- end
7
+ unless File.exists?(path)
8
+ raise IOError, "WSDL not found #{name}", caller
15
9
  end
10
+
11
+ path
16
12
  end
17
13
  end
@@ -1,3 +1,3 @@
1
1
  module Trackerific
2
- VERSION = "0.7.2"
2
+ VERSION = "0.7.3"
3
3
  end
@@ -11,6 +11,18 @@ describe Trackerific::Services::Base do
11
11
  end
12
12
  end
13
13
 
14
+ describe "#configure" do
15
+ it "should set @config properties passed from the given block" do
16
+ TestService.configure {|c| c.value = 'this' }
17
+ TestService.config.value.should eq 'this'
18
+ end
19
+ end
20
+
21
+ describe "#config" do
22
+ subject { TestService.new.config }
23
+ it { should eq TestService.config }
24
+ end
25
+
14
26
  describe "#track" do
15
27
  it "should create a new instance and call #track with the given id" do
16
28
  TestService.any_instance.should_receive(:track).with('ID')
@@ -51,11 +63,16 @@ describe Trackerific::Services::Base do
51
63
  end
52
64
 
53
65
  describe "#package_id_matchers" do
54
- it "should raise a NotImplementedError when not overridden" do
55
- expect {
56
- Trackerific::Services::Base.package_id_matchers
57
- }.to raise_error NotImplementedError
66
+ let(:matchers) { ['these','matchers'] }
67
+
68
+ before do
69
+ Trackerific::Services::Base.configure do |config|
70
+ config.package_id_matchers = matchers
71
+ end
58
72
  end
73
+
74
+ subject { Trackerific::Services::Base.package_id_matchers }
75
+ it { should eq matchers }
59
76
  end
60
77
 
61
78
  context "when creating a new instance without credentials" do
@@ -1,25 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Trackerific::Services::Concerns::SOAP do
4
- class TestConcernsSOAP
5
- include Trackerific::Services::Concerns::SOAP
6
-
7
- def initialize
8
- @credentials = { user_id: 'USER ID' }
9
- end
10
- end
11
-
12
4
  subject { TestConcernsSOAP }
13
5
 
14
- it { should respond_to :soap_track_operation }
15
- it { should respond_to :soap_track_operation= }
16
- it { should respond_to :soap_builder }
17
- it { should respond_to :soap_builder= }
18
- it { should respond_to :soap_parser }
19
- it { should respond_to :soap_parser= }
20
- it { should respond_to :soap_wsdl }
21
- it { should respond_to :soap_wsdl= }
22
-
23
6
  describe "#track" do
24
7
  let(:track_operation) { double(:track_operation) }
25
8
  let(:package_id) { "PACKAGE ID" }
@@ -38,10 +21,12 @@ describe Trackerific::Services::Concerns::SOAP do
38
21
  let(:soap_request) { double(:soap_request) }
39
22
 
40
23
  before do
41
- TestConcernsSOAP.stub(:soap_track_operation).and_return(track_operation)
42
- TestConcernsSOAP.stub(:soap_wsdl).and_return(wsdl)
43
- TestConcernsSOAP.stub(:soap_builder).and_return(builder)
44
- TestConcernsSOAP.stub(:soap_parser).and_return(parser)
24
+ TestConcernsSOAP.configure do |config|
25
+ config.track_operation = track_operation
26
+ config.wsdl = wsdl
27
+ config.builder = builder
28
+ config.parser = parser
29
+ end
45
30
 
46
31
  builder.stub(:members).and_return([:user_id, :package_id])
47
32
  builder.should_receive(:new).with("USER ID", package_id).and_return(builder_instance)