feat(shopping): listShoppingList mit Aggregation + Skalierung
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 2m14s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 2m14s
This commit is contained in:
@@ -103,3 +103,73 @@ describe('setCartServings', () => {
|
||||
expect(() => setCartServings(db, id, -3)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('listShoppingList aggregation', () => {
|
||||
it('aggregates same name+unit across recipes', () => {
|
||||
const db = openInMemoryForTest();
|
||||
const a = insertRecipe(db, recipe({
|
||||
title: 'Carbonara', servings_default: 4,
|
||||
ingredients: [{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
|
||||
}));
|
||||
const b = insertRecipe(db, recipe({
|
||||
title: 'Lasagne', servings_default: 4,
|
||||
ingredients: [{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
|
||||
}));
|
||||
addRecipeToCart(db, a, null, 4);
|
||||
addRecipeToCart(db, b, null, 4);
|
||||
const rows = listShoppingList(db).rows;
|
||||
expect(rows).toHaveLength(1);
|
||||
expect(rows[0].name_key).toBe('mehl');
|
||||
expect(rows[0].unit_key).toBe('g');
|
||||
expect(rows[0].total_quantity).toBe(400);
|
||||
expect(rows[0].from_recipes).toContain('Carbonara');
|
||||
expect(rows[0].from_recipes).toContain('Lasagne');
|
||||
});
|
||||
|
||||
it('keeps different units as separate rows', () => {
|
||||
const db = openInMemoryForTest();
|
||||
const id = insertRecipe(db, recipe({
|
||||
servings_default: 4,
|
||||
ingredients: [
|
||||
{ position: 1, quantity: 100, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null },
|
||||
{ position: 2, quantity: 1, unit: 'Pck', name: 'Mehl', note: null, raw_text: '', section_heading: null }
|
||||
]
|
||||
}));
|
||||
addRecipeToCart(db, id, null, 4);
|
||||
const rows = listShoppingList(db).rows;
|
||||
expect(rows).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('scales quantities by servings/servings_default', () => {
|
||||
const db = openInMemoryForTest();
|
||||
const id = insertRecipe(db, recipe({
|
||||
servings_default: 4,
|
||||
ingredients: [{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }]
|
||||
}));
|
||||
addRecipeToCart(db, id, null, 2);
|
||||
expect(listShoppingList(db).rows[0].total_quantity).toBe(100);
|
||||
});
|
||||
|
||||
it('null quantity stays null after aggregation', () => {
|
||||
const db = openInMemoryForTest();
|
||||
const id = insertRecipe(db, recipe({
|
||||
ingredients: [{ position: 1, quantity: null, unit: null, name: 'Salz', note: null, raw_text: '', section_heading: null }]
|
||||
}));
|
||||
addRecipeToCart(db, id, null);
|
||||
const rows = listShoppingList(db).rows;
|
||||
expect(rows[0].total_quantity).toBeNull();
|
||||
expect(rows[0].unit_key).toBe('');
|
||||
});
|
||||
|
||||
it('counts unchecked rows in uncheckedCount', () => {
|
||||
const db = openInMemoryForTest();
|
||||
const id = insertRecipe(db, recipe({
|
||||
ingredients: [
|
||||
{ position: 1, quantity: 1, unit: 'Stk', name: 'Apfel', note: null, raw_text: '', section_heading: null },
|
||||
{ position: 2, quantity: 1, unit: 'Stk', name: 'Birne', note: null, raw_text: '', section_heading: null }
|
||||
]
|
||||
}));
|
||||
addRecipeToCart(db, id, null);
|
||||
expect(listShoppingList(db).uncheckedCount).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user