import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { openInMemoryForTest } from '../../src/lib/server/db'; import { insertRecipe, getRecipeById, getRecipeIdBySourceUrl, deleteRecipe } from '../../src/lib/server/recipes/repository'; import { extractRecipeFromHtml } from '../../src/lib/server/parsers/json-ld-recipe'; import type { Recipe } from '../../src/lib/types'; const here = dirname(fileURLToPath(import.meta.url)); const fixture = (name: string): string => readFileSync(join(here, '../fixtures', name), 'utf8'); function baseRecipe(overrides: Partial = {}): Recipe { return { id: null, title: 'Test', description: null, source_url: null, source_domain: null, image_path: null, servings_default: 4, servings_unit: null, prep_time_min: null, cook_time_min: null, total_time_min: null, cuisine: null, category: null, ingredients: [], steps: [], tags: [], ...overrides }; } describe('recipe repository', () => { it('round-trips an imported chefkoch recipe', () => { const db = openInMemoryForTest(); const parsed = extractRecipeFromHtml(fixture('chefkoch-schupfnudeln.html')); expect(parsed).not.toBeNull(); parsed!.source_url = 'https://www.chefkoch.de/rezepte/4094871643016343/x.html'; parsed!.source_domain = 'chefkoch.de'; const id = insertRecipe(db, parsed!); const loaded = getRecipeById(db, id); expect(loaded).not.toBeNull(); expect(loaded!.title).toBe(parsed!.title); expect(loaded!.ingredients.length).toBe(parsed!.ingredients.length); expect(loaded!.steps.length).toBe(parsed!.steps.length); expect(loaded!.ingredients[0].name).toBe(parsed!.ingredients[0].name); }); it('FTS finds recipe by ingredient after refresh', () => { const db = openInMemoryForTest(); insertRecipe( db, baseRecipe({ title: 'Spaghetti Carbonara', ingredients: [ { position: 1, quantity: 200, unit: 'g', name: 'Pancetta', note: null, raw_text: '200 g Pancetta' } ], tags: ['Italienisch'] }) ); const byIngredient = db .prepare("SELECT rowid FROM recipe_fts WHERE recipe_fts MATCH 'pancetta'") .all(); expect(byIngredient.length).toBe(1); const byTag = db .prepare("SELECT rowid FROM recipe_fts WHERE recipe_fts MATCH 'italienisch'") .all(); expect(byTag.length).toBe(1); }); it('looks up by source_url and deletes cascading', () => { const db = openInMemoryForTest(); const id = insertRecipe( db, baseRecipe({ title: 'Foo', source_url: 'https://example.com/foo', source_domain: 'example.com' }) ); expect(getRecipeIdBySourceUrl(db, 'https://example.com/foo')).toBe(id); deleteRecipe(db, id); expect(getRecipeById(db, id)).toBeNull(); }); });