feat(shopping): toggleCheck (idempotent)
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 2m20s

Idempotentes Setzen/Loeschen von shopping_cart_check-Eintraegen
ueber (name_key, unit_key). Check ueberlebt Recipe-Removals,
solange ein anderes Rezept weiterhin zur Zeile beitraegt —
verifiziert durch 3 neue Integrationstests (17 total).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-21 23:08:20 +02:00
parent 494b672e8d
commit 1889b0dea0
2 changed files with 62 additions and 6 deletions

View File

@@ -5,7 +5,8 @@ import {
addRecipeToCart,
removeRecipeFromCart,
listShoppingList,
setCartServings
setCartServings,
toggleCheck
} from '../../src/lib/server/shopping/repository';
import type { Recipe } from '../../src/lib/types';
@@ -185,3 +186,48 @@ describe('listShoppingList aggregation', () => {
expect(rows[0].total_quantity).toBeNull();
});
});
describe('toggleCheck', () => {
function setupOneRowCart() {
const db = openInMemoryForTest();
const id = insertRecipe(db, recipe({
ingredients: [{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
}));
addRecipeToCart(db, id, null);
return { db, id };
}
it('marks a row as checked', () => {
const { db } = setupOneRowCart();
toggleCheck(db, 'mehl', 'g', true);
const rows = listShoppingList(db).rows;
expect(rows[0].checked).toBe(1);
});
it('unchecks a row when passed false', () => {
const { db } = setupOneRowCart();
toggleCheck(db, 'mehl', 'g', true);
toggleCheck(db, 'mehl', 'g', false);
expect(listShoppingList(db).rows[0].checked).toBe(0);
});
it('check survives removal of one recipe when another still contributes', () => {
const db = openInMemoryForTest();
const a = insertRecipe(db, recipe({
title: 'A',
ingredients: [{ position: 1, quantity: 100, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
}));
const b = insertRecipe(db, recipe({
title: 'B',
ingredients: [{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
}));
addRecipeToCart(db, a, null);
addRecipeToCart(db, b, null);
toggleCheck(db, 'mehl', 'g', true);
// Rezept A weg, Mehl kommt noch aus B — check bleibt, mit neuer Menge
removeRecipeFromCart(db, a);
const rows = listShoppingList(db).rows;
expect(rows[0].checked).toBe(1);
expect(rows[0].total_quantity).toBe(200);
});
});