Distinguer scénario, dessin et couleurs sur chaque livre

Le rôle vit sur le LIEN livre-auteur, jamais sur l'auteur : le même auteur
scénarise un album et dessine le suivant, et il ne doit pas exister en deux
fiches pour autant — ce que l'index unique sur la clé de regroupement
interdit de toute façon.

Les rôles se retrouvent par clé d'auteur résolue et non par position :
ResoudreAsync écarte les noms vides et fusionne les variantes, donc sa
liste peut être plus courte que la saisie.

Piège traité : le champ des noms reconstruit la liste à chaque frappe.
Decouper reprend les rôles connus en rapprochant sur la forme normalisée,
sans quoi corriger une faute de frappe les effacerait tous.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mathieu
2026-08-19 22:37:20 +02:00
co-authored by Claude Opus 5
parent 9ab6f23b8c
commit 07cb48b2be
16 changed files with 895 additions and 22 deletions
@@ -1,3 +1,5 @@
using MaBibli.Shared.Dtos;
using MaBibli.Shared.Entites;
using MaBibli.Shared.Textes;
namespace MaBibli.Tests;
@@ -117,6 +119,41 @@ public class RapprochementAuteursTests
public void La_normalisation_met_a_plat_casse_accents_et_ponctuation(string? brut, string attendu)
=> Assert.Equal(attendu, NormalisationTexte.Normaliser(brut));
/// <summary>
/// Retaper le champ des noms ne doit pas effacer les rôles déjà posés.
/// </summary>
/// <remarks>
/// Le champ se relie à chaque frappe : sans reprise des rôles connus, corriger une faute de
/// frappe dans le nom d'un auteur remettrait tous ses voisins à « non précisé », sous les
/// yeux de l'utilisateur et sans qu'il comprenne pourquoi.
/// </remarks>
[Fact]
public void Redecouper_la_ligne_dauteurs_preserve_les_roles()
{
var saisie = new EnregistrementLivre
{
Auteurs =
[
new AuteurSaisi("Dobbs", RoleAuteur.Scenario),
new AuteurSaisi("Christophe", RoleAuteur.Dessin),
],
};
// L'utilisateur ajoute un accent au second nom : la ligne est redécoupée entièrement.
saisie.Auteur = "Dobbs; Christophé";
// Les deux rôles survivent : le rapprochement se fait sur la forme NORMALISÉE, donc un
// accent ajouté après coup ne casse rien.
Assert.Equal(
[RoleAuteur.Scenario, RoleAuteur.Dessin],
saisie.Auteurs.Select(a => a.Role));
// Un nom réellement différent, lui, n'est pas reconnu : son rôle repart à zéro, ce qui
// est honnête — on ne devine pas qu'il s'agit de la même personne.
saisie.Auteur = "Dobbs; Marchand";
Assert.Equal(RoleAuteur.NonPrecise, saisie.Auteurs[1].Role);
}
/// <summary>
/// La ponctuation devient une espace et ne disparaît pas : sans ça « P.F. » donnerait un seul
/// mot et les initiales ne pourraient plus s'aligner.