Make demo search, filters, exports, and controls functional while exposing dedicated KPI detail pages with tested breakdowns. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
43
tests/analytics.test.ts
Normal file
43
tests/analytics.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getDashboardData, getMetricDetails } from "@/domain/analytics";
|
||||
|
||||
describe("metric drill-down analytics", () => {
|
||||
const dashboard = getDashboardData();
|
||||
const details = getMetricDetails();
|
||||
|
||||
it("reconciles inventory value with batch totals", () => {
|
||||
expect(details.inventoryValue.retailValue).toBe(dashboard.metrics.retailValue);
|
||||
expect(details.inventoryValue.costValue).toBe(
|
||||
dashboard.inventory.reduce((sum, item) => sum + item.costExposure, 0),
|
||||
);
|
||||
expect(details.inventoryValue.potentialMargin).toBe(
|
||||
details.inventoryValue.retailValue - details.inventoryValue.costValue,
|
||||
);
|
||||
expect(details.inventoryValue.byBranch).toHaveLength(4);
|
||||
});
|
||||
|
||||
it("uses complete current and prior revenue periods", () => {
|
||||
expect(details.revenue.current30d).toBe(dashboard.metrics.revenue30d);
|
||||
expect(details.revenue.current30d).toBeGreaterThan(0);
|
||||
expect(details.revenue.prior30d).toBeGreaterThan(0);
|
||||
expect(Number.isFinite(details.revenue.changePercent)).toBe(true);
|
||||
expect(details.revenue.byProduct).toHaveLength(8);
|
||||
});
|
||||
|
||||
it("limits headline risk exposure to at-risk and expired batches", () => {
|
||||
expect(details.risk.affected.every(
|
||||
(item) => item.status === "at_risk" || item.status === "expired",
|
||||
)).toBe(true);
|
||||
expect(details.risk.costValue).toBe(dashboard.metrics.atRiskValue);
|
||||
expect(details.risk.byStatus.some((row) => row.status === "watch")).toBe(true);
|
||||
});
|
||||
|
||||
it("provides bounded freshness rollups", () => {
|
||||
expect(details.freshness.averageScore).toBe(dashboard.metrics.averageFreshness);
|
||||
expect(details.freshness.weightedScore).toBeGreaterThanOrEqual(0);
|
||||
expect(details.freshness.weightedScore).toBeLessThanOrEqual(100);
|
||||
expect(details.freshness.freshUnitsPercent).toBeGreaterThanOrEqual(0);
|
||||
expect(details.freshness.freshUnitsPercent).toBeLessThanOrEqual(100);
|
||||
expect(details.freshness.byProduct).toHaveLength(8);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user