import { describe, it, expect } from "vitest"; import { MockAamosClient } from "@app/ai-contracts"; import { runPipeline, type PipelineTarget, type PipelineIngredient } from "../src/pipeline.js"; import type { CanonicalIngredientLookup, SimilarityLookup } from "../src/verification.js"; const mockClient = new MockAamosClient(); const mockIngredients: CanonicalIngredientLookup = { getById(id: string) { const db: Record> = { kycklingfile: { id: "kycklingfile", nutritionPer100: { basis: "per_100_g", values: { kcal: 165, proteinG: 31, carbsG: 0, fatG: 3.6, saturatedFatG: 1, fiberG: 0, sugarG: 0, saltG: 0.1, }, }, defaultUnit: "GRAM", densityGPerMl: null, gramsPerPiece: null, allergens: [], isVegan: false, isVegetarian: false, containsGluten: false, containsLactose: false, isPork: false, isBeef: false, isAlcohol: false, }, }; return db[id] ?? undefined; }, }; const noSimilarity: SimilarityLookup = { async hasSimilarity() { return false; }, }; const catalog: PipelineIngredient[] = [ { id: "kycklingfile", nameSv: "kycklingfilé", category: "kott_fagel", defaultUnit: "GRAM", isVegan: false, isVegetarian: false, containsGluten: false, containsLactose: false, allergens: [], }, ]; const targets: PipelineTarget[] = [ { mealType: "dinner", mainIngredientId: "kycklingfile", dietVariant: "standard", count: 2 }, ]; describe("runPipeline", () => { it("kör med mockad klient och returnerar resultat", async () => { const result = await runPipeline(mockClient, targets, catalog, mockIngredients, noSimilarity); expect(result.geminiResult.status).toBe("ok"); // MockAamosClient returnerar nu kandidater för GENERATE_RECIPE_CANDIDATES expect(result.candidates.length).toBeGreaterThan(0); expect(result.verifiedCount + result.unverifiedCount + result.rejectedCount).toBe(result.candidates.length); }); });