All checks were successful
`RecipeIngredient.quantity`/`unitId` deviennent nullable (migration purement additive) : une ligne de recette peut n'avoir ni quantité ni unité — sel, poivre… ajoutés selon le goût. Le schéma partagé impose « quantité et unité, ou aucune des deux » ; `toRecipeView` renvoie `null`/`null`. `aggregateShoppingList` fait apparaître une telle ligne une seule fois, sans quantité ni unité, jamais sommée ni mise à l'échelle. `ShoppingListPage` affiche « selon le goût » à la place de la quantité. Formulaire : `IngredientRow` gagne une case « Selon le goût » qui masque quantité/unité ; `RecipeFormPage` et `RecipeImportForm` n'exigent plus quantité/unité pour ces lignes et les envoient sans. Un import dont la source laisse une ligne résolue sans quantité (« salt to taste ») arrive directement en « selon le goût ». Le chemin clause-de-technique (session de cuisine) tolérait déjà `quantity` null — inchangé. Tests : Mocha (création/édition d'une ligne sans quantité, rejet quantité-sans-unité, liste de courses non sommée) ; Cypress (case à cocher + parcours), régression recette/liste de courses OK. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
49 lines
2.5 KiB
Gherkin
49 lines
2.5 KiB
Gherkin
Feature: Shopping list
|
|
As a signed-in user
|
|
I want to see every ingredient needed for this week's planned recipes, already summed
|
|
So that I know what to buy without recomputing it myself
|
|
|
|
Background:
|
|
Given I am signed in as "Alice" "Martin"
|
|
And today is frozen at "2026-08-17T09:00:00.000Z"
|
|
|
|
Scenario: Nothing planned this week shows the empty message, not an error
|
|
Given the shopping list for "2026-08-17" is empty
|
|
When I visit "/liste-de-courses"
|
|
Then I should see "Aucun ingrédient à acheter pour cette semaine — ajoutez des recettes à votre planning."
|
|
|
|
Scenario: Ingredients are grouped by aisle, in canonical order, each with its summed quantity
|
|
Given the shopping list for "2026-08-17" contains:
|
|
| ingredientKey | icon | category | quantity | unitKey |
|
|
| egg | EGG | dairyAndCheese | 6 | piece |
|
|
| tomato | VEGETABLE | freshProduce | 400 | gram |
|
|
When I visit "/liste-de-courses"
|
|
Then the shopping list group "Produits frais" should appear before "Crémerie & fromage"
|
|
And the shopping list should show "Tomate" at quantity "400 g"
|
|
And the shopping list should show "Oeuf" at quantity "6 unité"
|
|
|
|
Scenario: A « selon le goût » seasoning line shows no quantity (issue #128)
|
|
Given the shopping list for "2026-08-17" has a « selon le goût » line for "salt"
|
|
When I visit "/liste-de-courses"
|
|
Then the shopping list should show "Sel" at quantity "selon le goût"
|
|
|
|
Scenario: Navigating to another week fetches and shows that week's own list
|
|
Given the shopping list for "2026-08-17" is empty
|
|
And the shopping list for "2026-08-24" contains:
|
|
| ingredientKey | icon | category | quantity | unitKey |
|
|
| onion | VEGETABLE | freshProduce | 1 | kilogram |
|
|
When I visit "/liste-de-courses"
|
|
And I click the next week arrow
|
|
Then the shopping list should show "Oignon" at quantity "1 kg"
|
|
|
|
Scenario: Ticking an item marks it as in the cart, and the tick survives a reload
|
|
Given the shopping list for "2026-08-17" contains:
|
|
| ingredientKey | icon | category | quantity | unitKey |
|
|
| tomato | VEGETABLE | freshProduce | 400 | gram |
|
|
| onion | VEGETABLE | freshProduce | 2 | piece |
|
|
When I visit "/liste-de-courses"
|
|
And I tick the shopping list item "Tomate"
|
|
Then the shopping list item "Tomate" should be ticked
|
|
And the shopping list item "Oignon" should not be ticked
|
|
When I reload the page
|
|
Then the shopping list item "Tomate" should be ticked
|