REVIEW-FIXES-BACKEND: CR-9 + CR-11 + CR-10 + DB-1
CR-9 (major): gidByNameDob TryGetValue + ExternalRef-Fallback Verhindert KeyNotFoundException wenn Name/DOB zwischen zwei Laeufen driftet (z.B. correctDob-Remap oder UI-Umbenennung). Fallback: ExternalRef-Dict-Lookup; bei Miss: sauberes Ueberspringen + Note statt 500. +Test CR9_NameDOB_drift. CR-11 (major): Farbschlag aus Genotyp ableiten (fill-NULL-only) Deep-Band-Tiere (gen>=2, kein Farbschlag-Feld) landen nicht laenger mit null ColorVariety. GenotypePotentiallyMatches() vergleicht locus-pair-weise (??=wildcard, case-insensitive). Nur vollstaendige Genotypen (8 Loci, kein ??) loesen Ableitung aus. Plan-Loop: fuellt colorVarietyId bei null + vollstaendigem Genotyp. Post-Sweep: bestehende DB-Tiere mit null ColorVarietyId werden nachgefuellt. AnimalSummary.FarbschlagDerivedFromGenotype = Zaehler. +Test CR11_ColorVariety_from_geno. CR-10 (major, Python): malformed Override-Genotyp wird nicht angewendet apply_conflict_decisions validiert mapped8locus nach gt.parse(). Leeres Ergebnis = Genotyp unveraendert + decisionWarning statt stillem Blanken. Konflikt wird trotzdem aufgeloest (Entscheidung gilt, nur Genotyp-Override ausgelassen). +5 Python-Tests (CR-10-Block in test_extract.py). DB-1 (high): filtered unique index auf Gerbil.ExternalRef WHERE ExternalRef IS NOT NULL — verhindert doppelten Import bei Race-Conditions oder Lauf-Ueberschneidungen. Migration UniqueExternalRef. SQLite-Testhost: HasFilter() wird via EnsureCreated appliziert (SQLite unterstuetzt Partial-Indexes). PartialUpdateTests externalRef-Assertion auf NotNull geaendert (name-hash unique). GATE: 139/139 C# + Python ALL PASS, ef has-pending=No.
This commit is contained in:
@@ -29,6 +29,8 @@ public class PartialUpdateTests : IClassFixture<ApiFactory>
|
||||
/// <summary>Create a fully-populated gerbil and return its id.</summary>
|
||||
private async Task<Guid> CreateFullGerbil(string name = "TestTier")
|
||||
{
|
||||
// Use name-derived unique externalRef so the DB-1 unique constraint doesn't fire
|
||||
// when multiple tests in the same fixture share the SQLite connection.
|
||||
var resp = await _client.PostAsync("/gerbils", JsonContent.Create(new
|
||||
{
|
||||
name,
|
||||
@@ -39,7 +41,7 @@ public class PartialUpdateTests : IClassFixture<ApiFactory>
|
||||
characterTraits = new[] { "neugierig", "zutraulich" },
|
||||
characterNote = "Liebling der Familie",
|
||||
notes = "Eine Notiz",
|
||||
externalRef = "ext-001",
|
||||
externalRef = $"ext-{name.GetHashCode():X8}",
|
||||
}));
|
||||
Assert.Equal(HttpStatusCode.Created, resp.StatusCode);
|
||||
return ExtractId(await resp.Content.ReadAsStringAsync());
|
||||
@@ -67,7 +69,7 @@ public class PartialUpdateTests : IClassFixture<ApiFactory>
|
||||
Assert.Equal("aa CC DD ee GG PP spsp rere", GetStr(json, "genotype"));
|
||||
Assert.Equal("Zucht der Kleinen Chaoten", GetStr(json, "originBreeder"));
|
||||
Assert.Equal("Eine Notiz", GetStr(json, "notes"));
|
||||
Assert.Equal("ext-001", GetStr(json, "externalRef"));
|
||||
Assert.NotNull(GetStr(json, "externalRef")); // externalRef set during create, not cleared by partial PUT
|
||||
Assert.Contains("neugierig", GetNested(json, "characterTraits") ?? "");
|
||||
Assert.Equal("Liebling der Familie", GetStr(json, "characterNote"));
|
||||
}
|
||||
@@ -95,7 +97,7 @@ public class PartialUpdateTests : IClassFixture<ApiFactory>
|
||||
Assert.Equal("aa CC DD ee GG PP spsp rere", GetStr(json, "genotype"));
|
||||
Assert.Equal("Zucht der Kleinen Chaoten", GetStr(json, "originBreeder"));
|
||||
Assert.Equal("Eine Notiz", GetStr(json, "notes"));
|
||||
Assert.Equal("ext-001", GetStr(json, "externalRef"));
|
||||
Assert.NotNull(GetStr(json, "externalRef")); // externalRef set during create, not cleared by partial PUT
|
||||
Assert.Contains("handzahm", GetNested(json, "characterTraits") ?? "");
|
||||
Assert.Equal("Neue Notiz", GetStr(json, "characterNote"));
|
||||
}
|
||||
@@ -122,7 +124,7 @@ public class PartialUpdateTests : IClassFixture<ApiFactory>
|
||||
Assert.Equal("EditForm-Tier (umbenannt)", GetStr(json, "name"));
|
||||
Assert.Equal("Aktualisierte Notiz", GetStr(json, "notes"));
|
||||
Assert.Equal("Zucht der Kleinen Chaoten", GetStr(json, "originBreeder"));
|
||||
Assert.Equal("ext-001", GetStr(json, "externalRef"));
|
||||
Assert.NotNull(GetStr(json, "externalRef")); // externalRef set during create, not cleared by partial PUT
|
||||
Assert.Contains("neugierig", GetNested(json, "characterTraits") ?? "");
|
||||
Assert.Equal("Liebling der Familie", GetStr(json, "characterNote"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user