Testar e diagnosticar código gerado
Código gerado por IA precisa de testes antes de ir para produção. Estes testes não chamam o SharkPay real nem movimentam dinheiro: usam respostas simuladas fiéis ao contrato.
Testes automatizados (Node.js, sem dependências)
import test from 'node:test';
import assert from 'node:assert/strict';
import { createHmac, timingSafeEqual } from 'node:crypto';
// --- código sob teste (o que a IA gerou) ---
export function verificar(segredo, cabecalho, corpoBruto, agora = Math.floor(Date.now() / 1000)) {
const p = Object.fromEntries(cabecalho.split(',').map(kv => kv.split('=')));
if (!p.t || !p.v1 || Math.abs(agora - Number(p.t)) > 300) return false;
const esperado = createHmac('sha256', segredo).update(`${p.t}.${corpoBruto}`).digest('hex');
const a = Buffer.from(esperado), b = Buffer.from(p.v1);
return a.length === b.length && timingSafeEqual(a, b);
}
export async function criarPix(fetchImpl, pedido) {
const chave = `pix-${pedido.id}`;
for (let i = 0; i < 3; i++) {
const r = await fetchImpl('/api/pix/create', { method: 'POST', headers: { 'Idempotency-Key': chave }, body: JSON.stringify(pedido.corpo) });
if (r.status < 500) return r;
}
throw new Error('falhou');
}
// --- testes ---
const corpo = '{"id":"evt_test","type":"ping"}';
const sig = t => `t=${t},v1=${createHmac('sha256', 'whsec_x').update(`${t}.${corpo}`).digest('hex')}`;
test('aceita assinatura válida', () => assert.ok(verificar('whsec_x', sig(1700000000), corpo, 1700000010)));
test('rejeita corpo alterado', () => assert.ok(!verificar('whsec_x', sig(1700000000), corpo + ' ', 1700000010)));
test('rejeita segredo errado', () => assert.ok(!verificar('outro', sig(1700000000), corpo, 1700000010)));
test('rejeita replay antigo', () => assert.ok(!verificar('whsec_x', sig(1700000000), corpo, 1700001000)));
test('repete com a MESMA Idempotency-Key após 500', async () => {
const chaves = [];
const falso = async (_u, init) => { chaves.push(init.headers['Idempotency-Key']); return { status: chaves.length < 2 ? 500 : 200 }; };
const r = await criarPix(falso, { id: 'PED-1', corpo: {} });
assert.equal(r.status, 200);
assert.deepEqual(chaves, ['pix-PED-1', 'pix-PED-1']);
});Rode com node --test. Adicione casos para 401 (renovar token), 429 (respeitar Retry-After), 422 (não repetir) e evento duplicado.
Checklist de revisão do código gerado
| Verifique | Por quê |
|---|---|
| Todas as rotas existem no OpenAPI | Modelos inventam endpoints (ex.: /api/refund). |
| Segredos só em variáveis de ambiente | Evita vazamento em repositório/log. |
| Idempotency-Key estável por pedido | Retentativa não duplica cobrança. |
| Backoff + máximo de tentativas | Evita tempestade de requisições e 429. |
| Assinatura sobre o corpo bruto, tempo constante, tolerância | Evita falsificação e replay. |
| Valores como string decimal / inteiro em centavos | Float causa erros de arredondamento. |
| Pagamento confirmado por webhook/consulta | O redirecionamento do cliente pode ser forjado. |
| Sem log de cartão, token ou chave | Conformidade e segurança. |
Guia de diagnóstico
- Reproduza com cURL. Rode a mesma chamada do exemplo oficial. Se funciona, o erro está no código gerado.
- Compare com o OpenAPI. Rota, método, nomes e tipos dos campos. Campo extra/faltando costuma ser a causa de 422.
- Leia error e code (veja Erros) — não só o status HTTP.
- Webhook: consulte GET /api/webhook/deliveries (last_status, last_error) e teste a assinatura com o vetor oficial.
- Peça à IA para corrigir com evidência: cole a requisição (sem segredos), a resposta e o trecho do OpenAPI correspondente.
Compatibilidade com versões futuras
- Fixe no seu projeto a versão do OpenAPI usada na geração (campo info.version, hoje 2026-10-14) e o cabeçalho/campo api_version dos webhooks.
- Seja tolerante: ignore campos desconhecidos e valores novos de enumerações.
- Acompanhe o changelog; mudanças incompatíveis são avisadas e marcadas ali.
- Reexecute os testes acima a cada atualização da especificação.