feat(recipes): add local search (FTS5 bm25) and action handlers
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
113
tests/integration/recipe-actions.test.ts
Normal file
113
tests/integration/recipe-actions.test.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { openInMemoryForTest } from '../../src/lib/server/db';
|
||||
import { createProfile } from '../../src/lib/server/profiles/repository';
|
||||
import { insertRecipe, getRecipeById } from '../../src/lib/server/recipes/repository';
|
||||
import {
|
||||
setRating,
|
||||
clearRating,
|
||||
listRatings,
|
||||
addFavorite,
|
||||
removeFavorite,
|
||||
isFavorite,
|
||||
logCooked,
|
||||
listCookingLog,
|
||||
addComment,
|
||||
listComments,
|
||||
deleteComment,
|
||||
renameRecipe
|
||||
} from '../../src/lib/server/recipes/actions';
|
||||
import type Database from 'better-sqlite3';
|
||||
|
||||
let db: Database.Database;
|
||||
let profileId: number;
|
||||
let recipeId: number;
|
||||
|
||||
beforeEach(() => {
|
||||
db = openInMemoryForTest();
|
||||
profileId = createProfile(db, 'Hendrik').id;
|
||||
recipeId = insertRecipe(db, {
|
||||
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: []
|
||||
});
|
||||
});
|
||||
|
||||
describe('rating', () => {
|
||||
it('upserts a rating', () => {
|
||||
setRating(db, recipeId, profileId, 4);
|
||||
expect(listRatings(db, recipeId)).toEqual([{ profile_id: profileId, stars: 4 }]);
|
||||
setRating(db, recipeId, profileId, 5);
|
||||
expect(listRatings(db, recipeId)[0].stars).toBe(5);
|
||||
});
|
||||
|
||||
it('rejects invalid stars', () => {
|
||||
expect(() => setRating(db, recipeId, profileId, 0)).toThrow();
|
||||
expect(() => setRating(db, recipeId, profileId, 6)).toThrow();
|
||||
});
|
||||
|
||||
it('clears rating', () => {
|
||||
setRating(db, recipeId, profileId, 3);
|
||||
clearRating(db, recipeId, profileId);
|
||||
expect(listRatings(db, recipeId)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('favorite', () => {
|
||||
it('adds, checks, removes (idempotent add)', () => {
|
||||
expect(isFavorite(db, recipeId, profileId)).toBe(false);
|
||||
addFavorite(db, recipeId, profileId);
|
||||
addFavorite(db, recipeId, profileId); // no-op
|
||||
expect(isFavorite(db, recipeId, profileId)).toBe(true);
|
||||
removeFavorite(db, recipeId, profileId);
|
||||
expect(isFavorite(db, recipeId, profileId)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cooking log', () => {
|
||||
it('logs cooked and lists', () => {
|
||||
logCooked(db, recipeId, profileId);
|
||||
logCooked(db, recipeId, profileId);
|
||||
expect(listCookingLog(db, recipeId).length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('comments', () => {
|
||||
it('adds, lists with author name, deletes', () => {
|
||||
const id = addComment(db, recipeId, profileId, 'Salz durch Zucker ersetzen');
|
||||
const list = listComments(db, recipeId);
|
||||
expect(list.length).toBe(1);
|
||||
expect(list[0].text).toBe('Salz durch Zucker ersetzen');
|
||||
expect(list[0].author).toBe('Hendrik');
|
||||
deleteComment(db, id);
|
||||
expect(listComments(db, recipeId).length).toBe(0);
|
||||
});
|
||||
|
||||
it('rejects empty', () => {
|
||||
expect(() => addComment(db, recipeId, profileId, ' ')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('rename', () => {
|
||||
it('updates title', () => {
|
||||
renameRecipe(db, recipeId, 'Neuer Titel');
|
||||
const r = getRecipeById(db, recipeId);
|
||||
expect(r!.title).toBe('Neuer Titel');
|
||||
});
|
||||
|
||||
it('rejects empty title', () => {
|
||||
expect(() => renameRecipe(db, recipeId, '')).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user