Jest · fixture · Luhn

Gerador de Cartão para Testes em Jest

Fixture pra cartão sintético em testes Jest — Luhn válido, filtro por bandeira, mock de gateway. Session fixture, globalSetup, snapshot fixture. Tudo com SDK fakeforge-br. Ambiente de desenvolvimento apenas.

Ferramenta para desenvolvedores. Os cartão de crédito gerados são sintéticos e não pertencem a nenhuma pessoa real. Uso restrito a testes de software, seed de banco de dados de desenvolvimento e fixtures de QA. Usar em cadastro real ou apresentar como documento verdadeiro configura falsidade ideológica (art. 299 CP).

TL;DR

npm install --save-dev fakeforge-br

// tests/fixtures/cartao.ts
import { FakeForge } from "fakeforge-br"
export const ff = new FakeForge()

Fixture com cache

// tests/fixtures/cartao-fixture.ts
import { FakeForge, CreditCard } from "fakeforge-br"

const ff = new FakeForge()
let cache: Record<string, CreditCard[]> = {}

export async function getCartoes(brand?: string, qty = 10): Promise<CreditCard[]> {
  const key = brand || "any"
  if (!cache[key] || cache[key].length < qty) {
    const url = brand
      ? `?type=creditCard&brand=${brand}&quantity=${Math.max(qty, 50)}`
      : `?type=creditCard&quantity=${Math.max(qty, 50)}`
    // FakeForge SDK abstrai o URL; passamos brand como opção
    cache[key] = await ff.creditCard(Math.max(qty, 50), true)
  }
  return cache[key].slice(0, qty)
}

Teste E2E — checkout aprovado

// tests/checkout.test.ts
import { getCartoes } from "./fixtures/cartao-fixture"
import request from "supertest"
import app from "../src/app"

describe("POST /checkout", () => {
  test("aceita cartão com Luhn válido", async () => {
    const [cartao] = await getCartoes(undefined, 1)
    const res = await request(app).post("/checkout").send({
      cardNumber: cartao.number.replace(/\s/g, ""),
      cardCvv: cartao.cvv,
      cardExpiry: cartao.expiry,
      cardHolder: cartao.holder,
      amount: 100.00,
    })
    expect(res.status).toBe(200)
    expect(res.body.status).toBe("approved")
  })

  test("rejeita cartão com Luhn inválido", async () => {
    const res = await request(app).post("/checkout").send({
      cardNumber: "1234567890123456",  // Luhn inválido
      cardCvv: "123",
      cardExpiry: "12/28",
    })
    expect(res.status).toBe(400)
  })
})

Mock de gateway (Stripe)

// tests/payment.test.ts
import { getCartoes } from "./fixtures/cartao-fixture"

jest.mock("stripe", () => ({
  __esModule: true,
  default: jest.fn(() => ({
    paymentIntents: {
      create: jest.fn().mockResolvedValue({ id: "pi_mock", status: "succeeded" }),
    },
  })),
}))

test("PaymentService cria intent no Stripe", async () => {
  const { PaymentService } = await import("../src/payment.service")
  const [cartao] = await getCartoes(undefined, 1)

  const result = await PaymentService.pay({
    cardNumber: cartao.number,
    amount: 5000,  // R$50
  })

  expect(result.status).toBe("succeeded")
  expect(result.intentId).toBe("pi_mock")
})

Snapshot fixture determinística

# scripts/gen-cartoes-snapshot.mjs - roda 1 vez, commita
import { FakeForge } from "fakeforge-br"
import fs from "fs"

const ff = new FakeForge()
const cartoes = await ff.creditCard(50)
fs.writeFileSync("tests/fixtures/cartoes-snapshot.json", JSON.stringify(cartoes, null, 2))

# tests/loader.ts
import snapshot from "./fixtures/cartoes-snapshot.json"
export const cartoesSnapshot = snapshot