Skip to content

feat(tests): suíte de integração LIVE para 82 edge functions + fuzz expandido + gate CI#380

Merged
adm01-debug merged 3 commits into
mainfrom
claude/e2e-integration-tests-2eyUd
May 26, 2026
Merged

feat(tests): suíte de integração LIVE para 82 edge functions + fuzz expandido + gate CI#380
adm01-debug merged 3 commits into
mainfrom
claude/e2e-integration-tests-2eyUd

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 26, 2026

Contexto

A missão pedia testes de integração para cada Edge Function (validando entradas/saídas, erros e status codes), CI bloqueante, relatórios de cobertura e fuzz. O repositório já tinha E2E/CI/coverage/fuzz maduros; a lacuna real era que 62 das 84 edge functions não tinham teste algum e o fuzz cobria só ~8 endpoints. Por decisão do solicitante, os testes de integração são LIVE (HTTP real contra as funções deployadas), com foco no núcleo das edge functions.

O que muda

Harness LIVE (tests/edge-functions/live/)

  • _live-client.ts — fetch real com timeout + retry em 5xx; describeLive faz skip silencioso sem credenciais (CI verde) e roda LIVE com VITE_SUPABASE_URL + VITE_SUPABASE_PUBLISHABLE_KEY; aquisição de JWT por role (E2E_USER/ADMIN/DEV_*).
  • _authz.ts — deriva a fronteira de auth do edge-authz-manifest.ts + do verify_jwt real de config.toml; marca funções DESTRUCTIVE (negative-only) e SUPPORTS_DRY_RUN.
  • _schemas.ts (zod) + _live-suite.ts (gerador de suíte) + descriptors.ts (conteúdo por função).
  • 1 arquivo por função → 82/82 cobertas, 672 casos. Cada spec valida: CORS preflight, fronteira de auth (anon→401/403 ou reach/sem-5xx), 6+ inputs malformados (sem crash silencioso), contrato de erro {code|error|message} e happy-path read-only/dry-run.

Segurança

Funções com efeito externo (envio, sync, cleanup, reset de senha, logout global, bloqueio de IP, churn de chave) são negative-only — happy-path suprimido (exceto dry_run). Validado contra o ambiente deployado: 672/672 passando, zero mutação.

Fuzz expandido

  • fuzz-testing.mjs: 8→20 endpoints (catálogo, busca, IA, webhooks/orquestradores) via helper fieldFuzz.
  • fuzz-edge-uploads.mjs: +analyze-logo-colors, visual-search, generate-mockup (URL/campo adversarial).

CI & cobertura

  • Gate check:edge-live-coverage (bloqueia merge se uma função deployada não tiver teste LIVE) + scaffolder gen-edge-live-tests.mjs.
  • Passos LIVE plugados em ci.yml (job integration-tests) e edge-integration-all.yml (skip sem segredos).
  • generate-coverage-report.mjs agora emite seção por edge function (edge-coverage-report.json).
  • Docs: docs/testing/EDGE_LIVE_TESTS.md; .env.e2e.example atualizado.

Plano de teste

  • npm run check:edge-live-coverage → 82/82 ✅
  • npm run test:edge:live sem credenciais → 672 skipped (suíte verde)
  • npm run test:edge:live LIVE contra deployment → 672/672 passing (sem 5xx, sem mutação)
  • node scripts/fuzz-testing.mjs (dry-run) → 761 payloads ✅ · fuzz-edge-uploads.mjs → 134 ✅
  • npm run lint:baseline → sem regressão de lint
  • CI com segredos (VITE_SUPABASE_*, E2E_*) para exercitar happy-paths

Notas

  • O gate typecheck acusa drift pré-existente em src/components/search/useGlobalSearch.ts (etapa 16 adiada no STATUS.md), não relacionado a este PR — nenhum arquivo de src/ foi tocado aqui.

https://claude.ai/code/session_01NKv93VdzWci9KLG98MMHNH


Generated by Claude Code


Summary by cubic

Adiciona suíte de integração LIVE cobrindo 82 edge functions com HTTP real (CORS, auth, validação e contrato de erro), amplia o fuzz para 20 endpoints e cria um gate de CI por cobertura LIVE. Também ajusta a tipagem dinâmica em useGlobalSearch, agora usando o helper untypedFrom do main, destravando o gate de typecheck.

  • New Features

    • Harness LIVE em tests/edge-functions/live/* (_live-client/_authz/_schemas/_live-suite) + descriptors.ts e gerador scripts/gen-edge-live-tests.mjs — 1 spec por função (82/82), 672 casos.
    • Valida CORS, fronteira de auth (manifest + verify_jwt), inputs malformados sem 5xx e contrato {code|error|message}; happy-path só em rotas seguras/dry-run. Destrutivas em negative-only; caminhos caros via EDGE_LIVE_COSTLY=1. Sem segredos, describeLive faz skip; com VITE_SUPABASE_URL + VITE_SUPABASE_PUBLISHABLE_KEY roda LIVE (JWT por role via @supabase/supabase-js).
    • Fuzz 8→20 endpoints com fieldFuzz, incluindo uploads/imagem (analyze-logo-colors, visual-search, generate-mockup).
  • CI & Coverage

    • Gate check:edge-live-coverage (exige tests/edge-functions/live/<fn>.test.ts), passos LIVE em .github/workflows/ci.yml e edge-integration-all.yml. Scripts: test:edge:live, test:edge:live:coverage, scripts/check-edge-live-coverage.mjs.
    • Relatório por função em coverage/edge-coverage-report.json via scripts/generate-coverage-report.mjs. Docs em docs/testing/EDGE_LIVE_TESTS.md e variáveis em .env.e2e.example.
    • Merge com main: resolve conflitos e passa a usar untypedFrom em src/components/search/useGlobalSearch.ts (builder tipado, sem any).

Written for commit a894a4d. Summary will update on new commits. Review in cubic

…xpandido + gate CI

- Harness tests/edge-functions/live/ (_live-client/_authz/_schemas/_live-suite)
  dirigido pelo edge-authz-manifest + verify_jwt de config.toml.
- 1 spec por função (82/82) via descriptors.ts: CORS, fronteira de auth,
  validação de input (sem-crash 5xx), contrato de erro {code|error|message}
  e happy-path read-only/dry-run. Destrutivas em negative-only.
- describeLive faz skip sem credenciais (CI verde); roda LIVE com segredos.
- Fuzz: 8→20 endpoints (catálogo/busca/IA/webhooks) + imagem/uploads.
- Gate check:edge-live-coverage (bloqueia merge) + passos LIVE em ci.yml e
  edge-integration-all.yml. Relatório de coverage por edge function.
- Docs: docs/testing/EDGE_LIVE_TESTS.md; .env.e2e.example atualizado.

https://claude.ai/code/session_01NKv93VdzWci9KLG98MMHNH
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@adm01-debug, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 19 minutes and 52 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f51c4a32-385c-4a68-a4ad-6217958f5544

📥 Commits

Reviewing files that changed from the base of the PR and between c625c5a and a894a4d.

📒 Files selected for processing (99)
  • .env.e2e.example
  • .github/workflows/ci.yml
  • .github/workflows/edge-integration-all.yml
  • STATUS.md
  • docs/testing/EDGE_LIVE_TESTS.md
  • package.json
  • scripts/check-edge-live-coverage.mjs
  • scripts/fuzz-edge-uploads.mjs
  • scripts/fuzz-testing.mjs
  • scripts/gen-edge-live-tests.mjs
  • scripts/generate-coverage-report.mjs
  • src/components/search/useGlobalSearch.ts
  • tests/edge-functions/live/_authz.ts
  • tests/edge-functions/live/_live-client.ts
  • tests/edge-functions/live/_live-suite.ts
  • tests/edge-functions/live/_schemas.ts
  • tests/edge-functions/live/ai-recommendations.test.ts
  • tests/edge-functions/live/analyze-logo-colors.test.ts
  • tests/edge-functions/live/bi-copilot.test.ts
  • tests/edge-functions/live/bitrix-sync.test.ts
  • tests/edge-functions/live/block-ip-temporarily.test.ts
  • tests/edge-functions/live/bulk-random-passwords.test.ts
  • tests/edge-functions/live/categories-api.test.ts
  • tests/edge-functions/live/cleanup-notifications.test.ts
  • tests/edge-functions/live/cleanup-novelties.test.ts
  • tests/edge-functions/live/cnpj-lookup.test.ts
  • tests/edge-functions/live/collections-watcher.test.ts
  • tests/edge-functions/live/commemorative-dates.test.ts
  • tests/edge-functions/live/comparison-ai-advisor.test.ts
  • tests/edge-functions/live/comparison-price-watcher.test.ts
  • tests/edge-functions/live/connection-tester.test.ts
  • tests/edge-functions/live/connections-auto-test.test.ts
  • tests/edge-functions/live/connections-health-check.test.ts
  • tests/edge-functions/live/connections-hub-audit.test.ts
  • tests/edge-functions/live/cors-audit.test.ts
  • tests/edge-functions/live/crm-db-bridge.test.ts
  • tests/edge-functions/live/descriptors.ts
  • tests/edge-functions/live/detect-new-device.test.ts
  • tests/edge-functions/live/dropbox-list.test.ts
  • tests/edge-functions/live/e2e-cleanup.test.ts
  • tests/edge-functions/live/elevenlabs-scribe-token.test.ts
  • tests/edge-functions/live/elevenlabs-tts.test.ts
  • tests/edge-functions/live/expert-chat.test.ts
  • tests/edge-functions/live/external-db-bridge.test.ts
  • tests/edge-functions/live/external-db-inspect.test.ts
  • tests/edge-functions/live/favorites-watcher.test.ts
  • tests/edge-functions/live/force-global-logout.test.ts
  • tests/edge-functions/live/full-op-diagnostics.test.ts
  • tests/edge-functions/live/generate-ad-image.test.ts
  • tests/edge-functions/live/generate-ad-prompt.test.ts
  • tests/edge-functions/live/generate-mockup.test.ts
  • tests/edge-functions/live/generate-product-seo.test.ts
  • tests/edge-functions/live/get-visitor-info.test.ts
  • tests/edge-functions/live/github-credentials-test.test.ts
  • tests/edge-functions/live/health-check.test.ts
  • tests/edge-functions/live/image-proxy.test.ts
  • tests/edge-functions/live/kit-ai-builder.test.ts
  • tests/edge-functions/live/kit-identity-suggest.test.ts
  • tests/edge-functions/live/log-login-attempt.test.ts
  • tests/edge-functions/live/magic-up-score.test.ts
  • tests/edge-functions/live/manage-users.test.ts
  • tests/edge-functions/live/market-intelligence-insights.test.ts
  • tests/edge-functions/live/materials-api.test.ts
  • tests/edge-functions/live/mcp-keys-issue.test.ts
  • tests/edge-functions/live/mcp-keys-revoke.test.ts
  • tests/edge-functions/live/mcp-keys-rotate.test.ts
  • tests/edge-functions/live/mcp-keys-update.test.ts
  • tests/edge-functions/live/mcp-server.test.ts
  • tests/edge-functions/live/ownership-audit.test.ts
  • tests/edge-functions/live/ownership-repair.test.ts
  • tests/edge-functions/live/process-queue.test.ts
  • tests/edge-functions/live/process-scheduled-reports.test.ts
  • tests/edge-functions/live/product-webhook.test.ts
  • tests/edge-functions/live/quote-followup-reminders.test.ts
  • tests/edge-functions/live/quote-sync.test.ts
  • tests/edge-functions/live/rate-limit-check.test.ts
  • tests/edge-functions/live/rls-audit.test.ts
  • tests/edge-functions/live/rls-integration-tests.test.ts
  • tests/edge-functions/live/rls-matrix-export.test.ts
  • tests/edge-functions/live/secrets-manager.test.ts
  • tests/edge-functions/live/secure-upload.test.ts
  • tests/edge-functions/live/semantic-search.test.ts
  • tests/edge-functions/live/send-digest.test.ts
  • tests/edge-functions/live/send-notification.test.ts
  • tests/edge-functions/live/send-scheduled-reports.test.ts
  • tests/edge-functions/live/send-transactional-email.test.ts
  • tests/edge-functions/live/simulation-orchestrator.test.ts
  • tests/edge-functions/live/step-up-verify.test.ts
  • tests/edge-functions/live/sync-external-db.test.ts
  • tests/edge-functions/live/sync-quote-bitrix.test.ts
  • tests/edge-functions/live/test-contract-orchestrator.test.ts
  • tests/edge-functions/live/test-inventory-orchestrator.test.ts
  • tests/edge-functions/live/trends-insights.test.ts
  • tests/edge-functions/live/validate-access.test.ts
  • tests/edge-functions/live/verify-email.test.ts
  • tests/edge-functions/live/visual-search.test.ts
  • tests/edge-functions/live/voice-agent.test.ts
  • tests/edge-functions/live/webhook-dispatcher.test.ts
  • tests/edge-functions/live/webhook-inbound.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/e2e-integration-tests-2eyUd

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Error Error May 26, 2026 12:25pm

@adm01-debug adm01-debug marked this pull request as ready for review May 26, 2026 02:28
Copilot AI review requested due to automatic review settings May 26, 2026 02:28
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Este PR introduz uma suíte de testes de integração LIVE (HTTP real) para as Edge Functions do Supabase, com um harness comum, descritores por função e um gate de CI para garantir que toda função deployada tenha ao menos um teste LIVE correspondente. Também expande os scripts de fuzz e adiciona um relatório de “cobertura” por presença de testes por edge function.

Changes:

  • Adiciona harness e gerador de suíte LIVE em tests/edge-functions/live/ + registro central de descritores (descriptors.ts) e shims <fn>.test.ts.
  • Inclui gates e execução no CI (check:edge-live-coverage + job steps de LIVE) e documentação para rodar local/CI.
  • Expande fuzz para mais endpoints e gera relatório de cobertura por edge function em coverage/edge-coverage-report.json.

Reviewed changes

Copilot reviewed 98 out of 98 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/edge-functions/live/_live-client.ts Cliente HTTP LIVE com env detection, timeout e retry para chamadas às Edge Functions.
tests/edge-functions/live/_authz.ts Derivação de expectativas de auth e classificação de funções destrutivas/dry-run.
tests/edge-functions/live/_schemas.ts Schemas zod reutilizáveis para validar envelopes de erro e respostas.
tests/edge-functions/live/_live-suite.ts Gerador da suíte padronizada (CORS, fronteira de auth, inválidos, happy-path).
tests/edge-functions/live/descriptors.ts Registro central de inputs/happy-paths e casos inválidos por função.
tests/edge-functions/live/*.test.ts Shims “1 arquivo por função” chamando runLiveSuite(descriptorFor(fn)).
scripts/check-edge-live-coverage.mjs Gate de CI que falha se existir edge function sem shim LIVE.
scripts/gen-edge-live-tests.mjs Scaffolder idempotente para criar shims LIVE por função.
scripts/generate-coverage-report.mjs Emite relatório adicional de cobertura por edge function (presença de testes).
scripts/fuzz-testing.mjs Expansão do fuzz (helper fieldFuzz + mais endpoints).
scripts/fuzz-edge-uploads.mjs Adiciona fuzz de campos/URLs adversariais em funções de imagem/uploads.
package.json Novos scripts test:edge:live* e check:edge-live-coverage.
.github/workflows/ci.yml Integra gate + execução de LIVE (com skip sem segredos).
.github/workflows/edge-integration-all.yml Integra gate + execução de LIVE (com skip sem segredos).
docs/testing/EDGE_LIVE_TESTS.md Documenta como rodar e a política de segurança (negative-only/dry-run).
.env.e2e.example Exemplo de vars para execução LIVE e tiers (E2E_*).
STATUS.md Atualiza status com a sessão/entregáveis de testes LIVE.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +124 to +150
let lastResult: EdgeResult | undefined;
for (let attempt = 0; attempt <= RETRY_COUNT; attempt++) {
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), opts.signalTimeoutMs ?? TIMEOUT_MS);
try {
const res = await fetch(url, {
method,
headers: finalHeaders,
body: rawBody,
signal: controller.signal,
});
const text = await res.text();
let json: unknown = null;
try {
json = text ? JSON.parse(text) : null;
} catch {
json = null;
}
lastResult = { status: res.status, headers: res.headers, text, json };
if (!RETRY_STATUSES.has(res.status) || attempt === RETRY_COUNT) return lastResult;
} finally {
clearTimeout(t);
}
await sleep(RETRY_DELAY_MS * (attempt + 1));
}
return lastResult!;
}
Comment on lines +107 to +109
if (body !== undefined && body !== null && !("Content-Type" in finalHeaders)) {
finalHeaders["Content-Type"] = "application/json";
}
Comment on lines +32 to +38
interface InvalidInput {
label: string;
body?: Body;
headers?: Record<string, string>;
/** Role usado p/ passar a fronteira de auth antes da validação. */
role?: EdgeRole;
}
Comment on lines +53 to +65
/**
* Status aceitáveis para uma chamada ANÔNIMA (sem Authorization).
* - verify_jwt=false OU public/scoped: o handler é alcançado → qualquer não-5xx
* é válido (200 happy, 400/422 validação, 401 assinatura, 429 rate-limit…).
* O contrato relevante é "sem crash 500".
* - demais (gateway verify_jwt=true): gateway rejeita antes do handler → 401/403.
*/
export function expectedAnonStatuses(fn: string): { mode: "reject" | "reach" } {
if (VERIFY_JWT_FALSE.has(fn)) return { mode: "reach" };
const cat = categoryOf(fn);
if (cat === "public" || cat === "scoped") return { mode: "reach" };
return { mode: "reject" };
}
Comment on lines +7 to +21
import { z } from "zod";

/** Contrato de erro padrão das edges migradas: { code, message, fields? }. */
export const errorEnvelopeSchema = z
.object({
code: z.string().optional(),
error: z.string().optional(),
message: z.string().optional(),
fields: z.array(z.string()).optional(),
})
.passthrough()
// ao menos um identificador de erro presente
.refine((o) => Boolean(o.code || o.error || o.message), {
message: "erro sem code/error/message",
});
Comment on lines +51 to +55
"image-proxy": {
method: "GET",
query: "url=https://example.com/x.png",
invalidInputs: [{ label: "url ausente", body: undefined }],
},
Comment on lines +126 to +132
const res = await callEdge(fn, {
method,
query,
role: useRole,
headers: { ...baseHeaders, ...inv.headers },
body: inv.body,
});
adm01-debug pushed a commit that referenced this pull request May 26, 2026
… + CI gate (#380)

- Harness LIVE: 82/82 edge functions cobertas, 672 casos
- CORS, auth boundary, inputs malformados, contrato {code|error|message}
- Fuzz expandido: 8→20 endpoints, uploads/imagem
- Gate CI: bloqueia merge se edge function sem teste LIVE
- ESLint baseline atualizado (+3 any em useGlobalSearch.ts pré-existente)
…rava gate typecheck

simpleQueries usa supabase.from(q.table) com tabela dinâmica (string), sem
overload tipado → TS2769 (linha 417) + TS2345 em cascata (data como
GenericStringError[]). Modela um SimpleQueryBuilder mínimo (eq/or/ilike/order/
limit) e remove os `builder as any` do bloco — sem any, runtime-idêntico.
Elimina o drift legado da etapa 16 (STATUS.md) sem regressão de tipos/lint.

https://claude.ai/code/session_01NKv93VdzWci9KLG98MMHNH
@adm01-debug adm01-debug reopened this May 26, 2026
@supabase
Copy link
Copy Markdown

supabase Bot commented May 26, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Conflitos resolvidos:
- STATUS.md: PR #380 session (2026-05-26, edge LIVE tests) + sessão anterior do main mescladas
- useGlobalSearch.ts: pega 'untypedFrom' helper do main (mais limpo que cast duplo as never)
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

Deployment failed with the following error:

Invalid vercel.json file provided

@adm01-debug adm01-debug merged commit 347167a into main May 26, 2026
21 of 46 checks passed
@adm01-debug adm01-debug deleted the claude/e2e-integration-tests-2eyUd branch May 26, 2026 12:56
adm01-debug pushed a commit that referenced this pull request May 26, 2026
…tions)

Conflitos resolvidos:
- STATUS.md: mescla última sessão do PR com sessão anterior do main
- src/components/search/useGlobalSearch.ts: pega 'untypedFrom' helper do main (mais limpo)
adm01-debug pushed a commit that referenced this pull request May 26, 2026
- useGlobalSearch.ts: remove type SimpleQueryBuilder orphan (ficou do PR #380 mas untypedFrom do main não o usa)
- MockupGenerator.tsx: remove import Badge não usado
- MockupGenerator.tsx: renomeia summary → _summary (definida mas não usada no JSX)

ESLint baseline gate: ✅ zero regressões (drift positivo: -19 erros)
adm01-debug pushed a commit that referenced this pull request May 26, 2026
- useGlobalSearch.ts: remove type SimpleQueryBuilder orphan (ficou do PR #380 mas untypedFrom do main não o usa)
- MockupGenerator.tsx: remove import Badge não usado
- MockupGenerator.tsx: renomeia summary → _summary (definida mas não usada no JSX)

ESLint baseline gate: ✅ zero regressões (drift positivo: -19 erros)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants