summaryrefslogtreecommitdiffstats
path: root/tests/test-lookup.R
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:38:27 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:38:27 -0300
commit399eac351b1bc29d5047dbac96486c281be1b05c (patch)
tree81151d5bf139f07096a8f38313d64482250163c2 /tests/test-lookup.R
parent11d49bc25eb1643f1b742f9527212d8781f2e0de (diff)
downloadr-399eac351b1bc29d5047dbac96486c281be1b05c.tar.gz
Report the municipality a missing CEP would have belonged toHEADv0.2.0main
A CEP that fails a lookup is rarely a random number: it is usually someone who knows the city and guessed, and the classic guess is the -000 that 957 municipalities never received. The API now answers those 404s with a faixa naming the municipality that owns the band the number fell into, which is the difference between telling a user "invalid CEP" and "no such CEP in Areal/RJ". It is context for an error and never an address, so it rides on the cepis_not_found condition instead of turning the failure into a success, and cep_ini/cep_fim are the endpoints that exist rather than the range the Correios publish - the interval between them is sparse, which is what ceps counts. Parsing is deliberately unable to signal: a faixa that is null, an array, a string or half a body leaves a clean not-found behind, because the caller asked for the CEP, not for the decoration on its absence.
Diffstat (limited to 'tests/test-lookup.R')
-rw-r--r--tests/test-lookup.R99
1 files changed, 99 insertions, 0 deletions
diff --git a/tests/test-lookup.R b/tests/test-lookup.R
index 0223f4d..3ff4646 100644
--- a/tests/test-lookup.R
+++ b/tests/test-lookup.R
@@ -82,6 +82,105 @@ with_server(
}
)
+not_found_body <- function(faixa = NULL) {
+ body <- list(
+ erro = "cep_nao_encontrado",
+ mensagem = "CEP n\u00e3o existe na base do DNE"
+ )
+ if (!is.null(faixa)) {
+ body$faixa <- faixa
+ }
+ json(body)
+}
+
+# 25845000 is the DNE's own first number for Areal, and one of the 957 that
+# were never issued: the guess the faixa exists to answer.
+with_server(
+ list(route("/25845000", response(404L, not_found_body(AREAL_FAIXA)))),
+ function(client, server) {
+ condition <- check_condition(
+ "a CEP inside a municipality's range is still not found",
+ cep_lookup("25845000", client),
+ "cepis_not_found"
+ )
+ faixa <- condition$faixa
+ check("the condition carries the faixa", inherits(faixa, "cepis_faixa"))
+ check("the faixa names the municipality", identical(faixa$localidade, "Areal"))
+ check("the faixa carries the state", identical(faixa$uf, "RJ"))
+ check("the faixa carries the IBGE code", identical(faixa$ibge, "3300225"))
+ check("the faixa counts the CEPs that exist", identical(faixa$ceps, 118L))
+ check(
+ "the bounds are the CEPs that exist, unmasked",
+ identical(c(faixa$cep_ini, faixa$cep_fim), c("25845001", "25849899"))
+ )
+ check(
+ "the message names the municipality",
+ grepl("Areal/RJ", conditionMessage(condition), fixed = TRUE)
+ )
+ check("the faixa prints", length(capture.output(print(faixa))) == 2L)
+ check("a 404 with a faixa is not retried either", calls(server, "/25845000") == 1L)
+ }
+)
+
+with_server(
+ list(route("/99999999", response(404L, not_found_body()))),
+ function(client, server) {
+ condition <- check_condition(
+ "a CEP in a band nobody owns is not found too",
+ cep_lookup("99999999", client),
+ "cepis_not_found"
+ )
+ check("an omitted faixa is NULL", is.null(condition$faixa))
+ check("the CEP is still carried", identical(condition$cep, "99999999"))
+ check(
+ "the message claims no range",
+ !grepl("belongs to", conditionMessage(condition), fixed = TRUE)
+ )
+ }
+)
+
+# A faixa is decoration on an error. None of these may cost the caller the
+# error itself, which is the only thing it asked for.
+unusable <- list(
+ "a null faixa" = "{\"erro\":\"x\",\"faixa\":null}",
+ "an empty faixa" = "{\"erro\":\"x\",\"faixa\":{}}",
+ "a faixa that is an array" = "{\"erro\":\"x\",\"faixa\":[]}",
+ "a faixa that is a string" = "{\"erro\":\"x\",\"faixa\":\"Areal\"}",
+ "a faixa with no municipality" = "{\"erro\":\"x\",\"faixa\":{\"uf\":\"RJ\"}}",
+ "a faixa with an empty municipality" =
+ "{\"erro\":\"x\",\"faixa\":{\"localidade\":\"\",\"uf\":\"RJ\"}}",
+ "a truncated body" = "{\"erro\":\"cep_nao",
+ "a body that is not JSON at all" = "<html>captive portal</html>",
+ "an empty body" = ""
+)
+
+for (label in names(unusable)) {
+ with_server(
+ list(route("/99999999", response(404L, unusable[[label]]))),
+ function(client, server) {
+ condition <- check_condition(
+ paste0(label, " is still a clean cepis_not_found"),
+ cep_lookup("99999999", client),
+ "cepis_not_found"
+ )
+ check(paste0(label, " yields no faixa"), is.null(condition$faixa))
+ }
+ )
+}
+
+odd_count <- c(AREAL_FAIXA[names(AREAL_FAIXA) != "ceps"], list(ceps = "many"))
+with_server(
+ list(route("/25845000", response(404L, not_found_body(odd_count)))),
+ function(client, server) {
+ condition <- caught(cep_lookup("25845000", client))
+ check(
+ "an unreadable count does not lose the municipality",
+ identical(condition$faixa$localidade, "Areal")
+ )
+ check("an unreadable count reads as zero", identical(condition$faixa$ceps, 0L))
+ }
+)
+
with_server(
list(route("/01001000", response(200L, json(SE_ADDRESS)))),
function(client, server) {