Files
Cibello-app/packages/recipe-generation/test/gap-report.test.ts
T
Sven (AAMOS AI) 4b7dec2759 feat(recipe-generation): Cibello Receptkatalog Fas A – STEG 1
- Nytt paket @app/recipe-generation med pipeline, verifieringsgrind,
  gaprapport och pilotbatch-script.
- Ny AAMOS-task GENERATE_RECIPE_CANDIDATES i @app/ai-contracts.
- GeminiAamosClient utökat med receptgenereringsstöd.
- MockAamosClient uppdaterad med deterministiska kandidater.
- Verifieringspipeline: ingrediensmappning (hård spärr), härledda allergener,
  beräknad näring via nutrition-engine, språk-/kvalitetskontroll, dedup.
- Hermetiska tester: 10/10 gröna.
- typecheck + test + build: gröna för hela workspace.

Refs: docs/32-receptkatalog-buildout.md
2026-08-09 19:47:03 +07:00

40 lines
2.1 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { buildGapReport, formatGapReport } from "../src/gap-report.js";
import type { AnalyticsEvent, RecipeSignal } from "../src/gap-report.js";
describe("buildGapReport", () => {
it("identifierar topp-saknade ingredienser", () => {
const events: AnalyticsEvent[] = [
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "lax", suggestedIngredientId: "laxfile" } },
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "lax", suggestedIngredientId: "laxfile" } },
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "lax", suggestedIngredientId: "laxfile" } },
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "tofu", suggestedIngredientId: "fast_tofu" } },
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "tofu", suggestedIngredientId: "fast_tofu" } },
];
const report = buildGapReport(events, [], []);
expect(report.entries).toHaveLength(2);
expect(report.topMissingIngredients[0]?.canonicalIngredientId).toBe("laxfile");
expect(report.topMissingIngredients[0]?.count).toBe(3);
});
it("filtrerar bort enstaka missar", () => {
const events: AnalyticsEvent[] = [
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "enstaka" } },
];
const report = buildGapReport(events, [], [], { minMissThreshold: 2 });
expect(report.entries).toHaveLength(0);
});
it("formaterar rapporten", () => {
const events: AnalyticsEvent[] = [
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "lax" } },
{ eventName: "recipe_search_zero_results", occurredAt: new Date(), properties: { query: "lax" } },
];
const report = buildGapReport(events, [], [], { minMissThreshold: 1 });
const text = formatGapReport(report);
expect(text).toContain("Katalog-gaprapport");
expect(text).toContain("lax");
});
});