feat(db): section_heading roundtrip in recipe-repository

INSERT/SELECT in insertRecipe, replaceIngredients und getRecipeById
um section_heading ergänzt. IngredientSchema im PATCH-Endpoint sowie
Ingredient-Fixtures in search-local-, scaler- und repository-Tests
auf das neue Pflichtfeld aktualisiert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-19 14:55:46 +02:00
parent b0d5f921e2
commit a1baf7f30a
5 changed files with 44 additions and 14 deletions

View File

@@ -70,7 +70,8 @@ describe('recipe repository', () => {
unit: 'g',
name: 'Pancetta',
note: null,
raw_text: '200 g Pancetta'
raw_text: '200 g Pancetta',
section_heading: null
}
],
tags: ['Italienisch']
@@ -118,13 +119,13 @@ describe('recipe repository', () => {
baseRecipe({
title: 'Pasta',
ingredients: [
{ position: 1, quantity: 200, unit: 'g', name: 'Pancetta', note: null, raw_text: '200 g Pancetta' }
{ position: 1, quantity: 200, unit: 'g', name: 'Pancetta', note: null, raw_text: '200 g Pancetta', section_heading: null }
]
})
);
replaceIngredients(db, id, [
{ position: 1, quantity: 500, unit: 'g', name: 'Nudeln', note: null, raw_text: '500 g Nudeln' },
{ position: 2, quantity: 2, unit: null, name: 'Eier', note: null, raw_text: '2 Eier' }
{ position: 1, quantity: 500, unit: 'g', name: 'Nudeln', note: null, raw_text: '500 g Nudeln', section_heading: null },
{ position: 2, quantity: 2, unit: null, name: 'Eier', note: null, raw_text: '2 Eier', section_heading: null }
]);
const loaded = getRecipeById(db, id);
expect(loaded?.ingredients.length).toBe(2);
@@ -154,4 +155,31 @@ describe('recipe repository', () => {
const loaded = getRecipeById(db, id);
expect(loaded?.steps.map((s) => s.text)).toEqual(['Erst', 'Dann']);
});
it('persistiert section_heading und gibt es beim Laden zurueck', () => {
const db = openInMemoryForTest();
const recipe = baseRecipe({
title: 'Torte',
ingredients: [
{ position: 1, quantity: 200, unit: 'g', name: 'Mehl', note: null, raw_text: '200 g Mehl', section_heading: 'Für den Teig' },
{ position: 2, quantity: 100, unit: 'g', name: 'Zucker', note: null, raw_text: '100 g Zucker', section_heading: null },
{ position: 3, quantity: 300, unit: 'g', name: 'Beeren', note: null, raw_text: '300 g Beeren', section_heading: 'Für die Füllung' }
]
});
const id = insertRecipe(db, recipe);
const loaded = getRecipeById(db, id);
expect(loaded!.ingredients[0].section_heading).toBe('Für den Teig');
expect(loaded!.ingredients[1].section_heading).toBeNull();
expect(loaded!.ingredients[2].section_heading).toBe('Für die Füllung');
});
it('replaceIngredients persistiert section_heading', () => {
const db = openInMemoryForTest();
const id = insertRecipe(db, baseRecipe({ title: 'X' }));
replaceIngredients(db, id, [
{ position: 1, quantity: null, unit: null, name: 'A', note: null, raw_text: 'A', section_heading: 'Kopf' }
]);
const loaded = getRecipeById(db, id);
expect(loaded!.ingredients[0].section_heading).toBe('Kopf');
});
});

View File

@@ -48,7 +48,7 @@ describe('searchLocal', () => {
recipe({
title: 'Pasta',
ingredients: [
{ position: 1, quantity: 200, unit: 'g', name: 'Pancetta', note: null, raw_text: '' }
{ position: 1, quantity: 200, unit: 'g', name: 'Pancetta', note: null, raw_text: '', section_heading: null }
]
})
);

View File

@@ -8,7 +8,8 @@ const mk = (q: number | null, unit: string | null, name: string): Ingredient =>
unit,
name,
note: null,
raw_text: ''
raw_text: '',
section_heading: null
});
describe('roundQuantity', () => {