summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:38:46 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:38:46 -0300
commit3506a69f15fdf1c1c80acec26e906e6f25eeff14 (patch)
tree626ddce348a635e91aa7a5d3f64f39e2ba374841 /test
parentef1e5586a47002a6f21f43871b5fcfdb2c60af5d (diff)
downloadfortran-3506a69f15fdf1c1c80acec26e906e6f25eeff14.tar.gz
Name the municipality behind a CEP that does not existHEADv0.2.0main
A CEP that fails is rarely a random number. It is usually someone who knows the city and guessed the digits, and the classic guess is the -000 that 957 municipalities never received. Answering that with a bare "not found" throws away what the API already knows: which municipality the number would have fallen under. The 404 now carries an optional faixa, and it is exposed the way geo already is — a derived type behind a logical flag on the address, because the API omits the block entirely rather than sending null. It stays a 404: found is still false and the status is still CEPIS_ERR_NOT_FOUND. The band is context for the failure, never an address. cep_ini and cep_fim are the smallest and largest CEP that actually exist there, not the bounds the Correios publish — the published start for Areal is 25845000, exactly the CEP that fails. The pair is not a list either: 118 CEPs over some 4,900 numbers, which is what ceps is for. Parsing is deliberately silent about every failure. A body that is not JSON, or a faixa that is absent, null, not an object or empty, leaves has_faixa false. Turning any of those into an invalid-response error would tell the caller to retry a CEP that will never exist.
Diffstat (limited to 'test')
-rw-r--r--test/test_cepis.f90106
1 files changed, 104 insertions, 2 deletions
diff --git a/test/test_cepis.f90 b/test/test_cepis.f90
index 348e9df..9f22deb 100644
--- a/test/test_cepis.f90
+++ b/test/test_cepis.f90
@@ -16,7 +16,7 @@ program test_cepis
use test_server
implicit none
- character(len=:), allocatable :: SE, PAULISTA, CITYWIDE, CSV_HEADER, HEALTH_BODY
+ character(len=:), allocatable :: SE, PAULISTA, CITYWIDE, AREAL, CSV_HEADER, HEALTH_BODY
integer :: passed, failed
type(c_ptr) :: server
character(len=:), allocatable :: base
@@ -48,6 +48,8 @@ program test_cepis
call test_malformed_geo_does_not_lose_the_address()
call test_new_api_field_does_not_break()
call test_not_found_is_not_retried()
+ call test_not_found_carries_the_band()
+ call test_faixa_never_costs_the_not_found()
call test_invalid_cep_never_leaves_the_machine()
call test_api_400_becomes_invalid_cep()
call test_response_that_is_not_json()
@@ -74,7 +76,7 @@ program test_cepis
call test_status_names_exist()
call server_stop(server)
- deallocate (SE, PAULISTA, CITYWIDE, CSV_HEADER, HEALTH_BODY, base)
+ deallocate (SE, PAULISTA, CITYWIDE, AREAL, CSV_HEADER, HEALTH_BODY, base)
write (output_unit, '(A)') ''
write (output_unit, '(A,I0,A,I0,A)') 'passed ', passed, ', failed ', failed, ''
@@ -102,6 +104,17 @@ contains
CITYWIDE = CITYWIDE//'"gia":"","ddd":"68","siafi":"0003","geo":{"lat":-9.9754,'
CITYWIDE = CITYWIDE//'"lon":-67.8249,"raio_m":21400,"precisao":"localidade"}}'
+ ! A 404 that carries the band. 25845000 is the DNE's own published
+ ! start for Areal and does not exist; the CEPs that do start at
+ ! 25845001, and the 118 of them are scattered over the ~4,900 numbers
+ ! up to 25849899.
+ AREAL = '{"erro":"cep_nao_encontrado",'
+ AREAL = AREAL//'"mensagem":"CEP n\u00e3o existe na base do DNE",'
+ AREAL = AREAL//'"faixa":{"localidade":"Areal","uf":"RJ",'
+ AREAL = AREAL//'"estado":"Rio de Janeiro","regiao":"Sudeste",'
+ AREAL = AREAL//'"ibge":"3300225","cep_ini":"25845001",'
+ AREAL = AREAL//'"cep_fim":"25849899","ceps":118}}'
+
CSV_HEADER = 'cep,logradouro,complemento,unidade,bairro,localidade,uf,'
CSV_HEADER = CSV_HEADER//'estado,regiao,ibge,gia,ddd,siafi'
@@ -457,8 +470,97 @@ contains
call check(status == CEPIS_ERR_NOT_FOUND, '404 becomes not found')
call check(server_count(server, '/99999999') == 1, '404 is not retried')
call check(len(message) > 0, 'not found explains itself')
+ call check(.not. address%has_faixa, 'a 404 with no faixa leaves has_faixa false')
end subroutine test_not_found_is_not_retried
+ !> A 404 that names the municipality the CEP would have belonged to.
+ !>
+ !> 25845-000 is the case the field exists for: the DNE's own published
+ !> start for Areal, and a number that does not exist. Someone who knows the
+ !> city guessed the `-000`, as they do in the 957 municipalities that never
+ !> received one.
+ subroutine test_not_found_carries_the_band()
+ type(cepis_client) :: client
+ type(cepis_address) :: address
+ character(len=:), allocatable :: message
+ integer :: status
+
+ call server_reset(server)
+ call server_respond(server, '/25845000', 404, AREAL, '')
+ call local_client(client)
+
+ call client%lookup('25845000', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'a faixa does not make the 404 a success')
+ call check(.not. address%found, 'the address is still not found')
+ call check(server_count(server, '/25845000') == 1, 'a 404 with a faixa is not retried')
+
+ call check(address%has_faixa, 'has_faixa is true when the block is present')
+ call check(address%faixa%localidade == 'Areal', 'faixa names the municipality')
+ call check(address%faixa%uf == 'RJ', 'faixa uf')
+ call check(address%faixa%estado == 'Rio de Janeiro', 'faixa estado')
+ call check(address%faixa%regiao == 'Sudeste', 'faixa regiao')
+ call check(address%faixa%ibge == '3300225', 'faixa ibge')
+ call check(index(message, 'Areal') > 0, 'the message names the municipality')
+
+ ! The bounds are the CEPs that exist, not the band the Correios
+ ! publish: the published start is 25845000, the CEP that just failed.
+ call check(address%faixa%cep_ini == '25845001', 'cep_ini is the smallest that exists')
+ call check(address%faixa%cep_fim == '25849899', 'cep_fim is the largest that exists')
+ call check(address%faixa%formatted_cep_ini() == '25845-001', 'cep_ini masks')
+ call check(address%faixa%formatted_cep_fim() == '25849-899', 'cep_fim masks')
+
+ ! And they are not a list: 118 CEPs over ~4,900 numbers.
+ call check(address%faixa%ceps == 118, 'ceps counts what actually exists')
+ call check(address%faixa%ceps < 4899, 'the range is sparser than its span')
+ end subroutine test_not_found_carries_the_band
+
+ !> Nothing about the faixa may turn a clean not-found into a failure.
+ subroutine test_faixa_never_costs_the_not_found()
+ type(cepis_client) :: client
+ type(cepis_address) :: address
+ character(len=:), allocatable :: message
+ integer :: status
+
+ call server_reset(server)
+ call local_client(client)
+
+ call server_respond(server, '/99999991', 404, &
+ '{"erro":"cep_nao_encontrado","faixa":null}', '')
+ call client%lookup('99999991', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'a null faixa is still a not found')
+ call check(.not. address%has_faixa, 'a null faixa is absent, not present and empty')
+
+ call server_respond(server, '/99999992', 404, &
+ '{"erro":"cep_nao_encontrado","faixa":"Areal"}', '')
+ call client%lookup('99999992', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'a faixa that is not an object still 404s')
+ call check(.not. address%has_faixa, 'a faixa that is not an object is dropped')
+
+ call server_respond(server, '/99999993', 404, &
+ '{"erro":"cep_nao_encontrado","faixa":{}}', '')
+ call client%lookup('99999993', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'an empty faixa still 404s')
+ call check(.not. address%has_faixa, 'a faixa with no municipality is no faixa')
+
+ call server_respond(server, '/99999994', 404, '<html>not found</html>', '')
+ call client%lookup('99999994', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'a 404 body that is not JSON still 404s')
+ call check(.not. address%has_faixa, 'an unparseable 404 body carries no faixa')
+
+ call server_respond(server, '/99999995', 404, '', '')
+ call client%lookup('99999995', address, status, message)
+ call check(status == CEPIS_ERR_NOT_FOUND, 'an empty 404 body still 404s')
+ call check(.not. address%has_faixa, 'an empty 404 body carries no faixa')
+
+ call server_respond(server, '/99999996', 404, &
+ '{"erro":"cep_nao_encontrado","faixa":{"localidade":"Areal",'// &
+ '"uf":"RJ","cep_ini":"25845001","cep_fim":"25849899"}}', '')
+ call client%lookup('99999996', address, status, message)
+ call check(address%has_faixa, 'a faixa missing its count is still worth having')
+ call check(address%faixa%ceps == 0, 'a missing count is zero, not a dropped block')
+ call check(address%faixa%estado == '', 'a missing string field is empty')
+ end subroutine test_faixa_never_costs_the_not_found
+
subroutine test_invalid_cep_never_leaves_the_machine()
type(cepis_client) :: client
type(cepis_address) :: address