fix(akte): falscher Hinweis „Weicht vom eingetragenen Farbschlag ab"
Beim Prod-Nachtest aufgefallen: Bei Schecken meldete die Akte eine Abweichung, obwohl eingetragener und errechneter Farbschlag identisch angezeigt wurden (JackJack: „Saphir Schecke" vs. „Saphir Schecke"). Zwei Ursachen: - Der Vergleich schnitt „Schecke"/„Rex" nur auf der ERRECHNETEN Seite ab, nicht auf der eingetragenen (die den Zusatz über formatVarietyName trägt). Jetzt werden beide Seiten gleich normalisiert. - formatVarietyName hängte den Modifier auch an, wenn der Katalogname ihn schon trägt („Schwarz Schecke" → „Schwarz Schecke Schecke"). Tests: 3 vitest-Fälle zu formatVarietyName, e2e SCHECKE-MISMATCH mit Gegenprobe (Mock-Tier mit echter Abweichung zeigt den Hinweis weiter). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -168,6 +168,10 @@ export function seedDb(): MockDb {
|
|||||||
gerbil('balu', 'Balu', 'male', '2021-04-20', 'w-balu', 'cv-agouti'),
|
gerbil('balu', 'Balu', 'male', '2021-04-20', 'w-balu', 'cv-agouti'),
|
||||||
gerbil('maja', 'Maja', 'female', '2021-06-11', null, 'cv-schwarz-schecke', 'aa CC DD EE GG PP Spsp rere'),
|
gerbil('maja', 'Maja', 'female', '2021-06-11', null, 'cv-schwarz-schecke', 'aa CC DD EE GG PP Spsp rere'),
|
||||||
gerbil('karlsson', 'Karlsson', 'male', '2022-02-02', 'w-karlsson', 'cv-blau'),
|
gerbil('karlsson', 'Karlsson', 'male', '2022-02-02', 'w-karlsson', 'cv-blau'),
|
||||||
|
// FARBSCHLAG-MISMATCH: eingetragen „Schwarz Schecke", Gencode ergibt Agouti Schecke
|
||||||
|
// → der Hinweis „Weicht vom eingetragenen Farbschlag ab" MUSS hier erscheinen.
|
||||||
|
gerbil('mismatch-maus', 'Mismatch Maus', 'female', '2023-02-02', null, 'cv-schwarz-schecke',
|
||||||
|
'AA CC DD EE GG PP Spsp rere'),
|
||||||
gerbil('smilla', 'Smilla', 'female', '2022-09-30', null, 'cv-himalaya'),
|
gerbil('smilla', 'Smilla', 'female', '2022-09-30', null, 'cv-himalaya'),
|
||||||
gerbil('anton', 'Anton', 'male', '2019-07-07', 'w-anton', 'cv-agouti'),
|
gerbil('anton', 'Anton', 'male', '2019-07-07', 'w-anton', 'cv-agouti'),
|
||||||
gerbil('greta', 'Greta', 'female', '2019-05-23', null, 'cv-schwarz'),
|
gerbil('greta', 'Greta', 'female', '2019-05-23', null, 'cv-schwarz'),
|
||||||
|
|||||||
@@ -241,6 +241,23 @@ test('Detailseite: Abgabedatum steht direkt unter dem Abnehmer, auch bei Verstor
|
|||||||
await expect(goHomeRow.locator('.ak-kv-value')).toHaveText('15.01.2022')
|
await expect(goHomeRow.locator('.ak-kv-value')).toHaveText('15.01.2022')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Detailseite: Farbschlag-Hinweis nur bei echter Abweichung (SCHECKE-MISMATCH)', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
skipUnlessMock()
|
||||||
|
// Maja: eingetragen „Schwarz Schecke", Gencode ergibt genau das → KEIN Hinweis.
|
||||||
|
// (Vorher wurde der Zusatz „Schecke" nur auf der errechneten Seite abgeschnitten,
|
||||||
|
// dadurch bekam jede Schecke faelschlich „Weicht vom eingetragenen Farbschlag ab".)
|
||||||
|
await page.goto('/rennmaeuse/maja')
|
||||||
|
const genetik = page.locator('.ak-card', { hasText: t.detail.genetics }).first()
|
||||||
|
await expect(genetik.getByText(t.detail.resolvedPrefix, { exact: false })).toBeVisible()
|
||||||
|
await expect(page.getByText(t.detail.farbschlagMismatch)).toBeHidden()
|
||||||
|
|
||||||
|
// Gegenprobe: bei echter Abweichung erscheint der Hinweis weiter.
|
||||||
|
await page.goto('/rennmaeuse/mismatch-maus')
|
||||||
|
await expect(page.getByText(t.detail.farbschlagMismatch)).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
/** QOL-ELTERN: Vater/Mutter im Abstammungs-Block des Tier-Formulars setzen. */
|
/** QOL-ELTERN: Vater/Mutter im Abstammungs-Block des Tier-Formulars setzen. */
|
||||||
async function pickParent(page: Page, legend: string, name: string) {
|
async function pickParent(page: Page, legend: string, name: string) {
|
||||||
const group = page.getByRole('group', { name: legend })
|
const group = page.getByRole('group', { name: legend })
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { combineLocus } from '../punnett'
|
|||||||
import { LOCI, type LocusKey } from '../loci'
|
import { LOCI, type LocusKey } from '../loci'
|
||||||
import {
|
import {
|
||||||
farbschlagFor,
|
farbschlagFor,
|
||||||
|
formatVarietyName,
|
||||||
genotypeToFarbschlag,
|
genotypeToFarbschlag,
|
||||||
representativeGenotype,
|
representativeGenotype,
|
||||||
BASE_COLORS,
|
BASE_COLORS,
|
||||||
@@ -963,6 +964,22 @@ describe('GEN-6: C-Locus-Zygotie Platin / Saphir / Platin-Hell (bde4ec70 / f89e9
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('formatVarietyName: Modifier nicht doppeln', () => {
|
||||||
|
it('haengt „Schecke" an einen Basisnamen an', () => {
|
||||||
|
expect(formatVarietyName('Saphir', 'aa Cc[chm] DD E- G- pp Spsp')).toBe('Saphir Schecke')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('doppelt „Schecke" NICHT, wenn der Katalogname es schon traegt', () => {
|
||||||
|
// Sonst „Schwarz Schecke Schecke" — und der Akten-Vergleich „eingetragen vs. errechnet"
|
||||||
|
// meldete eine Abweichung, obwohl beides dasselbe ist.
|
||||||
|
expect(formatVarietyName('Schwarz Schecke', 'aa CC DD EE GG PP Spsp rere')).toBe('Schwarz Schecke')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('ohne Gencode bleibt der Name unveraendert', () => {
|
||||||
|
expect(formatVarietyName('Saphir', null)).toBe('Saphir')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('Schreibfehler-Alias c[hm] == c[chm] (Ticket 2322c2a8, Jay *24.10.2021)', () => {
|
describe('Schreibfehler-Alias c[hm] == c[chm] (Ticket 2322c2a8, Jay *24.10.2021)', () => {
|
||||||
it('c[hm] parst als c[chm] und ergibt Zobel, nicht Zobel-Hell', () => {
|
it('c[hm] parst als c[chm] und ergibt Zobel, nicht Zobel-Hell', () => {
|
||||||
// Die Quell-Charts (Alberto Kids / Pukas Kids) schreiben „aa c[chm]c[hm] …" —
|
// Die Quell-Charts (Alberto Kids / Pukas Kids) schreiben „aa c[chm]c[hm] …" —
|
||||||
|
|||||||
@@ -365,8 +365,13 @@ export function formatVarietyName(baseName: string, genotypeStr: string | null |
|
|||||||
try {
|
try {
|
||||||
const g = fromDisplayString(genotypeStr)
|
const g = fromDisplayString(genotypeStr)
|
||||||
const modifiers: string[] = []
|
const modifiers: string[] = []
|
||||||
if (locusToken(g, 'Sp') === 'Sp') modifiers.push('Schecke')
|
// Einen Modifier NICHT doppeln, wenn der Katalogname ihn schon traegt: Bestaende mit
|
||||||
if (locusToken(g, 'Re') === 'Re') modifiers.push('Rex')
|
// Namen wie „Schwarz Schecke" ergaeben sonst „Schwarz Schecke Schecke" — und der
|
||||||
|
// Vergleich mit dem errechneten Farbschlag meldet dann eine Abweichung, die es nicht gibt.
|
||||||
|
const words = baseName.toLowerCase().split(/[\s-]+/)
|
||||||
|
const alreadyNamed = (modifier: string) => words.includes(modifier.toLowerCase())
|
||||||
|
if (locusToken(g, 'Sp') === 'Sp' && !alreadyNamed('Schecke')) modifiers.push('Schecke')
|
||||||
|
if (locusToken(g, 'Re') === 'Re' && !alreadyNamed('Rex')) modifiers.push('Rex')
|
||||||
return [baseName, ...modifiers].join(' ')
|
return [baseName, ...modifiers].join(' ')
|
||||||
} catch {
|
} catch {
|
||||||
return baseName
|
return baseName
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ function describeGenotype(genotype: string | null): { display: string; farbschla
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A labelled key/value row inside a card (semantic dt/dd, styled as a grid). */
|
/** A labelled key/value row inside a card (semantic dt/dd, styled as a grid). */
|
||||||
|
/** „Saphir Schecke" → „Saphir": Modifier-Zusaetze fuer den Namensvergleich abschneiden. */
|
||||||
|
function stripVarietyModifiers(name: string): string {
|
||||||
|
return name.replace(' Schecke', '').replace(' Rex', '').trim()
|
||||||
|
}
|
||||||
|
|
||||||
function Kv({ label, children }: { label: string; children: ReactNode }) {
|
function Kv({ label, children }: { label: string; children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div className="ak-kv">
|
<div className="ak-kv">
|
||||||
@@ -594,10 +599,16 @@ export default function GerbilDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{resolvedFarbschlag}
|
{resolvedFarbschlag}
|
||||||
|
{/* Vergleich OHNE die Modifier-Zusaetze auf BEIDEN Seiten: der
|
||||||
|
eingetragene Name traegt „Schecke"/„Rex" bereits (formatVarietyName
|
||||||
|
haengt sie aus dem Gencode an), der errechnete ebenfalls. Vorher wurde
|
||||||
|
der Zusatz nur rechts entfernt → jede Schecke bekam faelschlich den
|
||||||
|
Hinweis „Weicht vom eingetragenen Farbschlag ab" (z. B. JackJack:
|
||||||
|
„Saphir Schecke" vs. „Saphir Schecke"). */}
|
||||||
{storedColorName &&
|
{storedColorName &&
|
||||||
resolvedFarbschlag !== de.genetics.unknownFarbschlag &&
|
resolvedFarbschlag !== de.genetics.unknownFarbschlag &&
|
||||||
storedColorName !==
|
stripVarietyModifiers(storedColorName) !==
|
||||||
resolvedFarbschlag.replace(' Schecke', '').replace(' Rex', '') && (
|
stripVarietyModifiers(resolvedFarbschlag) && (
|
||||||
<small className="ak-mismatch"> ⚠ {t.detail.farbschlagMismatch}</small>
|
<small className="ak-mismatch"> ⚠ {t.detail.farbschlagMismatch}</small>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user