Files
Sven (AAMOS AI) c32a7e33c7
CI / Typecheck, test & build (push) Failing after 2s
ci: trigga på master + formatfix inför Gitea Actions
2026-08-13 17:25:14 +07:00

114 lines
3.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
provenanceTemplateLanguages,
whyTemplateLanguages,
buildWhy,
type RecommendationCandidate,
type RecommendationContext,
type ProvenanceEntry,
} from "../src/index.js";
const EXPECTED_LANGS = ["sv", "en", "es", "it", "de", "fr", "da", "nb", "fi", "nl", "pl", "pt"];
const fullCoverage = { coverage: 1, matches: [], missing: [], expiringUsed: [] };
const nutrition = {
kcal: 550,
proteinG: 45,
carbsG: 50,
fatG: 18,
saturatedFatG: 6,
fiberG: 6,
sugarG: 4,
saltG: 1.5,
};
function candidate(overrides: Partial<RecommendationCandidate> = {}): RecommendationCandidate {
return {
recipeId: "r1",
titleSv: "Kycklinggryta",
cuisine: "swedish",
tags: [],
totalTimeMinutes: 30,
nutritionPerPortion: nutrition,
estimatedCostMinorPerPortion: 2200,
ratingAverage: null,
ratingCount: 0,
peakSeasons: [],
holidayTags: [],
spiceLevel: 1,
coverage: fullCoverage,
...overrides,
};
}
const ctx: RecommendationContext = {
mealType: "dinner",
persons: 4,
currentSeason: "summer",
activeHolidayTags: [],
isWeekday: true,
favoriteCuisines: ["swedish"],
remainingProteinG: 60,
remainingKcal: 800,
personalizationEnabled: false,
};
describe("S6 i18n-paritet", () => {
it("provenansmallarna täcker exakt 12 språk utan dubbletter", () => {
const langsByTemplate = provenanceTemplateLanguages();
expect(Object.keys(langsByTemplate).length).toBeGreaterThan(0);
for (const [key, langs] of Object.entries(langsByTemplate)) {
expect(langs.length, `mall ${key} har dubbletter eller saknar språk`).toBe(
EXPECTED_LANGS.length,
);
expect(new Set(langs).size, `mall ${key} har dubbletter`).toBe(EXPECTED_LANGS.length);
for (const lang of EXPECTED_LANGS) {
expect(langs).toContain(lang);
}
}
});
it("why-mallarna täcker exakt 12 språk utan dubbletter", () => {
const langs = whyTemplateLanguages();
expect(langs.length).toBe(EXPECTED_LANGS.length);
expect(new Set(langs).size).toBe(EXPECTED_LANGS.length);
for (const lang of EXPECTED_LANGS) {
expect(langs).toContain(lang);
}
});
it("buildWhy renderar på rätt språk för varje supporterat språk", () => {
const provenance: ProvenanceEntry[] = [{ key: "favoriteCuisine", args: { cuisine: "svensk" } }];
for (const lang of EXPECTED_LANGS) {
const why = buildWhy(
candidate(),
{ ...ctx, personalizationEnabled: true },
{
coverage: 1,
expiry: 0,
nutritionFit: 0.9,
taste: 0.5,
rating: 0.5,
season: 0,
holiday: 0,
time: 0,
budget: 0,
variety: 0.5,
weather: 0.5,
craving: 0.5,
memoryFit: 1,
tasteFit: 0,
cookingAssumptionFit: 0,
},
provenance,
`${lang}-XX`,
);
expect(why.length, `tom why för ${lang}`).toBeGreaterThan(0);
// Ingen why får falla tillbaka på svenska fallback om språket finns.
if (lang !== "sv") {
expect(why).not.toBe("En balanserad rätt som passar er profil.");
}
}
});
});