import fc from "fast-check"; import { Address, BillingDetails, CartItem } from "../../src/models/components"; /** * Shared fast-check parameters for E2E property tests. `numRuns` is deliberately * small because every run is a real network round-trip — we want broad-ish input * coverage without blowing the CI time budget. The seed is fixed (overridable via * `FC_SEED`) so a failing case is reproducible from the CI logs. */ const DEFAULT_SEED = 42; // Use FC_SEED when it parses to a real number; otherwise fall back to the // default so a non-numeric env value (common in CI templating) can't turn the // seed into NaN and make fast-check behave unexpectedly. const resolveSeed = (): number => { const raw = process.env["FC_SEED"]; if (!raw) return DEFAULT_SEED; const parsed = Number(raw); return Number.isFinite(parsed) ? parsed : DEFAULT_SEED; }; export const fcParams = (numRuns = 5): fc.Parameters => ({ numRuns, seed: resolveSeed(), }); /** Minor-unit amount the mock connector reliably authorises. */ export const amount = (): fc.Arbitrary => fc.integer({ min: 50, max: 100_000 }); /** Currencies the test merchant's `mock-card` service accepts. */ export const currency = (): fc.Arbitrary => fc.constantFrom("USD"); /** Countries the test merchant's `mock-card` service accepts. */ export const country = (): fc.Arbitrary => fc.constantFrom("US"); /** * Metadata maps mixing camelCase and snake_case keys, to exercise the * snakecase-keys serialisation boundary the way the auth/embed tests do. Values * are always strings to match the transaction metadata type. */ export const metadata = (): fc.Arbitrary> => fc.dictionary( fc.oneof( fc.constantFrom("orderId", "campaign", "noteForOps"), fc.constantFrom("order_id", "campaign_ref", "internal_note") ), fc.string({ minLength: 1, maxLength: 40 }), { minKeys: 1, maxKeys: 4 } ); /** Human-ish names with the odd unicode/whitespace edge case. */ export const name = (): fc.Arbitrary => fc .string({ minLength: 1, maxLength: 30 }) .filter((s) => s.trim().length > 0); export const addressArb = (): fc.Arbitrary
=> fc.record( { city: fc.constantFrom("London", "Paris", "Berlin", "San Francisco"), country: country(), postalCode: fc.constantFrom("94110", "10001", "SW1A 1AA"), state: fc.constantFrom("CA", "NY", "TX"), line1: fc.string({ minLength: 1, maxLength: 50 }), line2: fc.option(fc.string({ maxLength: 20 }), { nil: undefined }), }, { requiredKeys: ["country", "line1"] } ); export const billingDetailsArb = (): fc.Arbitrary => fc.record( { firstName: name(), lastName: name(), emailAddress: fc.emailAddress(), address: addressArb(), }, { requiredKeys: ["firstName", "lastName"] } ); export const cartItemArb = (): fc.Arbitrary => fc.record({ name: name(), quantity: fc.integer({ min: 1, max: 5 }), unitAmount: fc.integer({ min: 1, max: 5_000 }), });