- Produktdetailseite: dezenter Hinweis direkt bei der Kaufentscheidung, dass beim Checkout eine persoenliche Geschenknachricht hinterlegt werden kann (Feature existierte bereits, war aber nur im Checkout-Formular selbst sichtbar — zu spaet, um Mengen-/Produktwahl noch zu beeinflussen) - Produktdetailseite (Honig): kontextuelle Links zu passenden Honigwissen-Artikeln (Kristallisation immer, Fruehtracht/Sommertracht wenn aus Harvest.type erkennbar) direkt bei den Produktdetails statt einer isolierten, von der Kaufseite aus unverlinkten Wissenssektion - Suche (Shop-Uebersicht + Live-Suchvorschlaege) gleicht jetzt deutsche Umlaute/scharfes S gegen ihre ASCII-Transliteration ab (z.B. "Bluete" findet "Bluete"-Produkte, "kraeftig" findet "kräftig") — vorher lieferte eine Suche in der jeweils anderen Schreibweise keine Treffer, obwohl der Katalog durchgaengig echte Umlaute verwendet; Logik in neuer, reiner lib/search-match.ts mit eigenen Tests ausgelagert - Bewusst NICHT angefasst: Newsletter-Rabattanreiz (fehlt, aber Prozentsatz/ Mechanik ist eine Owner-Entscheidung) und Trust-Badges am Kaufabschluss (bereits vorhanden auf Produktseite/Warenkorb/Checkout) Verifikation: pnpm exec tsc --noEmit clean, pnpm test 151/151 (15 Dateien, +9 neue Tests fuer search-match), pnpm build erfolgreich.
47 lines
1.9 KiB
TypeScript
47 lines
1.9 KiB
TypeScript
import { describe, test, expect } from "vitest";
|
|
import { normalizeSearchText, matchesSearchQuery } from "./search-match";
|
|
|
|
describe("normalizeSearchText", () => {
|
|
test("lowercases and transliterates umlauts to their ASCII equivalent", () => {
|
|
expect(normalizeSearchText("Frühtracht")).toBe("fruehtracht");
|
|
expect(normalizeSearchText("kräftig")).toBe("kraeftig");
|
|
expect(normalizeSearchText("Altenmünster")).toBe("altenmuenster");
|
|
expect(normalizeSearchText("rußarm")).toBe("russarm");
|
|
});
|
|
|
|
test("leaves already-ASCII text unchanged apart from casing", () => {
|
|
expect(normalizeSearchText("Honig")).toBe("honig");
|
|
});
|
|
});
|
|
|
|
describe("matchesSearchQuery", () => {
|
|
test("matches when the query uses real umlauts and the haystack does too", () => {
|
|
expect(matchesSearchQuery("Frühtracht 2026", "Früh")).toBe(true);
|
|
});
|
|
|
|
test("matches when the query uses the ASCII transliteration of an umlaut", () => {
|
|
expect(matchesSearchQuery("Frühtracht 2026", "fruehtracht")).toBe(true);
|
|
});
|
|
|
|
test("matches when the haystack uses the ASCII transliteration and the query the real umlaut", () => {
|
|
expect(matchesSearchQuery("kraeftiger Sommerhonig", "kräftig")).toBe(true);
|
|
});
|
|
|
|
test("is case-insensitive", () => {
|
|
expect(matchesSearchQuery("Blütenhonig", "BLUETE")).toBe(true);
|
|
});
|
|
|
|
test("requires every word of a multi-word query to match", () => {
|
|
expect(matchesSearchQuery("kräftiger Sommerhonig aus Altenmünster", "kraeftig honig")).toBe(true);
|
|
expect(matchesSearchQuery("kräftiger Sommerhonig aus Altenmünster", "kraeftig kerze")).toBe(false);
|
|
});
|
|
|
|
test("returns false when no word matches", () => {
|
|
expect(matchesSearchQuery("Bienenwachskerze", "propolis")).toBe(false);
|
|
});
|
|
|
|
test("returns true for an empty query (no filter applied)", () => {
|
|
expect(matchesSearchQuery("Bienenwachskerze", "")).toBe(true);
|
|
});
|
|
});
|