Kapitel 3.3: neuer Button erzeugt eine Mitarbeitssitzung aus einer geplanten Stunde (Datum/Thema, dupl.-sicher über Lesson.LessonId), Sitzungen lassen sich jetzt mit Rückfrage bei vorhandenen Bewertungen löschen, und der Dashboard-Kalender zeigt Sitzungen als dritten Termintyp neben Stunden/ Klausuren. Das Bearbeiten von Sitzungen war bereits vorhanden (undokumentiert aus früherer Ad-hoc-Arbeit) und wird hier nur nachgezogen. Bugfix: "Serie erzeugen" legte für Doppelstunden zwei Lessons mit gleichem Datum an statt einer, da jede Stundenplan-Periode einzeln behandelt wurde. Folgeperioden werden jetzt der Lesson der ersten Periode zugerechnet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
184 lines
7.7 KiB
C#
184 lines
7.7 KiB
C#
using LehrerApp.Core.Models;
|
|
using LehrerApp.Core.Services;
|
|
using LehrerApp.Desktop.ViewModels.Groups;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Desktop.Tests;
|
|
|
|
/// Tests für die Serienerzeugung von Stunden aus dem Stundenplan (4.2.5).
|
|
public sealed class GenerateLessonSeriesDialogViewModelTests
|
|
{
|
|
private static GenerateLessonSeriesDialogViewModel BuildVm(FakeTimetableSlots slots, FakeLessons lessons,
|
|
FakeSchoolHolidays holidays, Guid unitId, Guid groupId, DateOnly? from = null, DateOnly? to = null)
|
|
{
|
|
// Bewusst kein "using": SchoolCalendarSettingsService liest den Pfad nur bei Bedarf.
|
|
var tempPath = System.IO.Path.Combine(
|
|
System.IO.Path.GetTempPath(), $"lehrerapp-lessonseries-tests-{Guid.NewGuid():N}");
|
|
Directory.CreateDirectory(tempPath);
|
|
|
|
var vm = new GenerateLessonSeriesDialogViewModel(slots, lessons, holidays,
|
|
new PublicHolidayService(), new SchoolCalendarSettingsService(tempPath), unitId, groupId, null, null);
|
|
if (from is not null) vm.FromDateText = from.Value.ToString("dd.MM.yyyy");
|
|
if (to is not null) vm.ToDateText = to.Value.ToString("dd.MM.yyyy");
|
|
return vm;
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_ErzeugtStundeProVorkommenDesWochentagsImZeitraum()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var to = from.AddDays(13); // deckt zwei Vorkommen des Wochentags von "from" ab (Tag 0 und 7)
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 1 });
|
|
var lessons = new FakeLessons();
|
|
var vm = BuildVm(slots, lessons, new FakeSchoolHolidays(), unitId, groupId, from, to);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.NotNull(vm.Result);
|
|
Assert.Equal(2, vm.Result!.Created);
|
|
Assert.Equal(0, vm.Result.SkippedHoliday);
|
|
Assert.Equal(0, vm.Result.SkippedExisting);
|
|
Assert.All(lessons.GetByGroupAndRange(groupId, from, to), l => Assert.Equal(unitId, l.UnitId));
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_UeberspringtTerminInSchulferien()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var to = from.AddDays(13);
|
|
var secondOccurrence = from.AddDays(7);
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 1 });
|
|
var holidays = new FakeSchoolHolidays();
|
|
holidays.Add(new SchoolHoliday { Name = "Ferien", StartDate = secondOccurrence, EndDate = secondOccurrence.AddDays(3) });
|
|
var vm = BuildVm(slots, new FakeLessons(), holidays, unitId, groupId, from, to);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Equal(1, vm.Result!.Created);
|
|
Assert.Equal(1, vm.Result.SkippedHoliday);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_UeberspringtBereitsVorhandeneStundeAmSelbenDatumUndPeriode()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var to = from.AddDays(13);
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 1 });
|
|
var lessons = new FakeLessons();
|
|
lessons.Add(new Lesson { UnitId = Guid.NewGuid(), GroupId = groupId, Date = from, LessonNumber = 1, Topic = "Bestehend" });
|
|
var vm = BuildVm(slots, lessons, new FakeSchoolHolidays(), unitId, groupId, from, to);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Equal(1, vm.Result!.Created);
|
|
Assert.Equal(1, vm.Result.SkippedExisting);
|
|
Assert.Equal(2, lessons.GetByGroupAndRange(groupId, from, to).Count); // 1 alt + 1 neu
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_Doppelstunde_ErzeugtNurEineStundeVerankertAnDerErstenPeriode()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 3 });
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 4 });
|
|
var lessons = new FakeLessons();
|
|
var vm = BuildVm(slots, lessons, new FakeSchoolHolidays(), unitId, groupId, from, from);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Equal(1, vm.Result!.Created);
|
|
var created = lessons.GetByGroupAndRange(groupId, from, from).Select(l => l.LessonNumber).ToList();
|
|
Assert.Equal([3], created);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_Dreifachstunde_ErzeugtNurEineStundeVerankertAnDerErstenPeriode()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 3 });
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 4 });
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 5 });
|
|
var lessons = new FakeLessons();
|
|
var vm = BuildVm(slots, lessons, new FakeSchoolHolidays(), unitId, groupId, from, from);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Equal(1, vm.Result!.Created);
|
|
var created = lessons.GetByGroupAndRange(groupId, from, from).Select(l => l.LessonNumber).ToList();
|
|
Assert.Equal([3], created);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_ZweiGetrennteEinzelstundenAmSelbenTagBleibenGetrennt()
|
|
{
|
|
// Perioden 1 und 3 sind NICHT aufeinanderfolgend (Periode 2 fehlt) — keine Doppelstunde,
|
|
// beide bekommen eine eigene Lesson.
|
|
var groupId = Guid.NewGuid();
|
|
var unitId = Guid.NewGuid();
|
|
var from = new DateOnly(2025, 9, 1);
|
|
var slots = new FakeTimetableSlots();
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 1 });
|
|
slots.Add(new TimetableSlot { GroupId = groupId, Weekday = from.DayOfWeek, PeriodNumber = 3 });
|
|
var lessons = new FakeLessons();
|
|
var vm = BuildVm(slots, lessons, new FakeSchoolHolidays(), unitId, groupId, from, from);
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Equal(2, vm.Result!.Created);
|
|
var created = lessons.GetByGroupAndRange(groupId, from, from).Select(l => l.LessonNumber).OrderBy(n => n).ToList();
|
|
Assert.Equal([1, 3], created);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_OhneStundenplanEintrag_SetztFehlerUndErzeugtNichts()
|
|
{
|
|
var groupId = Guid.NewGuid();
|
|
var vm = BuildVm(new FakeTimetableSlots(), new FakeLessons(), new FakeSchoolHolidays(), Guid.NewGuid(), groupId,
|
|
new DateOnly(2025, 9, 1), new DateOnly(2025, 9, 14));
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Null(vm.Result);
|
|
Assert.NotEqual("", vm.DateError);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_UngueltigesDatumsformat_SetztFehler()
|
|
{
|
|
var vm = BuildVm(new FakeTimetableSlots(), new FakeLessons(), new FakeSchoolHolidays(), Guid.NewGuid(), Guid.NewGuid());
|
|
vm.FromDateText = "keinDatum";
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Null(vm.Result);
|
|
Assert.NotEqual("", vm.DateError);
|
|
}
|
|
|
|
[Fact]
|
|
public void Save_EndeVorBeginn_SetztFehler()
|
|
{
|
|
var vm = BuildVm(new FakeTimetableSlots(), new FakeLessons(), new FakeSchoolHolidays(), Guid.NewGuid(), Guid.NewGuid(),
|
|
new DateOnly(2025, 9, 10), new DateOnly(2025, 9, 1));
|
|
|
|
vm.SaveCommand.Execute(null);
|
|
|
|
Assert.Null(vm.Result);
|
|
Assert.NotEqual("", vm.DateError);
|
|
}
|
|
}
|