summaryrefslogtreecommitdiffstats
path: root/test/browser.test.js
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:37:47 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:37:47 -0300
commitc4032605e0833a4c74d9bf58e679a83349ce9fb1 (patch)
tree224fb5c07276e0be9890b04a2207b6916ac62cf8 /test/browser.test.js
parent36486007ccada8c31d30e8f528d21233cabce32c (diff)
downloadautofill-7a25be0554c1f680a4af833253738c45b5ef9afc.tar.gz
Name the municipality behind a CEP that does not existHEADv0.2.0main
A CEP lookup that fails is rarely a random number: it is usually someone who knows the city and guessed the last digits, most often the -000 that 957 municipalities never received. The API now answers those 404s with a `faixa` naming the municipality the number would have belonged to and the first and last CEP that really exist there, so the shopper can be told "esse número seria de Areal/RJ" instead of a bare "não encontrado". It stays an error. The address does not exist, so no field is filled from `faixa` — quietly writing the city of a CEP that does not exist would produce a wrong address, which is worse than an empty form. Only the wording of the message changes. The range is sparse (Areal has 118 CEPs over some 4,900 numbers), so it is shown as a hint of where to look, never as a list to pick from. Parsing is defensive throughout: a body that is not JSON, a `faixa` that is not an object, a missing localidade or uf, a malformed range — each falls back to the message shipped before, and none of it can throw.
Diffstat (limited to 'test/browser.test.js')
-rw-r--r--test/browser.test.js117
1 files changed, 115 insertions, 2 deletions
diff --git a/test/browser.test.js b/test/browser.test.js
index 634df0d..afbfb2c 100644
--- a/test/browser.test.js
+++ b/test/browser.test.js
@@ -68,6 +68,22 @@ function events() {
return page.evaluate(() => window.__events);
}
+function lastError() {
+ return page.evaluate(() => window.__error);
+}
+
+/** Every field the fixture maps, so a test can prove none of them was written. */
+async function filledFields() {
+ const filled = {};
+ for (const selector of ["#rua", "#bairro", "#cidade", "#uf", "#numero"]) {
+ const current = await value(selector);
+ if (current !== "") {
+ filled[selector] = current;
+ }
+ }
+ return filled;
+}
+
async function waitForRequests(count, timeout = 4000) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
@@ -209,8 +225,10 @@ describe("errors", () => {
document.querySelector(".cepis-autofill-status").textContent.includes("não encontrado"),
);
- expect(await statusText()).toContain("CEP não encontrado");
- expect(await value("#rua")).toBe("");
+ expect(await statusText()).toBe(
+ "CEP não encontrado. Confira o número ou preencha o endereço manualmente.",
+ );
+ expect(await filledFields()).toEqual({});
expect(await events()).toContain("error:not_found");
});
@@ -256,6 +274,101 @@ describe("errors", () => {
});
});
+describe("the municipality behind a CEP that does not exist", () => {
+ async function lookFor(cep) {
+ await open();
+ await typeCep(cep);
+ await page.waitForFunction(() =>
+ document.querySelector(".cepis-autofill-status").textContent.includes("não encontrado"),
+ );
+ }
+
+ test("the message names the city and where its CEPs start and end", async () => {
+ await lookFor("25845000");
+
+ expect(await statusText()).toBe(
+ "CEP não encontrado. Esse número seria de Areal/RJ, " +
+ "que tem CEPs de 25845-001 a 25849-899.",
+ );
+ expect(await events()).toContain("error:not_found");
+ });
+
+ test("naming the city fills nothing — it is a failure, not an address", async () => {
+ await lookFor("25845000");
+
+ expect(await filledFields()).toEqual({});
+ expect(await events()).not.toContain("result:25845000");
+ expect(await page.locator("#cep").getAttribute("aria-invalid")).toBe("true");
+ });
+
+ test("the faixa reaches onError, whole", async () => {
+ await lookFor("25845000");
+
+ const error = await lastError();
+ expect(error.code).toBe("not_found");
+ expect(error.faixa).toEqual({
+ localidade: "Areal",
+ uf: "RJ",
+ estado: "Rio de Janeiro",
+ regiao: "Sudeste",
+ ibge: "3300225",
+ cep_ini: "25845001",
+ cep_fim: "25849899",
+ ceps: 118,
+ });
+ });
+
+ test("a CEP in no municipality keeps the plain message", async () => {
+ await lookFor("99999999");
+
+ expect(await statusText()).toBe(
+ "CEP não encontrado. Confira o número ou preencha o endereço manualmente.",
+ );
+ expect(await filledFields()).toEqual({});
+ expect((await lastError()).faixa).toBeUndefined();
+ });
+
+ test("a malformed faixa falls back to the plain message", async () => {
+ await lookFor("25845999");
+
+ expect(await statusText()).toBe(
+ "CEP não encontrado. Confira o número ou preencha o endereço manualmente.",
+ );
+ expect(await filledFields()).toEqual({});
+ expect((await lastError()).faixa).toBeUndefined();
+ });
+
+ test("the wording is overridable like every other message", async () => {
+ await open({
+ messages: { not_found_city_range: "Nada aqui. Tente um CEP de {localidade} ({uf})." },
+ });
+ await typeCep("25845000");
+ await page.waitForFunction(() =>
+ document.querySelector(".cepis-autofill-status").textContent.includes("Nada aqui"),
+ );
+
+ expect(await statusText()).toBe("Nada aqui. Tente um CEP de Areal (RJ).");
+ expect(await filledFields()).toEqual({});
+ });
+
+ test("lookup() hands the faixa over without touching the form", async () => {
+ await open();
+ const thrown = await page.evaluate(async (baseUrl) => {
+ try {
+ await window.CepisAutofill.lookup("25845-000", { baseUrl });
+ return null;
+ } catch (error) {
+ return { code: error.code, message: error.message, localidade: error.faixa.localidade };
+ }
+ }, api.url);
+
+ expect(thrown.code).toBe("not_found");
+ expect(thrown.message).toContain("Areal/RJ");
+ expect(thrown.localidade).toBe("Areal");
+ expect(await filledFields()).toEqual({});
+ });
+});
+
describe("what the shopper typed", () => {
test("overwrite: false leaves a filled field alone", async () => {
await open({ overwrite: false });