trackerific 0.7.1 → 0.7.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 (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
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0"?>
2
+ <TrackResponse>
3
+ <Response>
4
+ <ResponseStatusCode>3</ResponseStatusCode>
5
+ <ResponseStatusDescription>Failure</ResponseStatusDescription>
6
+ <Error>
7
+ <ErrorCode>10002</ErrorCode>
8
+ </Error>
9
+ </Response>
10
+ </TrackResponse>
@@ -0,0 +1 @@
1
+ <?xml encoding="UTF-8"?><AccessRequest><AccessLicenseNumber>KEY</AccessLicenseNumber><UserId>USER ID</UserId><Password>PASSWORD</Password></AccessRequest><TrackRequest><Request><RequestAction>Track</RequestAction><RequestOption>activity</RequestOption></Request><TrackingNumber>PACKAGE ID</TrackingNumber></TrackRequest>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <oops></oops>
@@ -0,0 +1 @@
1
+ <?xml encoding="UTF-8"?><TrackRequest USERID="USER ID"><TrackID ID="PACKAGE ID"/></TrackRequest>
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Builders::Base::SOAP do
4
+ let(:builder) { described_class.new(:hello, :world) }
5
+
6
+ context "when #build is not implemented in the subclass" do
7
+ it "should raise a NotImplementedError on initialize" do
8
+ expect {
9
+ builder.new
10
+ }.to raise_error NotImplementedError
11
+ end
12
+ end
13
+
14
+ context "when #build is implemented in the subclass" do
15
+ before do
16
+ builder.any_instance.stub(:build).and_return("BUILD")
17
+ end
18
+
19
+ it "should call #build on initialize" do
20
+ builder.any_instance.should_receive(:build)
21
+ builder.new
22
+ end
23
+
24
+ it "should assign the output of #build to #hash" do
25
+ b = builder.new
26
+ b.hash.should eq "BUILD"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Builders::Base::XML do
4
+ let(:builder) { described_class.new(:hello, :world) }
5
+
6
+ subject { builder }
7
+
8
+ it { should respond_to :xml_version }
9
+ it { should respond_to :xml_version= }
10
+
11
+ context "when #build is not implemented in the subclass" do
12
+ it "should raise a NotImplementedError on initialize" do
13
+ expect {
14
+ builder.new
15
+ }.to raise_error NotImplementedError
16
+ end
17
+ end
18
+
19
+ context "when #build is implemented in the subclass" do
20
+ subject { builder.new('hi', 'earth') }
21
+
22
+ before do
23
+ builder.send(:define_method, :build) do
24
+ builder.Hello hello
25
+ builder.World world
26
+ end
27
+ end
28
+
29
+ let(:xml) do
30
+ '<?xml encoding="UTF-8"?><Hello>hi</Hello><World>earth</World>'
31
+ end
32
+
33
+ its(:xml) { should eq xml }
34
+ end
35
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Builders::FedEx do
4
+ it { should be_a Trackerific::Builders::Base::SOAP }
5
+
6
+ describe "#members" do
7
+ subject { described_class.members }
8
+ it { should include :key }
9
+ it { should include :password }
10
+ it { should include :account_number }
11
+ it { should include :meter_number }
12
+ it { should include :package_id }
13
+ end
14
+
15
+ describe "#new" do
16
+ let(:params) do
17
+ [ "KEY", "PASSWORD", "ACCOUNT NUMBER", "METER NUMBER", "PACKAGE ID" ]
18
+ end
19
+
20
+ let(:transaction_id) { "TRANSACTION ID" }
21
+ let(:instance) { described_class.new(*params) }
22
+ let(:hash) { instance.hash }
23
+
24
+ describe "Web Authentication Detail" do
25
+ let(:web_authentication_detail) { hash[:web_authentication_detail] }
26
+
27
+ describe "User Credential" do
28
+ subject { web_authentication_detail[:user_credential] }
29
+ its([:key]) { should eq "KEY" }
30
+ its([:password]) { should eq "PASSWORD" }
31
+ end
32
+ end
33
+
34
+ describe "Client Detail" do
35
+ subject { hash[:client_detail] }
36
+ its([:account_number]) { should eq "ACCOUNT NUMBER" }
37
+ its([:meter_number]) { should eq "METER NUMBER" }
38
+ end
39
+
40
+ describe "Transaction Detail" do
41
+ subject { hash[:transaction_detail] }
42
+ its([:customer_transaction_id]) { should eq "Trackerific" }
43
+ end
44
+
45
+ describe "Version" do
46
+ subject { hash[:version] }
47
+ its([:service_id]) { should eq "trck" }
48
+ its([:major]) { should eq "8" }
49
+ its([:intermediate]) { should eq "0" }
50
+ its([:minor]) { should eq "0" }
51
+ end
52
+
53
+ describe "Selection Details" do
54
+ let(:selection_details) { hash[:selection_details] }
55
+ subject { selection_details }
56
+ its([:carrier_code]) { should eq "FDXE" }
57
+
58
+ describe "Package Identifier" do
59
+ subject { selection_details[:package_identifier] }
60
+ its([:type]) { should eq "TRACKING_NUMBER_OR_DOORTAG" }
61
+ its([:value]) { should eq "PACKAGE ID" }
62
+ end
63
+ end
64
+
65
+ describe "Processing Options" do
66
+ subject { hash[:processing_options] }
67
+ it { should eq "INCLUDE_DETAILED_SCANS" }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Builders::UPS do
4
+ subject { described_class.new("KEY", "USER ID", "PASSWORD", "PACKAGE ID") }
5
+
6
+ it { should be_a Trackerific::Builders::Base::XML }
7
+
8
+ let(:fixture) { Fixture.read('ups/request.xml') }
9
+
10
+ its(:xml) { should eq fixture.strip }
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Builders::USPS do
4
+ it { should be_a Trackerific::Builders::Base::XML }
5
+
6
+ subject { described_class.new("USER ID", "PACKAGE ID") }
7
+
8
+ let(:fixture) { Fixture.read('usps/request.xml') }
9
+
10
+ its(:xml) { should eq fixture.strip }
11
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific do
4
+ describe "#env" do
5
+ let(:rack_env) { nil }
6
+ let(:rails_env) { nil }
7
+
8
+ before(:all) do
9
+ Trackerific.env = nil
10
+ end
11
+
12
+ before(:each) do
13
+ ENV['RAILS_ENV'] = rails_env
14
+ ENV['RACK_ENV'] = rack_env
15
+ end
16
+
17
+ after(:all) do
18
+ Trackerific.env = 'test'
19
+ ENV['RAILS_ENV'] = nil
20
+ ENV['RACK_ENV'] = 'test'
21
+ end
22
+
23
+ subject { Trackerific.env }
24
+
25
+ context "when RAILS_ENV and RACK_ENV are not present" do
26
+ it { should eq 'development' }
27
+ end
28
+
29
+ context "when RAILS_ENV is present" do
30
+ let(:rails_env) { 'RAILS' }
31
+ it { should eq rails_env }
32
+ end
33
+
34
+ context "when RACK_ENV is present" do
35
+ let(:rack_env) { 'RACK' }
36
+ it { should eq rack_env }
37
+ end
38
+
39
+ context "when RAILS_ENV and RACK_ENV is present" do
40
+ let(:rack_env) { 'RACK' }
41
+ let(:rails_env) { 'RAILS' }
42
+ it { should eq rails_env }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Parsers::Base do
4
+ let(:package_id) { "PACKAGE ID" }
5
+ let(:response) { double(:response) }
6
+ let(:parser) { described_class.new(package_id, response) }
7
+
8
+ let(:response_error) { nil }
9
+ let(:summary) { "SUMMARY" }
10
+ let(:events) { double([Trackerific::Event]) }
11
+
12
+ describe "#parse" do
13
+ let(:stub_summary) { true }
14
+ let(:stub_events) { true }
15
+ let(:stub_response_error) { true }
16
+
17
+ before do
18
+ parser.stub(:summary).and_return(summary) if stub_summary
19
+ parser.stub(:events).and_return(events) if stub_events
20
+ parser.stub(:response_error).and_return(response_error) if stub_response_error
21
+ end
22
+
23
+ subject { parser.parse }
24
+
25
+ context "when #response_error is a Trackerific::Error" do
26
+ let(:response_error) { Trackerific::Error.new }
27
+ it { should eq response_error }
28
+ end
29
+
30
+ context "when #response_error is false" do
31
+ let(:response_error) { false }
32
+ it { should be_a Trackerific::Details }
33
+ its(:package_id) { should eq package_id }
34
+ its(:summary) { should eq summary }
35
+ its(:events) { should eq events }
36
+ end
37
+
38
+ context "when the subclass does not properly define all required methods" do
39
+ context "when #response_error is not overridden" do
40
+ let(:stub_response_error) { false }
41
+ it "should raise a NotImplementedError" do
42
+ expect { subject }.to raise_error NotImplementedError
43
+ end
44
+ end
45
+
46
+ context "when #events is not overridden" do
47
+ let(:stub_events) { false }
48
+ it "should raise a NotImplementedError" do
49
+ expect { subject }.to raise_error NotImplementedError
50
+ end
51
+ end
52
+
53
+ context "when #summary is not overridden" do
54
+ let(:stub_summary) { false }
55
+ it "should raise a NotImplementedError" do
56
+ expect { subject }.to raise_error NotImplementedError
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Parsers::UPS do
4
+ let(:package_id) { "PACKAGE ID" }
5
+
6
+ let(:xml) { "" }
7
+
8
+ let(:response) { Hash.from_xml(xml) || {} }
9
+
10
+ let(:parser) { described_class.new(package_id, response) }
11
+
12
+ subject { parser }
13
+
14
+ it { should be_a Trackerific::Parsers::Base }
15
+
16
+ describe "#parse" do
17
+ before do
18
+ response.stub(:code).and_return(response_code)
19
+ end
20
+
21
+ subject { parser.parse }
22
+
23
+ context "when response.code is not 200" do
24
+ let(:response_code) { 404 }
25
+ it { should be_a Trackerific::Error }
26
+ its(:message) { should eq "HTTP returned status 404" }
27
+ end
28
+
29
+ context "when response.code is 200" do
30
+ let(:response_code) { 200 }
31
+
32
+ context "with an unknown/malformed response" do
33
+ let(:xml) { Fixture.read('ups/malformed.xml') }
34
+ it { should be_a Trackerific::Error }
35
+ end
36
+
37
+ context "with an error response" do
38
+ let(:xml) { Fixture.read('ups/error.xml') }
39
+ it { should be_a Trackerific::Error }
40
+ end
41
+
42
+ context "with a success response" do
43
+ let(:xml) { Fixture.read('ups/success.xml') }
44
+ it { should be_a Trackerific::Details }
45
+
46
+ it "should populate its properties with values from the XML" do
47
+ subject.package_id.should eq "PACKAGE ID"
48
+ subject.summary.should eq "DELIVERED"
49
+ subject.weight.should be_nil
50
+ subject.via.should be_nil
51
+ end
52
+
53
+ describe "#events" do
54
+ subject { parser.parse.events }
55
+
56
+ it "should be an Array of Trackerific::Event" do
57
+ subject.should be_a Array
58
+ subject.length.should eq 1
59
+ subject.all? {|e| e.should be_a Trackerific::Event }.should be_true
60
+ end
61
+
62
+ it "should populate the events with values from the XML" do
63
+ subject[0].date.should be_a DateTime
64
+ subject[0].description.should eq "DELIVERED"
65
+ subject[0].location.should eq "MAYSVILLE 26833 9700 US"
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trackerific::Parsers::USPS do
4
+ let(:package_id) { "PACKAGE ID" }
5
+
6
+ let(:xml) { "" }
7
+
8
+ let(:response) { Hash.from_xml(xml) || {} }
9
+
10
+ let(:parser) { described_class.new(package_id, response) }
11
+
12
+ subject { parser }
13
+
14
+ it { should be_a Trackerific::Parsers::Base }
15
+
16
+ describe "#parse" do
17
+ before do
18
+ response.stub(:code).and_return(response_code)
19
+ end
20
+
21
+ subject { parser.parse }
22
+
23
+ context "when response.code is not 200" do
24
+ let(:response_code) { 404 }
25
+ it { should be_a Trackerific::Error }
26
+ its(:message) { should eq "HTTP returned status 404" }
27
+ end
28
+
29
+ context "when response.code is 200" do
30
+ let(:response_code) { 200 }
31
+
32
+ context "with an unknown/malformed response" do
33
+ let(:xml) { Fixture.read('usps/malformed.xml') }
34
+ it { should be_a Trackerific::Error }
35
+ end
36
+
37
+ context "with an error response" do
38
+ let(:xml) { Fixture.read('usps/error.xml') }
39
+ it { should be_a Trackerific::Error }
40
+ end
41
+
42
+ context "with a success response" do
43
+ let(:xml) { Fixture.read('usps/success.xml') }
44
+ it { should be_a Trackerific::Details }
45
+
46
+ it "should populate its properties with values from the XML" do
47
+ subject.package_id.should eq "PACKAGE ID"
48
+ subject.summary.should eq "Your item was delivered at 8:10 am on June 1 in Wilmington DE 19801."
49
+ subject.weight.should be_nil
50
+ subject.via.should be_nil
51
+ end
52
+
53
+ describe "#events" do
54
+ subject { parser.parse.events }
55
+
56
+ it "should be an Array of Trackerific::Event" do
57
+ subject.should be_a Array
58
+ subject.length.should eq 3
59
+ subject.all? {|e| e.should be_a Trackerific::Event }.should be_true
60
+ end
61
+
62
+ it "should populate the events with values from the XML" do
63
+ subject[0].date.should be_a DateTime
64
+ subject[0].description.should eq "NOTICE LEFT"
65
+ subject[0].location.should eq "WILMINGTON, DE 19801"
66
+ subject[1].date.should be_a DateTime
67
+ subject[1].description.should eq "ARRIVAL AT UNIT"
68
+ subject[1].location.should eq "WILMINGTON, DE 19850"
69
+ subject[2].date.should be_a DateTime
70
+ subject[2].description.should eq "ACCEPT OR PICKUP"
71
+ subject[2].location.should eq "EDGEWATER, NJ 07020"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end