brcep 2.0.10 → 2.0.11
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/lib/brcep/busca_endereco.rb +62 -25
- data/lib/brcep/version.rb +1 -1
- data/test/busca_endereco_test.rb +98 -20
- data/test/mocks/zip_20230024_buscar_cep.xml +2 -0
- data/test/mocks/zip_22640100_bronze_business.xml +33 -0
- data/test/mocks/zip_22640100_buscar_cep.xml +12 -0
- data/test/mocks/zip_not_found_bronze_business.xml +23 -0
- data/test/mocks/zip_not_found_buscar_cep.xml +2 -0
- metadata +7 -2
data/lib/brcep/busca_endereco.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'rexml/document'
|
3
|
+
require 'active_support'
|
4
|
+
require 'brstring'
|
3
5
|
|
4
|
-
#Este recurso
|
5
|
-
#
|
6
|
-
#
|
6
|
+
# Este recurso tem como finalidade encontrar um endereço através de um CEP, e
|
7
|
+
# para isso ele utiliza o web service da Bronze Business (http://www.bronzebusiness.com.br/webservices/wscep.asmx)
|
8
|
+
# e o web service do Buscar CEP (http://www.buscarcep.com.br). O segundo só é utilizado quando
|
9
|
+
# o primeiro está indisponível ou quando ele não encontra o endereço associado ao CEP informado.
|
10
|
+
# Obviamente, para utilizar este serviço é necessário uma conexão com a Internet.
|
7
11
|
#
|
8
12
|
#Como fazer a busca de endereço por cep?
|
9
13
|
#
|
10
|
-
# BuscaEndereco.por_cep(
|
11
|
-
# BuscaEndereco.por_cep('
|
12
|
-
# BuscaEndereco.por_cep('22640-
|
13
|
-
# BuscaEndereco.por_cep('22.640-
|
14
|
-
# BuscaEndereco.por_cep('00000000') ==> RuntimeError '
|
14
|
+
# BuscaEndereco.por_cep(22640100) ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
|
15
|
+
# BuscaEndereco.por_cep('22640100') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
|
16
|
+
# BuscaEndereco.por_cep('22640-100') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
|
17
|
+
# BuscaEndereco.por_cep('22.640-100') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
|
18
|
+
# BuscaEndereco.por_cep('00000000') ==> RuntimeError 'O CEP informado possui um formato inválido.'
|
15
19
|
#
|
16
20
|
#Se necessário usar proxy, faça (de preferência em environment.rb):
|
17
21
|
# BuscaEndereco.proxy_addr= 'endereco.do.proxy'
|
@@ -20,28 +24,61 @@ require 'rexml/document'
|
|
20
24
|
class BuscaEndereco
|
21
25
|
cattr_accessor :proxy_addr, :proxy_port
|
22
26
|
|
23
|
-
|
27
|
+
URL_WEB_SERVICE_BRONZE_BUSINESS = 'http://www.bronzebusiness.com.br/webservices/wscep.asmx/cep?strcep=' #:nodoc:
|
28
|
+
URL_WEB_SERVICE_BUSCAR_CEP = 'http://www.buscarcep.com.br/?cep=' #:nodoc:
|
29
|
+
|
30
|
+
# Elementos do XML retornado pelos web services
|
31
|
+
ELEMENTOS_XML_BRONZE_BUSINESS = %w(logradouro nome bairro UF cidade) #:nodoc:
|
32
|
+
ELEMENTOS_XML_BUSCAR_CEP = %w(tipo_logradouro logradouro bairro uf cidade) #:nodoc:
|
24
33
|
|
25
|
-
# Retorna um array com os dados de endereçamento para o cep informado ou um erro
|
34
|
+
# Retorna um array com os dados de endereçamento para o cep informado ou um erro quando o serviço está indisponível,
|
35
|
+
# quando o cep informado possui um formato inválido ou quando o endereço não foi encontrado.
|
26
36
|
#
|
27
37
|
# Exemplo:
|
28
|
-
# BuscaEndereco.por_cep(
|
38
|
+
# BuscaEndereco.por_cep(22640100) ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
|
29
39
|
def self.por_cep(numero)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
40
|
+
# to_i.to_s adicionado no fim para que o CEP '00000000' não passe pela exceção
|
41
|
+
raise "O CEP informado possui um formato inválido." if numero.to_s.gsub(/\./, '').gsub(/\-/, '').to_i.to_s.length != 8
|
42
|
+
|
43
|
+
@@cep = numero.to_s.gsub(/\./, '').gsub(/\-/, '').to_i
|
44
|
+
|
45
|
+
@@retorno = []
|
46
|
+
|
47
|
+
begin
|
48
|
+
usar_web_service_da_bronze_business
|
49
|
+
rescue
|
50
|
+
usar_web_service_do_buscar_cep
|
51
|
+
end
|
36
52
|
|
37
|
-
retorno
|
38
|
-
|
39
|
-
elemento = REXML::XPath.match(doc, "//#{e}").first
|
40
|
-
raise "Cep #{cep} não encontrado." if elemento.nil?
|
53
|
+
@@retorno << @@cep
|
54
|
+
end
|
41
55
|
|
42
|
-
|
43
|
-
|
56
|
+
private
|
57
|
+
|
58
|
+
def self.usar_web_service_da_bronze_business
|
59
|
+
@@response = Net::HTTP.Proxy(self.proxy_addr, self.proxy_port).get_response(URI.parse("#{URL_WEB_SERVICE_BRONZE_BUSINESS}#{@@cep}"))
|
60
|
+
raise "A busca de endereço por CEP através do web service da Bronze Business está indisponível." unless @@response.kind_of?(Net::HTTPSuccess)
|
61
|
+
|
62
|
+
@@doc = REXML::Document.new(@@response.body)
|
63
|
+
processar_xml ELEMENTOS_XML_BRONZE_BUSINESS
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.usar_web_service_do_buscar_cep
|
67
|
+
@@response = Net::HTTP.Proxy(self.proxy_addr, self.proxy_port).get_response(URI.parse("#{URL_WEB_SERVICE_BUSCAR_CEP}#{@@cep}&formato=xml"))
|
68
|
+
raise "A busca de endereço por CEP está indisponível no momento." unless @@response.kind_of?(Net::HTTPSuccess)
|
44
69
|
|
45
|
-
|
70
|
+
@@doc = REXML::Document.new(@@response.body)
|
71
|
+
processar_xml ELEMENTOS_XML_BUSCAR_CEP
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.processar_xml(elementos_do_xml)
|
75
|
+
elementos_do_xml.each do |e|
|
76
|
+
elemento = REXML::XPath.match(@@doc, "//#{e}").first
|
77
|
+
|
78
|
+
raise "CEP #{@@cep} não encontrado." if elemento.nil?
|
79
|
+
|
80
|
+
# Remove os acentos já que o Buscar Cep retorna o endereço com acento e a Bronze Business não
|
81
|
+
@@retorno << elemento.text.remover_acentos
|
82
|
+
end
|
46
83
|
end
|
47
|
-
end
|
84
|
+
end
|
data/lib/brcep/version.rb
CHANGED
data/test/busca_endereco_test.rb
CHANGED
@@ -3,9 +3,10 @@ require 'rubygems'
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'mocha'
|
5
5
|
|
6
|
-
|
7
6
|
INVALID_ZIPS = [0, '0', '00', '000', '0000', '00000', '000000', '0000000', '00000000']
|
8
|
-
VALID_ZIPS = [22640100, '22640100', '22.
|
7
|
+
VALID_ZIPS = [22640100, '22640100', '22.640100', '22640-100', '22.640-100']
|
8
|
+
VALID_CEPS_NOT_FOUND_ON_BRONZE_BUSINESS = [20230024, '20230024', '20.230024', '20230-024', '20.230-024']
|
9
|
+
ZIPS_WITH_NO_ADDRESS_ASSOCIATED = [12345678, '12345678', '12.345678', '12345-678', '12.345-678']
|
9
10
|
|
10
11
|
class MockSuccess < Net::HTTPSuccess
|
11
12
|
def initialize; end
|
@@ -23,39 +24,117 @@ def limpa_cep(numero)
|
|
23
24
|
end
|
24
25
|
|
25
26
|
class BuscaEnderecoTest < Test::Unit::TestCase
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
def test_raise_without_service_on_both_web_services
|
28
|
+
http_error_response = MockServerError.new
|
29
|
+
|
30
|
+
Net::HTTP.expects(:get_response).returns(http_error_response)
|
31
|
+
Net::HTTP.expects(:get_response).returns(http_error_response)
|
32
|
+
|
33
|
+
assert_raise RuntimeError, "A busca de endereço por CEP está indisponível no momento." do
|
30
34
|
BuscaEndereco.por_cep(VALID_ZIPS.first)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
34
38
|
def test_raise_for_invalid_zip_code
|
35
39
|
INVALID_ZIPS.each do |invalid_zip|
|
36
|
-
|
37
|
-
assert_raise RuntimeError, "Cep #{invalid_zip} não encontrado." do
|
40
|
+
assert_raise RuntimeError, "O CEP informado possui um formato inválido." do
|
38
41
|
BuscaEndereco.por_cep(invalid_zip)
|
39
42
|
end
|
40
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_valid_code_on_bronze_business
|
47
|
+
VALID_ZIPS.each do |valid_zip|
|
48
|
+
mock_get_response_from_bronze_business(limpa_cep(valid_zip))
|
49
|
+
|
50
|
+
assert_equal ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro',
|
51
|
+
limpa_cep(valid_zip)], BuscaEndereco.por_cep(valid_zip)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_valid_code_on_buscar_cep_when_bronze_business_is_unavailable
|
56
|
+
VALID_ZIPS.each do |valid_zip|
|
57
|
+
mock_get_response_from_buscar_cep_when_bronze_business_is_unavailable(limpa_cep(valid_zip))
|
58
|
+
|
59
|
+
assert_equal ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro',
|
60
|
+
limpa_cep(valid_zip)], BuscaEndereco.por_cep(valid_zip)
|
61
|
+
end
|
41
62
|
end
|
42
63
|
|
43
|
-
def
|
64
|
+
def test_valid_code_on_buscar_cep_when_address_not_found_on_bronze_business
|
65
|
+
VALID_CEPS_NOT_FOUND_ON_BRONZE_BUSINESS.each do |cep_not_found_on_bronze_business|
|
66
|
+
mock_get_response_from_buscar_cep_when_address_not_found_on_bronze_business(limpa_cep(cep_not_found_on_bronze_business))
|
67
|
+
|
68
|
+
assert_equal ['Rua', 'Washington Luis', 'Centro', 'RJ', 'Rio de Janeiro', limpa_cep(cep_not_found_on_bronze_business)],
|
69
|
+
BuscaEndereco.por_cep(cep_not_found_on_bronze_business)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_should_return_the_same_address_on_both_web_services
|
44
74
|
VALID_ZIPS.each do |valid_zip|
|
45
|
-
|
46
|
-
|
75
|
+
mock_get_response_from_bronze_business(limpa_cep(valid_zip))
|
76
|
+
mock_get_response_from_buscar_cep_when_bronze_business_is_unavailable(limpa_cep(valid_zip))
|
77
|
+
assert_equal BuscaEndereco.por_cep(valid_zip), BuscaEndereco.por_cep(valid_zip)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_raise_exception_when_search_for_zip_with_no_associated_address
|
82
|
+
ZIPS_WITH_NO_ADDRESS_ASSOCIATED.each do |zip_with_no_address_associated|
|
83
|
+
assert_raise RuntimeError, "CEP #{limpa_cep(zip_with_no_address_associated)} não encontrado." do
|
84
|
+
mock_get_response_when_theres_no_address_associated_with_zip
|
85
|
+
|
86
|
+
BuscaEndereco.por_cep(zip_with_no_address_associated)
|
87
|
+
end
|
47
88
|
end
|
48
89
|
end
|
49
90
|
|
50
91
|
private
|
51
92
|
|
52
|
-
def
|
53
|
-
xml_data = xml_data_from zip_name(zip_number)
|
93
|
+
def mock_get_response_from_bronze_business(zip_number)
|
94
|
+
xml_data = xml_data_from zip_name(zip_number, "bronze_business")
|
95
|
+
|
96
|
+
http_success_response = MockSuccess.new
|
97
|
+
http_success_response.expects(:body).returns(xml_data)
|
98
|
+
|
99
|
+
Net::HTTP.expects(:get_response).returns(http_success_response)
|
100
|
+
end
|
101
|
+
|
102
|
+
def mock_get_response_from_buscar_cep_when_bronze_business_is_unavailable(zip_number)
|
103
|
+
xml_data = xml_data_from zip_name(zip_number, "buscar_cep")
|
104
|
+
|
105
|
+
http_success_response = MockSuccess.new
|
106
|
+
http_success_response.expects(:body).returns(xml_data)
|
107
|
+
|
108
|
+
Net::HTTP.expects(:get_response).returns(http_success_response)
|
109
|
+
|
110
|
+
http_error_response = MockServerError.new
|
111
|
+
Net::HTTP.expects(:get_response).returns(http_error_response)
|
112
|
+
end
|
113
|
+
|
114
|
+
def mock_get_response_from_buscar_cep_when_address_not_found_on_bronze_business(zip_number)
|
115
|
+
xml_data_from_bronze_business = xml_data_from zip_name("not_found", "bronze_business")
|
116
|
+
xml_data_from_buscar_cep = xml_data_from zip_name(zip_number, "buscar_cep")
|
117
|
+
|
118
|
+
http_success_response_from_buscar_cep = MockSuccess.new
|
119
|
+
http_success_response_from_buscar_cep.expects(:body).returns(xml_data_from_buscar_cep)
|
120
|
+
Net::HTTP.expects(:get_response).returns(http_success_response_from_buscar_cep)
|
121
|
+
|
122
|
+
http_success_response_from_bronze_business = MockSuccess.new
|
123
|
+
http_success_response_from_bronze_business.expects(:body).returns(xml_data_from_bronze_business)
|
124
|
+
Net::HTTP.expects(:get_response).returns(http_success_response_from_bronze_business)
|
125
|
+
end
|
126
|
+
|
127
|
+
def mock_get_response_when_theres_no_address_associated_with_zip
|
128
|
+
xml_data_from_bronze_business = xml_data_from zip_name("not_found", "bronze_business")
|
129
|
+
xml_data_from_buscar_cep = xml_data_from zip_name("not_found", "buscar_cep")
|
54
130
|
|
55
|
-
|
56
|
-
|
131
|
+
http_success_response_from_buscar_cep = MockSuccess.new
|
132
|
+
http_success_response_from_buscar_cep.expects(:body).returns(xml_data_from_buscar_cep)
|
133
|
+
Net::HTTP.expects(:get_response).returns(http_success_response_from_buscar_cep)
|
57
134
|
|
58
|
-
|
135
|
+
http_success_response_from_bronze_business = MockSuccess.new
|
136
|
+
http_success_response_from_bronze_business.expects(:body).returns(xml_data_from_bronze_business)
|
137
|
+
Net::HTTP.expects(:get_response).returns(http_success_response_from_bronze_business)
|
59
138
|
end
|
60
139
|
|
61
140
|
def xml_data_from xml_mock
|
@@ -70,8 +149,7 @@ class BuscaEnderecoTest < Test::Unit::TestCase
|
|
70
149
|
xml_data
|
71
150
|
end
|
72
151
|
|
73
|
-
def zip_name(nome)
|
74
|
-
File.join(File.dirname(__FILE__), 'mocks', "zip_#{nome}.xml")
|
152
|
+
def zip_name(nome, web_service)
|
153
|
+
File.join(File.dirname(__FILE__), 'mocks', "zip_#{nome}_#{web_service}.xml")
|
75
154
|
end
|
76
|
-
end
|
77
|
-
|
155
|
+
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
<webservicecep><cep>20230024</cep><uf>RJ</uf><cidade>Rio de Janeiro</cidade><bairro>Centro</bairro><tipo_logradouro>Rua</tipo_logradouro><logradouro>Washington Lu�s</logradouro><resultado>1</resultado><resultado_txt>sucesso. cep encontrado</resultado_txt></webservicecep>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<DataSet xmlns="http://tempuri.org/">
|
3
|
+
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
4
|
+
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
|
5
|
+
<xs:complexType>
|
6
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
7
|
+
<xs:element name="tbCEP">
|
8
|
+
<xs:complexType>
|
9
|
+
<xs:sequence>
|
10
|
+
<xs:element name="logradouro" type="xs:string" minOccurs="0" />
|
11
|
+
<xs:element name="nome" type="xs:string" minOccurs="0" />
|
12
|
+
<xs:element name="bairro" type="xs:string" minOccurs="0" />
|
13
|
+
<xs:element name="UF" type="xs:string" minOccurs="0" />
|
14
|
+
<xs:element name="cidade" type="xs:string" minOccurs="0" />
|
15
|
+
</xs:sequence>
|
16
|
+
</xs:complexType>
|
17
|
+
</xs:element>
|
18
|
+
</xs:choice>
|
19
|
+
</xs:complexType>
|
20
|
+
</xs:element>
|
21
|
+
</xs:schema>
|
22
|
+
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
|
23
|
+
<NewDataSet xmlns="">
|
24
|
+
<tbCEP diffgr:id="tbCEP1" msdata:rowOrder="0">
|
25
|
+
<logradouro>Avenida</logradouro>
|
26
|
+
<nome>das Americas</nome>
|
27
|
+
<bairro>Barra da Tijuca</bairro>
|
28
|
+
<UF>RJ</UF>
|
29
|
+
<cidade>Rio de Janeiro</cidade>
|
30
|
+
</tbCEP>
|
31
|
+
</NewDataSet>
|
32
|
+
</diffgr:diffgram>
|
33
|
+
</DataSet>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1" ?>
|
2
|
+
|
3
|
+
<webservicecep>
|
4
|
+
<cep>22640100</cep>
|
5
|
+
<uf>RJ</uf>
|
6
|
+
<cidade>Rio de Janeiro</cidade>
|
7
|
+
<bairro>Barra da Tijuca</bairro>
|
8
|
+
<tipo_logradouro>Avenida</tipo_logradouro>
|
9
|
+
<logradouro>das Am�ricas</logradouro>
|
10
|
+
<resultado>1</resultado>
|
11
|
+
<resultado_txt>sucesso. cep encontrado</resultado_txt>
|
12
|
+
</webservicecep>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<DataSet xmlns="http://tempuri.org/">
|
3
|
+
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
4
|
+
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
|
5
|
+
<xs:complexType>
|
6
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
7
|
+
<xs:element name="tbCEP">
|
8
|
+
<xs:complexType>
|
9
|
+
<xs:sequence>
|
10
|
+
<xs:element name="logradouro" type="xs:string" minOccurs="0"/>
|
11
|
+
<xs:element name="nome" type="xs:string" minOccurs="0"/>
|
12
|
+
<xs:element name="bairro" type="xs:string" minOccurs="0"/>
|
13
|
+
<xs:element name="UF" type="xs:string" minOccurs="0"/>
|
14
|
+
<xs:element name="cidade" type="xs:string" minOccurs="0"/>
|
15
|
+
</xs:sequence>
|
16
|
+
</xs:complexType>
|
17
|
+
</xs:element>
|
18
|
+
</xs:choice>
|
19
|
+
</xs:complexType>
|
20
|
+
</xs:element>
|
21
|
+
</xs:schema>
|
22
|
+
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"/>
|
23
|
+
</DataSet>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brcep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Marcos Tapaj\xC3\xB3s"
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2008-
|
15
|
+
date: 2008-11-27 00:00:00 -02:00
|
16
16
|
default_executable:
|
17
17
|
dependencies: []
|
18
18
|
|
@@ -35,8 +35,13 @@ files:
|
|
35
35
|
- lib/brcep.rb
|
36
36
|
- test/busca_endereco_test.rb
|
37
37
|
- test/mocks
|
38
|
+
- test/mocks/zip_20230024_buscar_cep.xml
|
38
39
|
- test/mocks/zip_22640100.xml
|
40
|
+
- test/mocks/zip_22640100_bronze_business.xml
|
41
|
+
- test/mocks/zip_22640100_buscar_cep.xml
|
39
42
|
- test/mocks/zip_invalid.xml
|
43
|
+
- test/mocks/zip_not_found_bronze_business.xml
|
44
|
+
- test/mocks/zip_not_found_buscar_cep.xml
|
40
45
|
- test/test_helper.rb
|
41
46
|
has_rdoc: true
|
42
47
|
homepage: http://www.improveit.com.br/software_livre/brazilian_rails
|