summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:42:22 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:42:22 -0300
commitb6f876f8b0847c223f3310d3e5208d78982a13c1 (patch)
treefce85d75a2e491b6514a4ed7c42dca898f944cc5 /tests
parentcf5597871327dbff2c7c743672d696e7ff340c42 (diff)
downloadpascal-6637db2cb939c538c039b501ba9d827f07545208.tar.gz
Carry the municipality range on a not-found CEPHEADv0.2.0main
A CEP that fails is rarely a random number: it is usually someone who knows the city and guessed the last digits, and the classic guess is the -000 that 957 municipalities never received. The API now answers those 404s with a faixa block naming the municipality the number would have belonged to, which is enough to tell the user "no such CEP in Areal" instead of just "not found". It stays an error. ECepisNotFound carries the block as a TCepisFaixa and owns it, the same way an address owns its geo, so no shape of the response can turn a not-found into an address. Parsing is tolerant on purpose: a faixa that is absent, null, empty or unreadable leaves Faixa nil rather than costing the caller the clean not-found underneath. CepIni and CepFim are the first and the last CEP that actually exist in the municipality - not the bounds the Correios publish, whose start for Areal is the very CEP that just failed - and the range between them is sparse. That is what Ceps is for, and why the comments insist the pair is not a list.
Diffstat (limited to 'tests')
-rw-r--r--tests/TestCepis.pas203
1 files changed, 203 insertions, 0 deletions
diff --git a/tests/TestCepis.pas b/tests/TestCepis.pas
index 75a57ee..73c8639 100644
--- a/tests/TestCepis.pas
+++ b/tests/TestCepis.pas
@@ -34,6 +34,17 @@ const
SaoPaulo = 'S' + #$C3#$A3 + 'o Paulo';
PracaDaSe = 'Pra' + #$C3#$A7 + 'a da S' + #$C3#$A9;
+ {
+ A 404 as the API sends it for 25845-000: the CEP the Correios list as the
+ start of Areal's band and never allocated. The faixa places it, the status
+ still says the CEP does not exist.
+ }
+ ArealNotFound =
+ '{"erro":"cep_nao_encontrado","mensagem":"CEP n' + #$C3#$A3 +
+ '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}}';
+
CsvHeader = 'cep,logradouro,complemento,unidade,bairro,localidade,uf,' +
'estado,regiao,ibge,gia,ddd,siafi';
@@ -432,6 +443,10 @@ type
procedure NewApiFieldDoesNotBreak;
procedure NotFound;
procedure NotFoundIsNotRetried;
+ procedure NotFoundCarriesTheFaixa;
+ procedure NotFoundWithoutFaixaHasNone;
+ procedure UnusableFaixaStillLeavesACleanNotFound;
+ procedure FaixaKeepsTheMunicipalityWhenTheCountIsGarbage;
procedure InvalidCepNeverLeavesTheMachine;
procedure Api400BecomesInvalidCep;
procedure ResponseThatIsNotJson;
@@ -559,6 +574,163 @@ begin
AssertEquals(1, FServer.CallCount('/99999999'));
end;
+procedure TTestLookup.NotFoundCarriesTheFaixa;
+var
+ Address: TCepisAddress;
+ Raised, HasFaixa: Boolean;
+ Localidade, UF, Estado, Regiao, Ibge, CepIni, CepFim, Message: string;
+ Ceps: Int64;
+begin
+ FServer.Respond('/25845000', 404, ArealNotFound);
+ Raised := False;
+ HasFaixa := False;
+ Localidade := '';
+ UF := '';
+ Estado := '';
+ Regiao := '';
+ Ibge := '';
+ CepIni := '';
+ CepFim := '';
+ Message := '';
+ Ceps := 0;
+ Address := nil;
+ try
+ Address := FClient.Lookup('25845-000');
+ except
+ on E: ECepisNotFound do
+ begin
+ Raised := True;
+ Message := E.Message;
+ HasFaixa := E.HasFaixa;
+ if E.Faixa <> nil then
+ begin
+ Localidade := E.Faixa.Localidade;
+ UF := E.Faixa.UF;
+ Estado := E.Faixa.Estado;
+ Regiao := E.Faixa.Regiao;
+ Ibge := E.Faixa.Ibge;
+ CepIni := E.Faixa.CepIni;
+ CepFim := E.Faixa.CepFim;
+ Ceps := E.Faixa.Ceps;
+ end;
+ end;
+ end;
+ Address.Free;
+ AssertTrue('a faixa must not turn a not-found into an address', Raised);
+ AssertTrue('the faixa must be read', HasFaixa);
+ AssertEquals('Areal', Localidade);
+ AssertEquals('RJ', UF);
+ AssertEquals('Rio de Janeiro', Estado);
+ AssertEquals('Sudeste', Regiao);
+ AssertEquals('3300225', Ibge);
+ AssertTrue('cep_ini is the first CEP that exists, not the published bound',
+ CepIni = '25845001');
+ AssertEquals('25849899', CepFim);
+ AssertEquals(118, Ceps);
+ AssertTrue('the message must name the municipality',
+ Pos('Areal', Message) > 0);
+ AssertTrue('the message must still name the CEP',
+ Pos('25845000', Message) > 0);
+end;
+
+procedure TTestLookup.NotFoundWithoutFaixaHasNone;
+var
+ Address: TCepisAddress;
+ Raised, HasFaixa, FaixaIsNil: Boolean;
+begin
+ FServer.Respond('/99999999', 404,
+ '{"erro":"cep_nao_encontrado","mensagem":"CEP n' + #$C3#$A3 +
+ 'o existe na base do DNE"}');
+ Raised := False;
+ HasFaixa := True;
+ FaixaIsNil := False;
+ Address := nil;
+ try
+ Address := FClient.Lookup('99999999');
+ except
+ on E: ECepisNotFound do
+ begin
+ Raised := True;
+ HasFaixa := E.HasFaixa;
+ FaixaIsNil := E.Faixa = nil;
+ end;
+ end;
+ Address.Free;
+ AssertTrue('expected ECepisNotFound', Raised);
+ AssertFalse('a CEP in nobody''s band carries no faixa', HasFaixa);
+ AssertTrue('absent means nil, never an empty faixa', FaixaIsNil);
+end;
+
+procedure TTestLookup.UnusableFaixaStillLeavesACleanNotFound;
+const
+ Bodies: array[0..6] of string = (
+ '{"erro":"cep_nao_encontrado","faixa":null}',
+ '{"erro":"cep_nao_encontrado","faixa":{}}',
+ '{"erro":"cep_nao_encontrado","faixa":"Areal"}',
+ '{"erro":"cep_nao_encontrado","faixa":[{"localidade":"Areal"}]}',
+ '{"erro":"cep_nao_encontrado","faixa":{"uf":"RJ","ceps":118}}',
+ '{"erro":"cep_nao_encontrado","faixa":{"localidade":""}}',
+ '{"erro":"cep_nao_encontrado","faixa":{"localidade":"Areal"'
+ );
+var
+ Address: TCepisAddress;
+ Raised, HasFaixa: Boolean;
+ I: Integer;
+begin
+ for I := Low(Bodies) to High(Bodies) do
+ begin
+ FServer.Respond('/25845000', 404, Bodies[I]);
+ Raised := False;
+ HasFaixa := True;
+ Address := nil;
+ try
+ Address := FClient.Lookup('25845000');
+ except
+ on E: ECepisNotFound do
+ begin
+ Raised := True;
+ HasFaixa := E.HasFaixa;
+ end;
+ end;
+ Address.Free;
+ AssertTrue('body ' + IntToStr(I) + ' must still be a not-found', Raised);
+ AssertFalse('body ' + IntToStr(I) + ' must carry no faixa', HasFaixa);
+ end;
+end;
+
+procedure TTestLookup.FaixaKeepsTheMunicipalityWhenTheCountIsGarbage;
+var
+ Address: TCepisAddress;
+ Raised: Boolean;
+ Localidade: string;
+ Ceps: Int64;
+begin
+ FServer.Respond('/25845000', 404,
+ '{"erro":"cep_nao_encontrado","faixa":{"localidade":"Areal","uf":"RJ",' +
+ '"ceps":"muitos"}}');
+ Raised := False;
+ Localidade := '';
+ Ceps := -1;
+ Address := nil;
+ try
+ Address := FClient.Lookup('25845000');
+ except
+ on E: ECepisNotFound do
+ begin
+ Raised := True;
+ if E.Faixa <> nil then
+ begin
+ Localidade := E.Faixa.Localidade;
+ Ceps := E.Faixa.Ceps;
+ end;
+ end;
+ end;
+ Address.Free;
+ AssertTrue('expected ECepisNotFound', Raised);
+ AssertEquals('Areal', Localidade);
+ AssertEquals('an unreadable count falls back to 0', 0, Ceps);
+end;
+
procedure TTestLookup.InvalidCepNeverLeavesTheMachine;
var
Address: TCepisAddress;
@@ -1097,6 +1269,7 @@ type
published
procedure ExtractKeepsAnAddressAlive;
procedure ExtractGeoTransfersTheCoordinate;
+ procedure ExtractFaixaOutlivesTheError;
end;
procedure TTestOwnership.ExtractKeepsAnAddressAlive;
@@ -1137,6 +1310,36 @@ begin
end;
end;
+procedure TTestOwnership.ExtractFaixaOutlivesTheError;
+var
+ Address: TCepisAddress;
+ Faixa: TCepisFaixa;
+ StillOwned: Boolean;
+begin
+ FServer.Respond('/25845000', 404, ArealNotFound);
+ Faixa := nil;
+ StillOwned := True;
+ Address := nil;
+ try
+ Address := FClient.Lookup('25845000');
+ except
+ on E: ECepisNotFound do
+ begin
+ Faixa := E.ExtractFaixa;
+ StillOwned := E.HasFaixa;
+ end;
+ end;
+ Address.Free;
+ try
+ AssertFalse('the error no longer owns it', StillOwned);
+ AssertTrue('the faixa survives the handler', Faixa <> nil);
+ AssertEquals('Areal', Faixa.Localidade);
+ AssertEquals(118, Faixa.Ceps);
+ finally
+ Faixa.Free;
+ end;
+end;
+
var
Runner: TTestRunner;