using GerbilManagerWebAPI.Models; using GerbilManagerWebAPI.Services; namespace GerbilManager.Tests; /// STATUS-MODEL: GerbilStatusService.Derive() precedence rules. public class GerbilStatusTests { private static readonly DateOnly Today = new(2026, 6, 7); // 1) DateOfDeath → Deceased, always overrides user input [Fact] public void DateOfDeath_set_returns_Deceased() { var status = GerbilStatusService.Derive( GerbilStatus.Breeding, new DateOnly(2020, 1, 1), new DateOnly(2024, 3, 4), isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Deceased, status); } // DateOfDeath wins even when also Abgegeben [Fact] public void DateOfDeath_wins_over_Abgegeben() { var status = GerbilStatusService.Derive( GerbilStatus.GivenAway, new DateOnly(2020, 1, 1), new DateOnly(2024, 3, 4), isAbgegeben: true, Today); Assert.Equal(GerbilStatus.Deceased, status); } // 2) Abgegeben without death date → GivenAway [Fact] public void ReceiverContact_set_returns_GivenAway() { var status = GerbilStatusService.Derive( GerbilStatus.Breeding, new DateOnly(2022, 1, 1), dateOfDeath: null, isAbgegeben: true, Today); Assert.Equal(GerbilStatus.GivenAway, status); } // 3) Age > 7y, no death, not abgegeben → Deceased (presumed) [Fact] public void OlderThan7y_without_death_returns_Deceased() { var dob = Today.AddYears(-GerbilStatusService.MaxAgeYears).AddDays(-1); // 1 day past threshold var status = GerbilStatusService.Derive( GerbilStatus.Breeding, dob, dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Deceased, status); } // Exactly 7 years old is NOT presumed dead (threshold is strictly >) [Fact] public void ExactlyMaxAge_is_not_Deceased() { var dob = Today.AddYears(-GerbilStatusService.MaxAgeYears); // exactly 7y today var status = GerbilStatusService.Derive( GerbilStatus.Breeding, dob, dateOfDeath: null, isAbgegeben: false, Today); // today >= dob.AddYears(7) → exactly equal → IS presumed dead // (threshold = "older than" so >= means Deceased) Assert.Equal(GerbilStatus.Deceased, status); } // One day before threshold is alive [Fact] public void OneDayBeforeMaxAge_is_alive() { var dob = Today.AddYears(-GerbilStatusService.MaxAgeYears).AddDays(1); var status = GerbilStatusService.Derive( GerbilStatus.Breeding, dob, dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Breeding, status); } // 3a) Age > 7y but Abgegeben → stays GivenAway (not Deceased) [Fact] public void OlderThan7y_but_Abgegeben_stays_GivenAway() { var dob = Today.AddYears(-8); var status = GerbilStatusService.Derive( GerbilStatus.GivenAway, dob, dateOfDeath: null, isAbgegeben: true, Today); Assert.Equal(GerbilStatus.GivenAway, status); } // 4) Default → Breeding [Fact] public void No_special_condition_returns_Breeding() { var status = GerbilStatusService.Derive( GerbilStatus.Breeding, new DateOnly(2024, 1, 1), dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Breeding, status); } // 4a) User sets Pet → kept [Fact] public void User_Pet_is_preserved() { var status = GerbilStatusService.Derive( GerbilStatus.Pet, new DateOnly(2024, 1, 1), dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Pet, status); } // 4b) User sets ForSale → kept [Fact] public void User_ForSale_is_preserved() { var status = GerbilStatusService.Derive( GerbilStatus.ForSale, new DateOnly(2024, 1, 1), dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.ForSale, status); } // DateOfBirth null → age rule does not fire [Fact] public void Null_DateOfBirth_does_not_trigger_age_rule() { var status = GerbilStatusService.Derive( GerbilStatus.Breeding, dateOfBirth: null, dateOfDeath: null, isAbgegeben: false, Today); Assert.Equal(GerbilStatus.Breeding, status); } }