From 36486007ccada8c31d30e8f528d21233cabce32c Mon Sep 17 00:00:00 2001 From: Murilo Ijanc Date: Sun, 26 Jul 2026 15:01:02 -0300 Subject: Initial import --- test/server.js | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 test/server.js (limited to 'test/server.js') diff --git a/test/server.js b/test/server.js new file mode 100644 index 0000000..720f4a0 --- /dev/null +++ b/test/server.js @@ -0,0 +1,171 @@ +/** + * A fake cep.is, stood up with `Bun.serve` so the browser tests never touch the + * network. Same shapes and status codes as the real API, plus the counters the + * tests assert on. + * + * @module + */ + +const ADDRESSES = { + "01001000": { + cep: "01001000", + logradouro: "Praça da Sé", + complemento: "lado ímpar", + unidade: "", + bairro: "Sé", + localidade: "São Paulo", + uf: "SP", + estado: "São Paulo", + regiao: "Sudeste", + ibge: "3550308", + gia: "1004", + ddd: "11", + siafi: "7107", + geo: { lat: -23.567202, lon: -46.649659, raio_m: 1084, precisao: "logradouro" }, + }, + 20040020: { + cep: "20040020", + logradouro: "Avenida Rio Branco", + complemento: "até 0999 - lado ímpar", + unidade: "", + bairro: "Centro", + localidade: "Rio de Janeiro", + uf: "RJ", + estado: "Rio de Janeiro", + regiao: "Sudeste", + ibge: "3304557", + gia: "", + ddd: "21", + siafi: "6001", + }, +}; + +const CORS = { + "Access-Control-Allow-Origin": "*", + "Content-Type": "application/json; charset=utf-8", +}; + +/** + * Start the fake API on an ephemeral port. + * + * The returned `state` is live: set `state.delays[cep]` to hold a response + * back, or `state.force` to `{status}` to make every route fail. `requests` + * lists every CEP asked for, and `aborted` counts the requests the browser + * dropped mid-flight. + * + * @returns {{url: string, state: {requests: string[], aborted: number, delays: Record, force: {status: number}|null}, reset: () => void, stop: () => void}} + */ +export function startApi() { + const state = { requests: [], aborted: 0, delays: {}, force: null }; + + const server = Bun.serve({ + port: 0, + hostname: "127.0.0.1", + async fetch(request) { + const path = new URL(request.url).pathname.slice(1); + state.requests.push(path); + request.signal.addEventListener("abort", () => { + state.aborted += 1; + }); + + const delay = state.delays[path] ?? 0; + if (delay > 0) { + await Bun.sleep(delay); + } + if (request.signal.aborted) { + return new Response(null, { status: 499 }); + } + + if (state.force) { + return new Response(JSON.stringify({ erro: "interno", mensagem: "falha interna" }), { + status: state.force.status, + headers: { + ...CORS, + ...(state.force.status === 429 ? { "Retry-After": "3" } : {}), + }, + }); + } + if (!/^\d{8}$/.test(path)) { + return new Response( + JSON.stringify({ erro: "cep_invalido", mensagem: "CEP deve ter 8 dígitos" }), + { status: 400, headers: CORS }, + ); + } + if (path === "88888888") { + return new Response(JSON.stringify({ erro: "interno", mensagem: "falha interna" }), { + status: 500, + headers: CORS, + }); + } + if (path === "77777777") { + return new Response(JSON.stringify({ erro: "limite", mensagem: "muitas consultas" }), { + status: 429, + headers: { ...CORS, "Retry-After": "3" }, + }); + } + const address = ADDRESSES[path]; + if (!address) { + return new Response( + JSON.stringify({ erro: "cep_nao_encontrado", mensagem: "CEP não existe na base do DNE" }), + { status: 404, headers: CORS }, + ); + } + return new Response(JSON.stringify(address), { status: 200, headers: CORS }); + }, + }); + + return { + url: `http://127.0.0.1:${server.port}`, + state, + reset() { + state.requests.length = 0; + state.aborted = 0; + state.delays = {}; + state.force = null; + }, + stop() { + server.stop(true); + }, + }; +} + +/** + * Serve the checkout fixture page together with a freshly built `