diff --git a/gerbil-manager-web/e2e/farbschlag-sync.spec.ts b/gerbil-manager-web/e2e/farbschlag-sync.spec.ts new file mode 100644 index 0000000..c1e5911 --- /dev/null +++ b/gerbil-manager-web/e2e/farbschlag-sync.spec.ts @@ -0,0 +1,79 @@ +/** FARBSCHLAG-GENOTYPE-SYNC: Bidirektionale Sync im Tier-Formular. */ +import { de, expect, skipUnlessMock, test } from './fixtures' + +const t = de.pages.gerbils + +test('Farbschlag-Auswahl füllt Gencode automatisch aus', async ({ page }) => { + skipUnlessMock() + await page.goto('/rennmaeuse/neu') + + const farbschlagSelect = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.colorVariety}")`) }) + .locator('select') + const genotypeInput = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.genotype}")`) }) + .locator('input') + + // Vor der Auswahl ist das Gencode-Feld leer. + await expect(genotypeInput).toHaveValue('') + + // 'Agouti' wählen → Gencode wird automatisch befüllt. + await farbschlagSelect.selectOption({ label: 'Agouti' }) + await expect(genotypeInput).toHaveValue('AA CC DD EE GG PP spsp rere') +}) + +test('Gencode-Eingabe aktualisiert die Farbschlag-Auswahl', async ({ page }) => { + skipUnlessMock() + await page.goto('/rennmaeuse/neu') + + const farbschlagSelect = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.colorVariety}")`) }) + .locator('select') + const genotypeInput = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.genotype}")`) }) + .locator('input') + + // Gencode für Schwarz eintippen → Farbschlag-Select springt auf 'Schwarz'. + await genotypeInput.fill('aa CC DD EE GG PP spsp rere') + await expect(farbschlagSelect).toHaveValue('cv-schwarz') +}) + +test('Gencode ohne passende Farbschlag-Auswahl leert das Dropdown', async ({ page }) => { + skipUnlessMock() + await page.goto('/rennmaeuse/neu') + + const farbschlagSelect = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.colorVariety}")`) }) + .locator('select') + const genotypeInput = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.genotype}")`) }) + .locator('input') + + // Zuerst eine bekannte Farbe wählen, damit das Select belegt ist. + await farbschlagSelect.selectOption({ label: 'Agouti' }) + await expect(farbschlagSelect).not.toHaveValue('') + + // Marder-Genotyp: bekannte Farbe im Engine, aber NICHT im Mock-Dropdown + // → Select wird auf '' (kein Eintrag) zurückgesetzt. + await genotypeInput.fill('aa cchmcchm DD EE GG PP spsp rere') + await expect(farbschlagSelect).toHaveValue('') +}) + +test('Unbekannter Genotyp leert das Farbschlag-Dropdown (Unbekannt-Fall)', async ({ page }) => { + skipUnlessMock() + await page.goto('/rennmaeuse/neu') + + const farbschlagSelect = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.colorVariety}")`) }) + .locator('select') + const genotypeInput = page + .locator('label.field', { has: page.locator(`span:text-is("${t.fields.genotype}")`) }) + .locator('input') + + await farbschlagSelect.selectOption({ label: 'Blau' }) + await expect(farbschlagSelect).not.toHaveValue('') + + // aa CC dd EE gg pp → Unbekannter Farbschlag (nicht im Katalog) → Select leert sich. + await genotypeInput.fill('aa CC dd EE gg pp spsp rere') + await expect(farbschlagSelect).toHaveValue('') +}) diff --git a/gerbil-manager-web/src/pages/GerbilFormPage.tsx b/gerbil-manager-web/src/pages/GerbilFormPage.tsx index 0fe805b..7f7ecdd 100644 --- a/gerbil-manager-web/src/pages/GerbilFormPage.tsx +++ b/gerbil-manager-web/src/pages/GerbilFormPage.tsx @@ -6,7 +6,7 @@ import { listColorVarieties, listContacts, listEnclosures, listLitters } from '. import { GENDERS, GERBIL_STATUSES, type CreateGerbil, type Gender, type GerbilStatus } from '../api/types' import { useApi, useMutation } from '../hooks/useApi' import { genderLabel, statusLabel } from '../format/labels' -import { fromDisplayString } from '../genetics' +import { fromDisplayString, genotypeToFarbschlag, UNKNOWN_FARBSCHLAG } from '../genetics' import FarbschlagImage from '../components/FarbschlagImage' import NameSuggestPanel from '../components/NameSuggestPanel' import '../components/NameSuggestPanel.css' @@ -307,7 +307,14 @@ export default function GerbilFormPage() {