brcep 2.0.10 → 2.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 usa o webservice da http://www.bronzebusiness.com.br/webservices/wscep.asmx para
5
- #realizar as consultas de cep, então, somente funcionará para serviços com acesso a internet e
6
- #disponibilidade do serviço da Bronze Business.
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(22640010) ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
11
- # BuscaEndereco.por_cep('22640010') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
12
- # BuscaEndereco.por_cep('22640-010') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
13
- # BuscaEndereco.por_cep('22.640-010') ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
14
- # BuscaEndereco.por_cep('00000000') ==> RuntimeError 'Cep 00000000 não encontrado.'
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
- URL_WEB_SERVICE = 'http://www.bronzebusiness.com.br/webservices/wscep.asmx/cep?strcep=' #:nodoc:
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 para cep inexistente.
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(22640010) ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
38
+ # BuscaEndereco.por_cep(22640100) ==> ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', 22640100]
29
39
  def self.por_cep(numero)
30
- cep = numero.to_s.gsub(/\./, '').gsub(/\-/, '').to_i
31
- response = Net::HTTP.Proxy(self.proxy_addr,self.proxy_port).get_response(URI.parse("#{URL_WEB_SERVICE}#{cep}"))
32
-
33
- raise "Não foi possível obter o cep. (#{response.code} - #{response.message})" unless response.kind_of?(Net::HTTPSuccess)
34
-
35
- doc = REXML::Document.new(response.body)
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
- %w(logradouro nome bairro UF cidade).each do |e|
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
- retorno << elemento.text
43
- end
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
- retorno << cep
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
@@ -4,6 +4,6 @@ module BrCep
4
4
 
5
5
 
6
6
 
7
- STRING = "2.0.10"
7
+ STRING = "2.0.11"
8
8
  end
9
9
  end
@@ -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.640-100', '22.640-100']
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 test_raise_witout_service
27
- http_response = MockServerError.new
28
- Net::HTTP.expects(:get_response).returns(http_response)
29
- assert_raise RuntimeError, "Não foi possível obter o cep. (505 - HTTPServiceUnaviable)" do
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
- mock_get_response('invalid')
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 test_valid_code
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
- mock_get_response(limpa_cep(valid_zip))
46
- assert_equal ['Avenida', 'das Americas', 'Barra da Tijuca', 'RJ', 'Rio de Janeiro', limpa_cep(valid_zip)], BuscaEndereco.por_cep(valid_zip)
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 mock_get_response(zip_number)
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
- http_response = MockSuccess.new
56
- http_response.expects(:body).returns(xml_data)
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
- Net::HTTP.expects(:get_response).returns(http_response)
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>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1"?>
2
+ <webservicecep><resultado>-1</resultado><resultado_txt>cep nao encontrado</resultado_txt><cep>12345678</cep></webservicecep>
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.10
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-09-24 00:00:00 -03:00
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