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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/Gemfile.lock +43 -1
- data/README.rdoc +58 -60
- data/lib/trackerific.rb +17 -20
- data/lib/trackerific/builders/base/soap.rb +21 -0
- data/lib/trackerific/builders/base/xml.rb +38 -0
- data/lib/trackerific/builders/fedex.rb +46 -0
- data/lib/trackerific/builders/ups.rb +32 -0
- data/lib/trackerific/builders/usps.rb +19 -0
- data/lib/trackerific/environment.rb +11 -0
- data/lib/trackerific/error.rb +3 -1
- data/lib/trackerific/parsers/base.rb +35 -0
- data/lib/trackerific/parsers/fedex.rb +59 -0
- data/lib/trackerific/parsers/ups.rb +66 -0
- data/lib/trackerific/parsers/usps.rb +51 -0
- data/lib/trackerific/services/base.rb +23 -10
- data/lib/trackerific/services/concerns/soap.rb +45 -0
- data/lib/trackerific/services/concerns/xml.rb +44 -0
- data/lib/trackerific/services/fedex.rb +9 -79
- data/lib/trackerific/services/mock_service.rb +4 -12
- data/lib/trackerific/services/ups.rb +11 -95
- data/lib/trackerific/services/usps.rb +21 -181
- data/lib/trackerific/soap/wsdl.rb +17 -0
- data/lib/trackerific/version.rb +1 -1
- data/spec/fixtures/fedex/error.xml +1 -10
- data/spec/fixtures/fedex/success.xml +1 -74
- data/spec/fixtures/ups/malformed.xml +10 -0
- data/spec/fixtures/ups/request.xml +1 -0
- data/spec/fixtures/usps/malformed.xml +2 -0
- data/spec/fixtures/usps/request.xml +1 -0
- data/spec/lib/trackerific/builders/base/soap_spec.rb +29 -0
- data/spec/lib/trackerific/builders/base/xml_spec.rb +35 -0
- data/spec/lib/trackerific/builders/fedex_spec.rb +70 -0
- data/spec/lib/trackerific/builders/ups_spec.rb +11 -0
- data/spec/lib/trackerific/builders/usps_spec.rb +11 -0
- data/spec/lib/trackerific/environment_spec.rb +45 -0
- data/spec/lib/trackerific/parsers/base_spec.rb +62 -0
- data/spec/lib/trackerific/parsers/ups_spec.rb +71 -0
- data/spec/lib/trackerific/parsers/usps_spec.rb +77 -0
- data/spec/lib/trackerific/services/base_spec.rb +56 -0
- data/spec/lib/trackerific/services/concerns/soap_spec.rb +71 -0
- data/spec/lib/trackerific/services/concerns/xml_spec.rb +65 -0
- data/spec/lib/trackerific/services/fedex_spec.rb +43 -45
- data/spec/lib/trackerific/services/ups_spec.rb +23 -2
- data/spec/lib/trackerific/services/usps_spec.rb +44 -34
- data/spec/lib/trackerific/services_spec.rb +7 -0
- data/spec/lib/trackerific/soap/wsdl_spec.rb +29 -0
- data/spec/lib/trackerific/version_spec.rb +1 -1
- data/spec/lib/trackerific_spec.rb +2 -11
- data/spec/spec_helper.rb +17 -1
- data/spec/support/reload.rb +6 -0
- data/spec/support/trackerific.rb +7 -0
- data/trackerific.gemspec +2 -0
- data/vendor/wsdl/fedex/TrackService_v8.wsdl +2284 -0
- metadata +81 -7
- data/lib/trackerific/configuration.rb +0 -7
- data/spec/fixtures/usps/city_state_lookup.xml +0 -8
- data/spec/lib/trackerific/configuration_spec.rb +0 -13
@@ -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 @@
|
|
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
|