diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:37:09 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:37:09 -0300 |
| commit | a891657aa43d2aba06a6347dd2f94edd19afd6ba (patch) | |
| tree | b6369ed2c8485455f9c1aa707c1cd287cb8e7065 /test | |
| parent | 794f28199a4dde9d18ec711864336c96c58bb422 (diff) | |
| download | d-0.2.0.tar.gz | |
A 404 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. The API now attaches a faixa to the
not-found body naming the municipality that owns the range, so the caller
can say "no such CEP, but that range is Areal/RJ" instead of only "no".
It stays an error. Faixa hangs off CepNotFoundException, never off
Address, and parsing is deliberately lenient: an absent, malformed or
unnamed block yields a null Nullable, so reading the extra context can
never cost the caller the answer it already had.
cep_ini and cep_fim are the smallest and largest CEP that actually exist
there, not the bounds the Correios publish, and the range between them is
sparse — hence ceps, so nobody mistakes the pair for a list.
Diffstat (limited to 'test')
| -rw-r--r-- | test/cepis_test.d | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/test/cepis_test.d b/test/cepis_test.d index 3ced878..694da0f 100644 --- a/test/cepis_test.d +++ b/test/cepis_test.d @@ -16,7 +16,7 @@ module cepis_test; import core.sync.mutex : Mutex; import core.thread : Thread; import core.time : Duration, MonoTime, dur; -import std.algorithm : filter, map, startsWith; +import std.algorithm : canFind, filter, map, startsWith; import std.array : array, join; import std.conv : to; import std.exception : assertThrown; @@ -35,6 +35,22 @@ private enum string SE_ADDRESS = `{ "ddd": "11", "siafi": "7107" }`; +/** + * A 404 that knows which municipality the CEP would have belonged to. + * + * `25845000` is the DNE's own start for Areal and does not exist; the smallest + * one that does is `25845001`. Fixed here rather than fetched: production does + * not serve `faixa` yet, so a live call would pass for the wrong reason. + */ +private enum string AREAL_NOT_FOUND = `{ + "erro": "cep_nao_encontrado", "mensagem": "CEP não existe na base do DNE", + "faixa": { + "localidade": "Areal", "uf": "RJ", "estado": "Rio de Janeiro", + "regiao": "Sudeste", "ibge": "3300225", "cep_ini": "25845001", + "cep_fim": "25849899", "ceps": 118 + } +}`; + private enum string CSV_HEADER = "cep,logradouro,complemento,unidade,bairro,localidade,uf," ~ "estado,regiao,ibge,gia,ddd,siafi"; @@ -339,6 +355,87 @@ unittest assert(server.calledTimes("/99999999") == 1); } +@("a not-found says which municipality the cep would have belonged to") +unittest +{ + auto server = new TestServer(); + server.respond("/25845000", Reply(404, AREAL_NOT_FOUND)); + + auto client = server.client; + bool caught; + try + client.lookup("25845-000"); + catch (CepNotFoundException error) + { + caught = true; + assert(error.cep == "25845000"); + assert(!error.retriable); + assert(!error.faixa.isNull); + + const faixa = error.faixa.get; + assert(faixa.localidade == "Areal"); + assert(faixa.uf == "RJ"); + assert(faixa.estado == "Rio de Janeiro"); + assert(faixa.regiao == "Sudeste"); + assert(faixa.ibge == "3300225"); + assert(faixa.cep_ini == "25845001"); + assert(faixa.cep_fim == "25849899"); + assert(faixa.ceps == 118); + assert(error.msg.canFind("Areal/RJ")); + } + + assert(caught); + assert(server.calledTimes("/25845000") == 1); +} + +@("a not-found in a band nobody owns carries no faixa") +unittest +{ + auto server = new TestServer(); + server.respond("/99999999", Reply(404, + `{"erro":"cep_nao_encontrado","mensagem":"CEP não existe na base do DNE"}`)); + + auto client = server.client; + bool caught; + try + client.lookup("99999999"); + catch (CepNotFoundException error) + { + caught = true; + assert(error.faixa.isNull); + assert(error.msg.canFind("99999999")); + } + + assert(caught); +} + +@("a malformed faixa is still an ordinary not-found") +unittest +{ + foreach (content; [ + `{"erro":"cep_nao_encontrado","faixa":{}}`, + `{"erro":"cep_nao_encontrado","faixa":{"uf":"RJ"}}`, + `{"erro":"cep_nao_encontrado","faixa":"Areal"}`, + `{"erro":"cep_nao_encontrado","faixa":null}`, `<html>gateway</html>`, `` + ]) + { + auto server = new TestServer(); + server.respond("/99999999", Reply(404, content)); + + auto client = server.client; + bool caught; + try + client.lookup("99999999"); + catch (CepNotFoundException error) + { + caught = true; + assert(error.faixa.isNull); + } + + assert(caught); + } +} + @("an invalid cep never leaves the machine") unittest { |