using LehrerApp.Core.Models; using LehrerApp.Desktop.ViewModels.Planning; using Xunit; namespace LehrerApp.Desktop.Tests; public sealed class SubstitutionEntryDialogViewModelTests { private static SubstitutionEntryDialogViewModel BuildVm( FakeSubstitutionEntries? substitutions = null, FakeGroups? groups = null, FakeUnits? units = null, FakeLessons? lessons = null) => new(substitutions ?? new FakeSubstitutionEntries(), groups ?? new FakeGroups([]), units ?? new FakeUnits(), lessons ?? new FakeLessons()); [Fact] public void Save_Aufsicht_GueltigeEingabe_ErzeugtSupervisionEntry() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Aufsicht"; vm.AfterPeriod = 2; vm.Description = "Vertretung für Hr. Müller"; vm.SaveCommand.Execute(null); Assert.NotNull(vm.Result); var saved = Assert.Single(substitutions.GetAll()); Assert.Equal(SubstitutionKind.Supervision, saved.Kind); Assert.Equal(2, saved.AfterPeriod); Assert.Equal("Vertretung für Hr. Müller", saved.Description); } [Fact] public void Save_Aufsicht_FehlenderGrund_SetztFehlerUndSpeichertNicht() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Aufsicht"; vm.AfterPeriod = 2; vm.SaveCommand.Execute(null); Assert.Null(vm.Result); Assert.Empty(substitutions.GetAll()); Assert.NotEqual("", vm.ValidationError); } [Fact] public void Save_Stunde_FremdeGruppe_ErzeugtEintragOhneGroupId() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Stunde"; vm.PeriodNumber = 3; vm.GroupLabel = "8a"; vm.Description = "Vertretung Erdkunde"; vm.SaveCommand.Execute(null); var saved = Assert.Single(substitutions.GetAll()); Assert.Null(saved.GroupId); Assert.Equal("8a", saved.GroupLabel); Assert.Equal(SubstitutionKind.Lesson, saved.Kind); } [Fact] public void Save_Stunde_EigeneGruppeOhnePromote_ErzeugtKeineLesson() { var group = new LearningGroup { Name = "Q1 Chemie" }; var unit = new Unit { GroupId = group.Id, Title = "Optik" }; var units = new FakeUnits(); units.Add(unit); var lessons = new FakeLessons(); var vm = BuildVm(groups: new FakeGroups([group]), units: units, lessons: lessons); vm.DateText = "12.03.2026"; vm.KindName = "Stunde"; vm.PeriodNumber = 3; vm.SelectedOwnGroup = group; vm.Description = "Stillarbeit"; vm.SaveCommand.Execute(null); Assert.NotNull(vm.Result); Assert.Empty(lessons.GetByUnit(unit.Id)); } [Fact] public void Save_Stunde_EigeneGruppeMitPromote_ErzeugtZusaetzlichLesson() { var group = new LearningGroup { Name = "Q1 Chemie" }; var unit = new Unit { GroupId = group.Id, Title = "Optik" }; var units = new FakeUnits(); units.Add(unit); var lessons = new FakeLessons(); var vm = BuildVm(groups: new FakeGroups([group]), units: units, lessons: lessons); vm.DateText = "12.03.2026"; vm.KindName = "Stunde"; vm.PeriodNumber = 3; vm.SelectedOwnGroup = group; // füllt UnitsOfSelectedGroup + SelectedUnit vm.Description = "Brechung (vorgezogen)"; vm.PromoteToLesson = true; vm.SaveCommand.Execute(null); var lesson = Assert.Single(lessons.GetByUnit(unit.Id)); Assert.Equal(group.Id, lesson.GroupId); Assert.Equal(3, lesson.LessonNumber); Assert.Equal("Brechung (vorgezogen)", lesson.Topic); Assert.Equal(new DateOnly(2026, 3, 12), lesson.Date); } [Fact] public void SelectedOwnGroupChanged_FuelltGroupLabelUndEinheitenListe() { var group = new LearningGroup { Name = "Q1 Chemie" }; var unit = new Unit { GroupId = group.Id, Title = "Optik" }; var units = new FakeUnits(); units.Add(unit); var vm = BuildVm(groups: new FakeGroups([group]), units: units); vm.SelectedOwnGroup = group; Assert.Equal("Q1 Chemie", vm.GroupLabel); Assert.Single(vm.UnitsOfSelectedGroup); Assert.Equal(unit.Id, vm.SelectedUnit!.Id); } [Fact] public void CanPromoteToLesson_FalseWennGruppeKeineEinheitenHat() { var group = new LearningGroup { Name = "Q1 Chemie" }; var vm = BuildVm(groups: new FakeGroups([group])); vm.KindName = "Stunde"; vm.SelectedOwnGroup = group; Assert.False(vm.CanPromoteToLesson); } [Fact] public void Save_UngueltigesDatum_SetztFehler() { var vm = BuildVm(); vm.DateText = "keinDatum"; vm.KindName = "Aufsicht"; vm.Description = "x"; vm.SaveCommand.Execute(null); Assert.Null(vm.Result); Assert.NotEqual("", vm.DateError); } // ── Sondereinsatz ───────────────────────────────────────────────────────── [Fact] public void Save_Sondereinsatz_Ganztaegig_ErzeugtEintragOhneStundenbereich() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Sondereinsatz"; vm.IsAllDay = true; vm.Description = "Ausflug ins Museum"; vm.SaveCommand.Execute(null); var saved = Assert.Single(substitutions.GetAll()); Assert.Equal(SubstitutionKind.SpecialAssignment, saved.Kind); Assert.True(saved.IsAllDay); Assert.Null(saved.FromPeriod); Assert.Null(saved.ToPeriod); } [Fact] public void Save_Sondereinsatz_MitStundenbereich_SpeichertVonBis() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Sondereinsatz"; vm.IsAllDay = false; vm.FromPeriod = 3; vm.ToPeriod = 4; vm.Description = "Berufsmesse"; vm.SaveCommand.Execute(null); var saved = Assert.Single(substitutions.GetAll()); Assert.False(saved.IsAllDay); Assert.Equal(3, saved.FromPeriod); Assert.Equal(4, saved.ToPeriod); } [Fact] public void Save_Sondereinsatz_BisVorVon_SetztFehler() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Sondereinsatz"; vm.IsAllDay = false; vm.FromPeriod = 5; vm.ToPeriod = 2; vm.Description = "Berufsmesse"; vm.SaveCommand.Execute(null); Assert.Null(vm.Result); Assert.Empty(substitutions.GetAll()); Assert.NotEqual("", vm.ValidationError); } [Fact] public void Save_Sondereinsatz_OhneBeschreibung_SetztFehler() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Sondereinsatz"; vm.SaveCommand.Execute(null); Assert.Null(vm.Result); Assert.Empty(substitutions.GetAll()); Assert.NotEqual("", vm.ValidationError); } [Fact] public void Save_Sondereinsatz_OhneGruppe_SpeichertLeeresGroupLabel() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Sondereinsatz"; vm.Description = "Berufsmesse"; vm.SaveCommand.Execute(null); var saved = Assert.Single(substitutions.GetAll()); Assert.Null(saved.GroupId); Assert.Equal("", saved.GroupLabel); } [Fact] public void CanPromoteToLesson_FalseFuerSondereinsatz() { var group = new LearningGroup { Name = "Q1 Chemie" }; var unit = new Unit { GroupId = group.Id, Title = "Optik" }; var units = new FakeUnits(); units.Add(unit); var vm = BuildVm(groups: new FakeGroups([group]), units: units); vm.KindName = "Sondereinsatz"; vm.SelectedOwnGroup = group; Assert.False(vm.CanPromoteToLesson); } // ── Ausfall ─────────────────────────────────────────────────────────────── [Fact] public void Save_Ausfall_GueltigeEingabe_ErzeugtEintragMitPeriodeUndGrund() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Ausfall"; vm.PeriodNumber = 2; vm.Description = "6a auf Klassenfahrt"; vm.SaveCommand.Execute(null); var saved = Assert.Single(substitutions.GetAll()); Assert.Equal(SubstitutionKind.Cancelled, saved.Kind); Assert.Equal(2, saved.PeriodNumber); Assert.Equal("6a auf Klassenfahrt", saved.Description); } [Fact] public void Save_Ausfall_OhneGrund_IstErlaubt() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Ausfall"; vm.PeriodNumber = 2; vm.SaveCommand.Execute(null); Assert.NotNull(vm.Result); Assert.Single(substitutions.GetAll()); } [Fact] public void Save_Ausfall_UngueltigePeriode_SetztFehler() { var substitutions = new FakeSubstitutionEntries(); var vm = BuildVm(substitutions); vm.DateText = "12.03.2026"; vm.KindName = "Ausfall"; vm.PeriodNumber = 11; vm.SaveCommand.Execute(null); Assert.Null(vm.Result); Assert.Empty(substitutions.GetAll()); Assert.NotEqual("", vm.ValidationError); } [Fact] public void CanPromoteToLesson_FalseFuerAusfall() { var group = new LearningGroup { Name = "Q1 Chemie" }; var unit = new Unit { GroupId = group.Id, Title = "Optik" }; var units = new FakeUnits(); units.Add(unit); var vm = BuildVm(groups: new FakeGroups([group]), units: units); vm.KindName = "Ausfall"; vm.SelectedOwnGroup = group; Assert.False(vm.CanPromoteToLesson); } }