correios-sro-xml 0.0.4 → 0.1.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.
- data/.gitignore +25 -0
- data/CHANGELOG.rdoc +14 -8
- data/Gemfile +1 -12
- data/README.rdoc +181 -35
- data/Rakefile +13 -35
- data/correios-sro-xml.gemspec +24 -80
- data/lib/correios-sro-xml.rb +4 -4
- data/lib/correios/sro.rb +11 -0
- data/lib/correios/sro/destination.rb +16 -0
- data/lib/correios/sro/event.rb +31 -0
- data/lib/correios/sro/object.rb +13 -0
- data/lib/correios/sro/parser.rb +5 -5
- data/lib/correios/sro/tracker.rb +43 -0
- data/lib/correios/sro/version.rb +1 -6
- data/lib/correios/sro/web_service.rb +64 -11
- data/misc/correios_sro_xml_manual_v1.5.pdf +0 -0
- data/spec/correios/sro/event_spec.rb +15 -0
- data/spec/correios/sro/parser_spec.rb +44 -44
- data/spec/correios/sro/tracker_spec.rb +116 -0
- data/spec/correios/sro/web_service_spec.rb +10 -4
- data/spec/correios/sro_spec.rb +22 -0
- data/spec/spec_helper.rb +3 -5
- data/spec/support/mock_request.rb +22 -0
- data/spec/support/responses/failure_response_not_found.xml +6 -0
- data/spec/support/responses/{success-response-many-objects.xml → success_response_many_objects.xml} +0 -0
- data/spec/support/responses/{success-response-many-objects-international.xml → success_response_many_objects_international.xml} +0 -0
- data/spec/support/responses/{success-response-one-object.xml → success_response_one_object.xml} +0 -0
- metadata +54 -59
- data/Gemfile.lock +0 -62
- data/lib/correios/sro/destino.rb +0 -16
- data/lib/correios/sro/evento.rb +0 -31
- data/lib/correios/sro/objeto.rb +0 -13
- data/lib/correios/sro/rastreador.rb +0 -43
- data/spec/correios/sro/evento_spec.rb +0 -15
- data/spec/correios/sro/rastreador_spec.rb +0 -53
- data/spec/support/fake_request.rb +0 -21
data/lib/correios-sro-xml.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'rubygems'
|
3
3
|
require 'correios/sro'
|
4
|
-
require 'correios/sro/
|
5
|
-
require 'correios/sro/
|
6
|
-
require 'correios/sro/
|
4
|
+
require 'correios/sro/destination'
|
5
|
+
require 'correios/sro/event'
|
6
|
+
require 'correios/sro/object'
|
7
7
|
require 'correios/sro/parser'
|
8
|
-
require 'correios/sro/
|
8
|
+
require 'correios/sro/tracker'
|
9
9
|
require 'correios/sro/string'
|
10
10
|
require 'correios/sro/web_service'
|
data/lib/correios/sro.rb
CHANGED
@@ -4,5 +4,16 @@ require 'log-me'
|
|
4
4
|
module Correios
|
5
5
|
module SRO
|
6
6
|
extend LogMe
|
7
|
+
|
8
|
+
module Timeout
|
9
|
+
DEFAULT_REQUEST_TIMEOUT = 5 #seconds
|
10
|
+
attr_writer :request_timeout
|
11
|
+
|
12
|
+
def request_timeout
|
13
|
+
(@request_timeout ||= DEFAULT_REQUEST_TIMEOUT).to_i
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
extend Timeout
|
7
18
|
end
|
8
19
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'sax-machine'
|
3
|
+
|
4
|
+
module Correios
|
5
|
+
module SRO
|
6
|
+
class Destination
|
7
|
+
include SAXMachine
|
8
|
+
|
9
|
+
element :local, :as => :place
|
10
|
+
element :codigo, :as => :code
|
11
|
+
element :cidade, :as => :city
|
12
|
+
element :bairro, :as => :neighborhood
|
13
|
+
element :uf, :as => :state
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'sax-machine'
|
3
|
+
|
4
|
+
module Correios
|
5
|
+
module SRO
|
6
|
+
class Event
|
7
|
+
include SAXMachine
|
8
|
+
|
9
|
+
element :tipo, :as => :type
|
10
|
+
element :status, :as => :status
|
11
|
+
element :data, :as => :date
|
12
|
+
element :hora, :as => :hour
|
13
|
+
element :descricao, :as => :description
|
14
|
+
element :recebedor, :as => :receiver
|
15
|
+
element :documento, :as => :document
|
16
|
+
element :comentario, :as => :comment
|
17
|
+
element :local, :as => :place
|
18
|
+
element :codigo, :as => :code
|
19
|
+
element :cidade, :as => :city
|
20
|
+
element :uf, :as => :state
|
21
|
+
element :sto, :as => :sto
|
22
|
+
element :destino, :as => :destination, :class => Correios::SRO::Destination
|
23
|
+
|
24
|
+
[:receiver, :document, :comment].each do |method|
|
25
|
+
define_method "#{method}=" do |value|
|
26
|
+
instance_variable_set("@#{method}", value.to_s.strip)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/correios/sro/parser.rb
CHANGED
@@ -4,17 +4,17 @@ require 'nokogiri'
|
|
4
4
|
module Correios
|
5
5
|
module SRO
|
6
6
|
class Parser
|
7
|
-
def
|
8
|
-
|
7
|
+
def objects(xml)
|
8
|
+
objects = {}
|
9
9
|
xml = xml.backward_encode("UTF-8", "ISO-8859-1")
|
10
10
|
|
11
11
|
doc = Nokogiri::XML(xml)
|
12
12
|
doc.xpath("//objeto").each do |element|
|
13
|
-
|
14
|
-
|
13
|
+
object = Correios::SRO::Object.parse(element.to_xml)
|
14
|
+
objects[object.number] = object
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
objects
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Correios
|
3
|
+
module SRO
|
4
|
+
class Tracker
|
5
|
+
attr_accessor :user, :password
|
6
|
+
attr_accessor :query_type, :result_mode
|
7
|
+
attr_reader :object_numbers
|
8
|
+
|
9
|
+
DEFAULT_OPTIONS = { :query_type => :list, :result_mode => :last }
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
DEFAULT_OPTIONS.merge(options).each do |attr, value|
|
13
|
+
self.send("#{attr}=", value)
|
14
|
+
end
|
15
|
+
|
16
|
+
yield self if block_given?
|
17
|
+
@object_numbers = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(*object_numbers)
|
21
|
+
@object_numbers = object_numbers
|
22
|
+
response = web_service.request!
|
23
|
+
objects = parser.objects(response)
|
24
|
+
|
25
|
+
if @object_numbers.size == 1
|
26
|
+
objects.values.first
|
27
|
+
else
|
28
|
+
objects
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def web_service
|
35
|
+
@web_service ||= Correios::SRO::WebService.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def parser
|
39
|
+
@parser ||= Correios::SRO::Parser.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/correios/sro/version.rb
CHANGED
@@ -6,29 +6,82 @@ module Correios
|
|
6
6
|
module SRO
|
7
7
|
class WebService
|
8
8
|
URL = "http://websro.correios.com.br/sro_bin/sroii_xml.eventos"
|
9
|
-
|
10
|
-
|
9
|
+
QUERY_TYPES = { :list => "L", :range => "F" }
|
10
|
+
RESULT_MODES = { :all => "T", :last => "U" }
|
11
11
|
|
12
|
-
def initialize
|
12
|
+
def initialize(tracker)
|
13
13
|
@uri = URI.parse(URL)
|
14
|
+
@tracker = tracker
|
14
15
|
end
|
15
16
|
|
16
|
-
def request
|
17
|
-
|
17
|
+
def request!
|
18
|
+
http = build_http
|
19
|
+
|
20
|
+
request = build_request
|
21
|
+
log_request(request)
|
22
|
+
|
23
|
+
response = http.request(request)
|
24
|
+
log_response(response)
|
25
|
+
|
18
26
|
response.body
|
19
27
|
end
|
20
28
|
|
21
29
|
private
|
22
30
|
|
23
|
-
def
|
31
|
+
def build_http
|
32
|
+
http = Net::HTTP.new(@uri.host, @uri.port)
|
33
|
+
http.open_timeout = Correios::SRO.request_timeout
|
34
|
+
http
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_request
|
38
|
+
request = Net::HTTP::Post.new(@uri.path)
|
39
|
+
request.set_form_data(request_params)
|
40
|
+
request
|
41
|
+
end
|
42
|
+
|
43
|
+
def request_params
|
24
44
|
{
|
25
|
-
:Usuario =>
|
26
|
-
:Senha =>
|
27
|
-
:Tipo =>
|
28
|
-
:Resultado =>
|
29
|
-
:Objetos =>
|
45
|
+
:Usuario => @tracker.user,
|
46
|
+
:Senha => @tracker.password,
|
47
|
+
:Tipo => QUERY_TYPES[@tracker.query_type],
|
48
|
+
:Resultado => RESULT_MODES[@tracker.result_mode],
|
49
|
+
:Objetos => @tracker.object_numbers.join
|
30
50
|
}
|
31
51
|
end
|
52
|
+
|
53
|
+
def log_request(request)
|
54
|
+
message = format_message(request) do
|
55
|
+
message = with_line_break { "Correios-SRO-XML Request:" }
|
56
|
+
message << with_line_break { "POST #{URL}" }
|
57
|
+
end
|
58
|
+
|
59
|
+
Correios::SRO.log(message)
|
60
|
+
end
|
61
|
+
|
62
|
+
def log_response(response)
|
63
|
+
message = format_message(response) do
|
64
|
+
message = with_line_break { "Correios-SRO-XML Response:" }
|
65
|
+
message << with_line_break { "HTTP/#{response.http_version} #{response.code} #{response.message}" }
|
66
|
+
end
|
67
|
+
|
68
|
+
Correios::SRO.log(message)
|
69
|
+
end
|
70
|
+
|
71
|
+
def format_message(http)
|
72
|
+
message = yield
|
73
|
+
message << with_line_break { format_headers_for(http) } if Correios::SRO.log_level == :debug
|
74
|
+
message << with_line_break { http.body }
|
75
|
+
end
|
76
|
+
|
77
|
+
def format_headers_for(http)
|
78
|
+
# I'm using an empty block in each_header method for Ruby 1.8.7 compatibility.
|
79
|
+
http.each_header{}.map { |name, values| "#{name}: #{values.first}" }.join("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
def with_line_break
|
83
|
+
"#{yield}\n"
|
84
|
+
end
|
32
85
|
end
|
33
86
|
end
|
34
87
|
end
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Correios::SRO::Event do
|
5
|
+
let(:event) { Correios::SRO::Event.new }
|
6
|
+
|
7
|
+
[:receiver, :document, :comment].each do |method|
|
8
|
+
describe "##{method}=" do
|
9
|
+
it "strips string" do
|
10
|
+
event.send("#{method}=", " Texto. ")
|
11
|
+
event.send(method).should == "Texto."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -2,87 +2,87 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Correios::SRO::Parser do
|
5
|
-
describe "#
|
5
|
+
describe "#objects" do
|
6
6
|
let(:xml) { body_for :success_response_many_objects }
|
7
7
|
let(:parser) { Correios::SRO::Parser.new }
|
8
8
|
|
9
9
|
it "encodes from ISO-8859-1 to UTF-8" do
|
10
10
|
xml.should_receive(:backward_encode).with("UTF-8", "ISO-8859-1").and_return(xml)
|
11
|
-
parser.
|
11
|
+
parser.objects(xml)
|
12
12
|
end
|
13
13
|
|
14
14
|
["SI047624825BR", "SX104110463BR"].each do |number|
|
15
15
|
it "returns object number" do
|
16
|
-
|
17
|
-
|
16
|
+
objects = parser.objects(xml)
|
17
|
+
objects[number].number.should == number
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
context "returns event" do
|
22
|
-
before(:each) { @
|
22
|
+
before(:each) { @objects = parser.objects(xml) }
|
23
23
|
|
24
24
|
{ "SI047624825BR" => {
|
25
|
-
:
|
25
|
+
:type => "BDI",
|
26
26
|
:status => "01",
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
27
|
+
:date => "26/12/2011",
|
28
|
+
:hour => "15:22",
|
29
|
+
:description => "Entregue",
|
30
|
+
:receiver => "",
|
31
|
+
:document => "",
|
32
|
+
:comment => "?",
|
33
|
+
:place => "AC CENTRAL DE SAO PAULO",
|
34
|
+
:code => "01009972",
|
35
|
+
:city => "SAO PAULO",
|
36
|
+
:state => "SP",
|
37
37
|
:sto => "00024419"
|
38
38
|
},
|
39
39
|
"SX104110463BR" => {
|
40
|
-
:
|
40
|
+
:type => "BDE",
|
41
41
|
:status => "01",
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
42
|
+
:date => "08/12/2011",
|
43
|
+
:hour => "09:30",
|
44
|
+
:description => "Entregue",
|
45
|
+
:receiver => "",
|
46
|
+
:document => "",
|
47
|
+
:comment => "",
|
48
|
+
:place => "CEE JUNDIAI",
|
49
|
+
:code => "13211970",
|
50
|
+
:city => "JUNDIAI",
|
51
|
+
:state => "SP",
|
52
52
|
:sto => "74654209"
|
53
53
|
},
|
54
54
|
}.each do |number, first_event|
|
55
55
|
first_event.each do |attr, value|
|
56
56
|
it attr do
|
57
|
-
|
58
|
-
|
57
|
+
event = @objects[number].events.first
|
58
|
+
event.send(attr).should == value
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
context "returns destination" do
|
65
|
-
before(:each) { @
|
65
|
+
before(:each) { @objects = parser.objects(xml) }
|
66
66
|
|
67
67
|
{ "SI047624825BR" => {
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
68
|
+
:place => "CTE VILA MARIA",
|
69
|
+
:code => "02170975",
|
70
|
+
:city => "SAO PAULO",
|
71
|
+
:neighborhood => "PQ NOVO MUNDO",
|
72
|
+
:state => "SP"
|
73
73
|
},
|
74
74
|
"SX104110463BR" => {
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
75
|
+
:place => "CTE CAMPINAS",
|
76
|
+
:code => "13050971",
|
77
|
+
:city => "VALINHOS",
|
78
|
+
:neighborhood => "MACUCO",
|
79
|
+
:state => "SP"
|
80
80
|
},
|
81
|
-
}.each do |number,
|
82
|
-
|
81
|
+
}.each do |number, destinations|
|
82
|
+
destinations.each do |attr, value|
|
83
83
|
it attr do
|
84
|
-
|
85
|
-
|
84
|
+
destination = @objects[number].events[3].destination
|
85
|
+
destination.send(attr).should == value
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Correios::SRO::Tracker do
|
5
|
+
describe ".new" do
|
6
|
+
it "creates with default values" do
|
7
|
+
sro = Correios::SRO::Tracker.new
|
8
|
+
sro.query_type.should == :list
|
9
|
+
sro.result_mode.should == :last
|
10
|
+
sro.object_numbers.should == []
|
11
|
+
end
|
12
|
+
|
13
|
+
{ :user => "PRODIS",
|
14
|
+
:password => "pim321",
|
15
|
+
:query_type => :range,
|
16
|
+
:result_mode => :all
|
17
|
+
}.each do |attr, value|
|
18
|
+
context "when #{attr} is supplied" do
|
19
|
+
it "sets #{attr}" do
|
20
|
+
sro = Correios::SRO::Tracker.new(attr => value)
|
21
|
+
sro.send(attr).should == value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when #{attr} is supplied in a block" do
|
26
|
+
it "sets #{attr}" do
|
27
|
+
sro = Correios::SRO::Tracker.new { |t| t.send("#{attr}=", value) }
|
28
|
+
sro.send(attr).should == value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#get" do
|
35
|
+
around do |example|
|
36
|
+
Correios::SRO.configure { |config| config.log_enabled = false }
|
37
|
+
example.run
|
38
|
+
Correios::SRO.configure { |config| config.log_enabled = true }
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:sro) { Correios::SRO::Tracker.new(:user => "PRODIS", :password => "pim321") }
|
42
|
+
|
43
|
+
context "to many objects" do
|
44
|
+
before(:each) { mock_request_for(:success_response_many_objects) }
|
45
|
+
|
46
|
+
it "sets objects numbers" do
|
47
|
+
sro.get("SI047624825BR", "SX104110463BR")
|
48
|
+
sro.object_numbers.size.should == 2
|
49
|
+
sro.object_numbers.first.should == "SI047624825BR"
|
50
|
+
sro.object_numbers.last.should == "SX104110463BR"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "creates a WebService with correct params" do
|
54
|
+
web_service = Correios::SRO::WebService.new(sro)
|
55
|
+
Correios::SRO::WebService.should_receive(:new).with(sro).and_return(web_service)
|
56
|
+
sro.get("SI047624825BR", "SX104110463BR")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns all objects" do
|
60
|
+
objects = sro.get("SI047624825BR", "SX104110463BR")
|
61
|
+
objects.size.should == 2
|
62
|
+
objects["SI047624825BR"].number.should == "SI047624825BR"
|
63
|
+
objects["SX104110463BR"].number.should == "SX104110463BR"
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when only one object found" do
|
67
|
+
before(:each) { mock_request_for(:success_response_one_object) }
|
68
|
+
|
69
|
+
it "returns a Hash" do
|
70
|
+
objects = sro.get("SI047624825BR", "SX104110463BR")
|
71
|
+
objects.should be_an_instance_of Hash
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns the object found" do
|
75
|
+
objects = sro.get("SI047624825BR", "SX104110463BR")
|
76
|
+
objects.size.should == 1
|
77
|
+
objects["SI047624825BR"].number.should == "SI047624825BR"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns nil in object not found" do
|
81
|
+
objects = sro.get("SI047624825BR", "SX104110463BR")
|
82
|
+
objects["SX104110463BR"].should be_nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "to one object" do
|
88
|
+
before(:each) { mock_request_for(:success_response_one_object) }
|
89
|
+
|
90
|
+
it "sets object number" do
|
91
|
+
sro.get("SI047624825BR")
|
92
|
+
sro.object_numbers.size.should == 1
|
93
|
+
sro.object_numbers.first.should == "SI047624825BR"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "creates a WebService with correct params" do
|
97
|
+
web_service = Correios::SRO::WebService.new(sro)
|
98
|
+
Correios::SRO::WebService.should_receive(:new).with(sro).and_return(web_service)
|
99
|
+
sro.get("SI047624825BR")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns only one object" do
|
103
|
+
object = sro.get("SI047624825BR")
|
104
|
+
object.number.should == "SI047624825BR"
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when object not found" do
|
108
|
+
it "returns nil" do
|
109
|
+
mock_request_for(:failure_response_not_found)
|
110
|
+
object = sro.get("SI047624825BR")
|
111
|
+
object.should be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|