diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:33:37 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:33:37 -0300 |
| commit | 487b4c5628c02130580c675925a1d64b09a5f6cb (patch) | |
| tree | 240338af0c2c246bb2c689464f63d70b1f27f240 /tests | |
| parent | 4a8c3b675df4b1a6b29904fc2af60605002a7f9e (diff) | |
| download | rust-487b4c5628c02130580c675925a1d64b09a5f6cb.tar.gz | |
A 404 from the API now brings a "faixa" naming the municipality the CEP
would have belonged to, and NotFound carries it. A CEP that fails is
rarely a random number: it is usually someone who knows the city and
guessed the digits, so naming the city turns a dead end into an answer
the caller can show.
It stays an error. The range it carries is the CEPs that actually exist
there, not the bounds the Correios publish — those start at the very CEP
that just failed — and it is sparse, which is what "ceps" measures. The
field is decoration on a failure, so parsing it is entirely defensive:
absent, null or malformed all yield None rather than costing a clean
not-found.
Breaking: NotFound gained a field, hence 0.2.0.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/api.rs | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/tests/api.rs b/tests/api.rs index c794687..349c951 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -25,6 +25,13 @@ const SE_ADDRESS: &str = r#"{ "ddd": "11", "siafi": "7107" }"#; +/// The `faixa` a 404 carries when the CEP falls inside a municipality. +/// +/// Areal/RJ, and the numbers are the real ones: 118 CEPs scattered over the +/// ~4,900 between the two ends, and a `cep_ini` one above the CEP being looked +/// up — the DNE's own start for Areal is `25845000`, which does not exist. +const FAIXA: &str = r#","faixa":{"localidade":"Areal","uf":"RJ","estado":"Rio de Janeiro","regiao":"Sudeste","ibge":"3300225","cep_ini":"25845001","cep_fim":"25849899","ceps":118}"#; + const CSV_HEADER: &str = "cep,logradouro,complemento,unidade,bairro,localidade,uf,estado,regiao,ibge,gia,ddd,siafi"; @@ -180,6 +187,12 @@ fn csv_body(rows: &[String]) -> String { format!("{}\n{}\n", CSV_HEADER, rows.join("\n")) } +/// A 404 body, with `extra` spliced in as further fields — a `faixa`, whole or +/// broken. +fn not_found_with(extra: &str) -> String { + format!(r#"{{"erro":"cep_nao_encontrado","mensagem":"CEP não existe na base do DNE"{extra}}}"#) +} + fn with_geo(precisao: &str, raio_m: i64) -> String { format!( r#"{{"cep":"01310100","logradouro":"Avenida Paulista","complemento":"","unidade":"","bairro":"Bela Vista","localidade":"São Paulo","uf":"SP","estado":"São Paulo","regiao":"Sudeste","ibge":"3550308","gia":"1004","ddd":"11","siafi":"7107","geo":{{"lat":-23.5,"lon":-46.6,"raio_m":{raio_m},"precisao":"{precisao}"}}}}"# @@ -295,8 +308,92 @@ fn not_found() { let err = server.client().lookup("99999999").unwrap_err(); - assert!(matches!(&err, Error::NotFound { cep } if cep == "99999999")); + assert!(matches!(&err, Error::NotFound { cep, .. } if cep == "99999999")); + assert!(!err.is_retriable()); + assert!(err.faixa().is_none()); + assert_eq!( + err.to_string(), + "CEP 99999999 does not exist in the DNE database" + ); +} + +#[test] +fn not_found_names_the_municipality_when_the_api_does() { + let server = Server::start(); + server.respond("/25845000", vec![Reply::new(404, ¬_found_with(FAIXA))]); + + let err = server.client().lookup("25845000").unwrap_err(); + let faixa = err.faixa().expect("faixa present"); + + assert_eq!(faixa.localidade, "Areal"); + assert_eq!(faixa.uf, "RJ"); + assert_eq!(faixa.estado, "Rio de Janeiro"); + assert_eq!(faixa.regiao, "Sudeste"); + assert_eq!(faixa.ibge, "3300225"); + assert_eq!(faixa.municipality(), "Areal/RJ"); + + // The ends are the CEPs that exist, not the Correios bounds: the published + // start for Areal is 25845000 — the CEP that just failed. + assert_eq!(faixa.cep_ini, "25845001"); + assert_eq!(faixa.cep_fim, "25849899"); + assert_eq!(faixa.ceps, 118); +} + +#[test] +fn a_faixa_is_still_a_not_found() { + let server = Server::start(); + server.respond("/25845000", vec![Reply::new(404, ¬_found_with(FAIXA))]); + + let err = server.client().lookup("25845000").unwrap_err(); + + assert!(matches!(&err, Error::NotFound { cep, .. } if cep == "25845000")); assert!(!err.is_retriable()); + assert_eq!( + err.to_string(), + "CEP 25845000 does not exist in the DNE database (it would be in Areal/RJ)" + ); +} + +#[test] +fn an_unreadable_faixa_does_not_cost_the_not_found() { + for broken in [ + r#","faixa":null"#, + r#","faixa":{}"#, + r#","faixa":[]"#, + r#","faixa":"Areal""#, + r#","faixa":{"uf":"RJ","ceps":118}"#, + ] { + let server = Server::start(); + server.respond("/25845000", vec![Reply::new(404, ¬_found_with(broken))]); + + let err = server.client().lookup("25845000").unwrap_err(); + + assert!( + matches!(&err, Error::NotFound { cep, .. } if cep == "25845000"), + "expected NotFound for {broken}, got {err:?}" + ); + assert!(err.faixa().is_none(), "expected no faixa for {broken}"); + } +} + +#[test] +fn a_faixa_missing_the_extras_still_names_the_municipality() { + let server = Server::start(); + server.respond( + "/25845000", + vec![Reply::new( + 404, + ¬_found_with(r#","faixa":{"localidade":"Areal"}"#), + )], + ); + + let err = server.client().lookup("25845000").unwrap_err(); + let faixa = err.faixa().expect("faixa present"); + + assert_eq!(faixa.localidade, "Areal"); + assert_eq!(faixa.uf, ""); + assert_eq!(faixa.cep_ini, ""); + assert_eq!(faixa.ceps, 0); } #[test] |