Files
kochwas/tests/integration/shopping-repository.test.ts

106 lines
3.3 KiB
TypeScript
Raw Normal View History

import { describe, it, expect } from 'vitest';
import { openInMemoryForTest } from '../../src/lib/server/db';
import { insertRecipe } from '../../src/lib/server/recipes/repository';
import {
addRecipeToCart,
2026-04-21 22:56:26 +02:00
removeRecipeFromCart,
listShoppingList,
setCartServings
} from '../../src/lib/server/shopping/repository';
import type { Recipe } from '../../src/lib/types';
function recipe(overrides: Partial<Recipe> = {}): 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('addRecipeToCart', () => {
it('inserts recipe with default servings from recipe.servings_default', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe({ title: 'Pasta', servings_default: 4 }));
addRecipeToCart(db, id, null);
const snap = listShoppingList(db);
expect(snap.recipes).toHaveLength(1);
expect(snap.recipes[0].servings).toBe(4);
});
it('respects explicit servings override', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe({ servings_default: 4 }));
addRecipeToCart(db, id, null, 2);
expect(listShoppingList(db).recipes[0].servings).toBe(2);
});
it('is idempotent: second insert updates servings, not fails', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe({ servings_default: 4 }));
addRecipeToCart(db, id, null, 2);
addRecipeToCart(db, id, null, 6);
const snap = listShoppingList(db);
expect(snap.recipes).toHaveLength(1);
expect(snap.recipes[0].servings).toBe(6);
});
it('falls back to servings=4 when recipe has no default', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe({ servings_default: null }));
addRecipeToCart(db, id, null);
expect(listShoppingList(db).recipes[0].servings).toBe(4);
});
});
2026-04-21 22:56:26 +02:00
describe('removeRecipeFromCart', () => {
it('deletes only the given recipe', () => {
const db = openInMemoryForTest();
const a = insertRecipe(db, recipe({ title: 'A' }));
const b = insertRecipe(db, recipe({ title: 'B' }));
addRecipeToCart(db, a, null);
addRecipeToCart(db, b, null);
removeRecipeFromCart(db, a);
const snap = listShoppingList(db);
expect(snap.recipes).toHaveLength(1);
expect(snap.recipes[0].recipe_id).toBe(b);
});
it('is idempotent when recipe is not in cart', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe());
expect(() => removeRecipeFromCart(db, id)).not.toThrow();
});
});
describe('setCartServings', () => {
it('updates servings for a cart recipe', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe());
addRecipeToCart(db, id, null, 4);
setCartServings(db, id, 8);
expect(listShoppingList(db).recipes[0].servings).toBe(8);
});
it('rejects non-positive servings', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe());
addRecipeToCart(db, id, null, 4);
expect(() => setCartServings(db, id, 0)).toThrow();
expect(() => setCartServings(db, id, -3)).toThrow();
});
});