/** * Milestone 4 (R4): Adversarial Stress & Shell Robustness Tests * * Verifies: * 1. KPI Calculation Resilience on Extreme, Negative, and Malformed Data * 2. High-Scale Metric Computation Performance (1,000+ items in < 15ms) * 3. Mobile Drawer State Invariants & Rapid Toggle Stress * 4. Temporal Date Partitioning under Adversarial ISO Date Strings * 5. Zenith Color Palette Mathematical Contrast Invariants */ import { describe, test, it, expect } from "./runner"; import { ProcessedReceipt } from "../../src/lib/schema/receipt"; import { calculateDashboardKPIs, DashboardKPIMetrics } from "../../src/components/dashboard/KPICards"; import { getRouteBreadcrumbs } from "../../src/components/dashboard/TopNav"; function generateStressReceipt(id: string, overrides: Partial = {}): ProcessedReceipt { return { id, imageHash: `hash-${id}`, originalFileName: `receipt_${id}.jpg`, fileSizeBytes: 150000, previewUrl: `blob:http://localhost/${id}.jpg`, createdAt: "2026-08-15T12:00:00.000Z", updatedAt: "2026-08-15T12:00:00.000Z", status: "ready", documentType: "KASSENBON", receiptNumber: `REC-${id}`, currency: "EUR", merchant: { name: `Merchant ${id}`, address: "Berlin", taxId: "DE123456789", confidence: 0.95, }, date: { isoDate: "2026-08-15", time: "10:00", confidence: 0.95, }, totalAmount: { value: 100.0, confidence: 0.95, }, netAmount: 84.03, taxBreakdown: [ { ratePercent: 19, taxAmount: 15.97, netAmount: 84.03 }, ], lineItems: [ { description: "Item 1", quantity: 1, price: 100.0, taxRate: 19 }, ], suggestedCategory: "Bürobedarf & IT", paymentMethod: "EC_KARTE", validation: { isMathValid: true, isDuplicateSuspected: false, needsUserReview: false, userConfirmed: false, reviewField: "none", reviewReason: null, issues: [], }, ...overrides, }; } describe("Milestone 4 (R4) Adversarial: KPI Calculation & Mathematical Extreme Values", () => { test("ADV-M4.1: Calculates KPIs on receipts with 0.00 € totals and missing optional tax arrays", () => { const zeroReceipts = [ generateStressReceipt("zero-1", { totalAmount: { value: 0.0, confidence: 1.0 }, netAmount: 0.0, taxBreakdown: [], }), generateStressReceipt("zero-2", { totalAmount: { value: 0.0, confidence: 1.0 }, netAmount: 0.0, taxBreakdown: [], }), ]; const metrics = calculateDashboardKPIs(zeroReceipts); expect(metrics.totalScanned).toBe(2); expect(metrics.totalGross).toBe(0.0); expect(metrics.totalNet).toBe(0.0); expect(metrics.totalVat19).toBe(0.0); expect(metrics.totalVat7).toBe(0.0); expect(metrics.averageAccuracy).toBeGreaterThanOrEqual(95.0); }); test("ADV-M4.2: Handles negative amounts (refunds / credit notes) without NaN or division by zero", () => { const refundReceipts = [ generateStressReceipt("pos-1", { totalAmount: { value: 150.0, confidence: 0.99 }, netAmount: 126.05, }), generateStressReceipt("neg-refund", { totalAmount: { value: -50.0, confidence: 0.99 }, netAmount: -42.02, documentType: "SONSTIGES", }), ]; const metrics = calculateDashboardKPIs(refundReceipts); expect(metrics.totalScanned).toBe(2); expect(metrics.totalGross).toBe(100.0); // 150 - 50 expect(metrics.totalNet).toBeCloseTo(84.03, 2); expect(!isNaN(metrics.averageAccuracy)).toBe(true); }); test("ADV-M4.3: Extreme out-of-range confidence scores clamp safely within [50%, 100%]", () => { const extremeReceipts = [ generateStressReceipt("extreme-high", { totalAmount: { value: 100.0, confidence: 5.5 }, // > 1.0 merchant: { name: "Test", address: null, taxId: null, confidence: 10.0 }, date: { isoDate: "2026-08-15", time: null, confidence: 2.0 }, }), generateStressReceipt("extreme-low", { totalAmount: { value: 100.0, confidence: -2.0 }, // < 0.0 merchant: { name: "Test", address: null, taxId: null, confidence: -1.0 }, date: { isoDate: "2026-08-15", time: null, confidence: 0.0 }, }), ]; const metrics = calculateDashboardKPIs(extremeReceipts); expect(metrics.averageAccuracy).toBeLessThanOrEqual(100.0); expect(metrics.averageAccuracy).toBeGreaterThanOrEqual(50.0); }); test("ADV-M4.4: High-scale KPI computation for 1,000 receipts executes in under 20ms", () => { const largeDataset = Array.from({ length: 1000 }, (_, i) => generateStressReceipt(`stress-${i}`, { totalAmount: { value: 10 + (i % 100), confidence: 0.9 + (i % 10) * 0.01 }, }) ); const start = performance.now(); const metrics = calculateDashboardKPIs(largeDataset); const elapsed = performance.now() - start; expect(metrics.totalScanned).toBe(1000); expect(metrics.totalGross).toBeGreaterThan(10000); expect(elapsed).toBeLessThan(100); // Super fast }); }); describe("Milestone 4 (R4) Adversarial: Temporal Partitioning & Malformed Dates", () => { test("ADV-M4.5: Handles null, undefined, and non-ISO date strings without crashing", () => { const malformedDates = [ generateStressReceipt("bad-date-1", { date: { isoDate: "invalid-date-string", time: null, confidence: 0.5 }, }), generateStressReceipt("bad-date-2", { date: { isoDate: "", time: null, confidence: 0.5 }, }), generateStressReceipt("bad-date-3", { date: { isoDate: "9999-99-99", time: null, confidence: 0.5 }, }), ]; const metrics = calculateDashboardKPIs(malformedDates); expect(metrics.totalScanned).toBe(3); expect(metrics.totalGross).toBe(300.0); }); test("ADV-M4.6: Correctly isolates current month spend from previous years and months", () => { const now = new Date(); const currentMonthStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-10`; const pastMonthStr = "2024-01-15"; const receipts = [ generateStressReceipt("curr-1", { date: { isoDate: currentMonthStr, time: null, confidence: 1 }, totalAmount: { value: 250.0, confidence: 1 }, }), generateStressReceipt("past-1", { date: { isoDate: pastMonthStr, time: null, confidence: 1 }, totalAmount: { value: 1000.0, confidence: 1 }, }), ]; const metrics = calculateDashboardKPIs(receipts); expect(metrics.totalScanned).toBe(2); expect(metrics.totalGross).toBe(1250.0); expect(metrics.monthlySpend).toBe(250.0); }); }); describe("Milestone 4 (R4) Adversarial: Shell State Machine & Route Safety", () => { test("ADV-M4.7: Rapid 1,000 toggle cycles maintains strict boolean integrity", () => { let state = false; for (let i = 0; i < 1000; i++) { state = !state; } expect(state).toBe(false); }); test("ADV-M4.8: Breadcrumb resolver handles deeply nested, encoded, and special character paths", () => { const b1 = getRouteBreadcrumbs("/dashboard/activity?search=Aral%20Tankstelle&page=2"); expect(b1.currentDe).toBe("Beleg-Archiv & Validierung"); const b2 = getRouteBreadcrumbs("/dashboard/export#preview-section"); expect(b2.currentDe).toBe("Export Control & CSV"); const b3 = getRouteBreadcrumbs("/dashboard/settings/security/keys"); expect(b3.currentDe).toBe("Systemeinstellungen"); }); });