summaryrefslogtreecommitdiffstats
path: root/internal/app/fakes_test.go
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:46:40 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:46:40 -0300
commit83ce95cf10fd9e9d581362453c558239d37ae06e (patch)
treedcaf1e9258e1c55c2df19f6556e15c39eaf622bb /internal/app/fakes_test.go
parent3ca1d2c4370e8e79aba3940d5c8fe115960b75a8 (diff)
downloadtelegram-83ce95cf10fd9e9d581362453c558239d37ae06e.tar.gz
Name the municipality when the CEP does not existv0.2.0
Answering only "não encontrei" wastes the trip. A CEP that fails is almost never a random number: it is someone who knows the city and guessed the rest, most often at the "-000" that 957 municipalities never received. The API now names that municipality on the 404, so the reply names it too. It stays an answer to a failure. No 📮, no address block, and no CEP suggested from inside the range — the range is sparse (Areal's 118 CEPs span nearly five thousand numbers), so the reply gives the count and says so instead of letting the two ends read as a list of valid CEPs. cep.is/go v0.1.0 discards the 404 body, so internal/lookup reads it with one extra GET, on that path alone and never inside a retry. Everything that can go wrong there — a slow answer, broken JSON, a faixa naming no municipality — falls back to the reply the bot has always given. The wrapper goes away the day the library exposes the field.
Diffstat (limited to 'internal/app/fakes_test.go')
-rw-r--r--internal/app/fakes_test.go20
1 files changed, 18 insertions, 2 deletions
diff --git a/internal/app/fakes_test.go b/internal/app/fakes_test.go
index 011d4af..9281a53 100644
--- a/internal/app/fakes_test.go
+++ b/internal/app/fakes_test.go
@@ -182,12 +182,16 @@ func (f *fakeTelegram) pendingCount() int {
// fakeCEPIS is a real HTTP server speaking the cep.is native contract, with
// enough of it to exercise every branch the bot has: an address with a street
-// coordinate, one that is a whole municipality, a 404, a 400 and a 500.
+// coordinate, one that is a whole municipality, a 404 that names the
+// municipality the CEP would fall in, a 404 that does not, a 400 and a 500.
type fakeCEPIS struct {
server *httptest.Server
- mu sync.Mutex
+ mu sync.Mutex
+ // bodies are the 200s, missing are the 404s that carry a faixa, and
+ // statuses forces a status for a CEP regardless of the other two.
bodies map[string]string
+ missing map[string]string
statuses map[string]int
requests int
}
@@ -208,6 +212,14 @@ func newFakeCEPIS(t *testing.T) *fakeCEPIS {
`"unidade":"","bairro":"Centro","localidade":"Linhares","uf":"ES","estado":"Espírito Santo",` +
`"regiao":"Sudeste","ibge":"3203205","gia":"","ddd":"27","siafi":"5665"}`,
},
+ // 25845000 is the CEP the "-000" guess produces for Areal/RJ, which
+ // is coded street by street and never received that number: the
+ // municipality exists, the CEP does not.
+ missing: map[string]string{
+ "25845000": `{"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}}`,
+ },
statuses: map[string]int{
"50000000": http.StatusInternalServerError,
},
@@ -225,6 +237,7 @@ func (f *fakeCEPIS) handle(w http.ResponseWriter, r *http.Request) {
cep := strings.TrimPrefix(r.URL.Path, "/")
status, forced := f.statuses[cep]
body, known := f.bodies[cep]
+ absent, attributed := f.missing[cep]
f.mu.Unlock()
w.Header().Set("Content-Type", "application/json; charset=utf-8")
@@ -235,6 +248,9 @@ func (f *fakeCEPIS) handle(w http.ResponseWriter, r *http.Request) {
case known:
w.WriteHeader(http.StatusOK)
w.Write([]byte(body))
+ case attributed:
+ w.WriteHeader(http.StatusNotFound)
+ w.Write([]byte(absent))
case len(cep) != 8:
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(`{"erro":"cep_invalido","mensagem":"CEP deve ter 8 dígitos"}`))