Expose côté UI ce que tech-step-matcher.ts détecte déjà à la sauvegarde
(Step.techSteps) mais qui restait backend-only : dans le panneau détail
d'une recette, les mots exacts ayant déclenché une technique sont
surlignés, avec un tooltip (survol/focus clavier) donnant son nom.
- tech-step-matcher.ts : matchTechStepSpans(description, mappings) expose
désormais {techStepId, start, end} en plus de la simple séquence d'ids
(déjà calculé en interne, jusqu'ici jeté). matchTechSteps devient un
wrapper fin dessus — aucun changement à ses ~12 tests existants ni à
recipe-translation.ts.
- StepTechStep gagne start/end (nullable, pas de backfill — même leçon que
l'incident de migration ingredient_unit_catalog : NOT NULL sans défaut
sur une table déjà peuplée casse le déploiement). Une ligne pré-existante
sans span est simplement omise de la réponse API plutôt que de fuiter un
null, jusqu'à ce que la recette soit resauvegardée.
- recipe.service.ts : createRecipe/updateRecipe persistent start/end ;
StepView expose techSteps: { techStep: {id,key}, start, end }[]. Le
recalcul complet à chaque édition (ajout/modif/suppression d'étape) était
déjà garanti par le delete-then-recreate existant d'updateRecipe — testé
explicitement (nouveau test "recomputes techniques from scratch...").
- Frontend : StepDescription.tsx (découpe le texte via
highlight-tech-steps.ts, pur et testé) remplace le <p> brut dans
RecipeDetailPanel. Nouveau Tooltip.tsx (composants/ui, CSS pur, aucune
lib externe — même esprit que Dialog.tsx) : un <button> (focusable
nativement, pas de tabIndex sur un <mark> non interactif) affiche le nom
de la technique (catalog.techSteps.<key>) au survol/focus.
Tests : matchTechStepSpans (spans corrects, chevauchement résolu),
recipe.test.ts (forme API + recalcul complet sur modif/ajout/suppression
d'étape, avec vérification que les anciennes lignes StepTechStep sont bien
supprimées), splitDescriptionByTechSteps (tri, bornes invalides ignorées,
chevauchement résiduel ignoré), scénario Cypress recipes.feature
(surlignage + tooltip au focus).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
41 lines
1.8 KiB
Gherkin
41 lines
1.8 KiB
Gherkin
Feature: Managing a recipe from the catalog
|
|
As a signed-in user
|
|
I want to favorite or delete one of my recipes
|
|
So that I can curate my catalog as it grows
|
|
|
|
Background:
|
|
Given I am signed in as "Alice" "Martin"
|
|
And my household id is 1
|
|
And the disliked ingredients list is empty
|
|
|
|
Scenario: Toggles a recipe's favorite from the detail panel and reflects it in the table
|
|
Given the recipe catalog contains "Omelette"
|
|
And recipe 2's detail is available
|
|
And toggling recipe 2's favorite will succeed
|
|
When I visit "/recettes/2"
|
|
Then the recipe "Omelette" should not be marked as favorite
|
|
When I click the favorite star
|
|
Then the favorite request should have been made
|
|
And the favorite star should be marked as favorite
|
|
And the recipe "Omelette" should be marked as favorite
|
|
|
|
Scenario: Highlights a detected technique in a step, with its name shown on focus
|
|
Given the recipe catalog contains "Omelette"
|
|
And recipe 2's detail is available
|
|
When I visit "/recettes/2"
|
|
Then I should see the highlighted technique "Cuire"
|
|
When I focus the highlighted technique "Cuire"
|
|
Then the tooltip should show "Cuire"
|
|
|
|
Scenario: Deletes a recipe after a two-step confirmation, then clears the selection
|
|
Given the recipe catalog contains "Omelette"
|
|
And recipe 2's detail is available
|
|
And deleting recipe 2 will succeed
|
|
When I visit "/recettes/2"
|
|
Then the recipe detail panel heading should be "Omelette"
|
|
When I click "Supprimer" in the recipe detail panel
|
|
And I confirm the deletion in the recipe detail panel
|
|
Then the delete request should have been made
|
|
And the URL should match the recipes list
|
|
And the recipe "Omelette" should not be visible in the table
|
|
And I should see "Sélectionnez une recette dans le tableau"
|