Unterrichtsplanung: Serienerzeugung, Stundenraster, Aufsichten & Vertretung (Kapitel 4.2/4.3 Nachtrag)
Stunden serienweise aus dem Stundenplan erzeugen (4.2.5); Stundenraster (Uhrzeiten je Stunde) in den Einstellungen mit Zeitbedarf-Rückmeldung im Verlaufsplan-Editor; wiederkehrende Pausenaufsicht; neuer "Vertretung eintragen"-Dialog für einmalige Vertretungsaufsicht, Vertretungsstunde, Sondereinsätze (Ausflüge, Berufsmessen) und schlichten Stundenausfall. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user