Files
LehrerApp/LehrerApp.Desktop.Tests/GenerateLessonSeriesDialogViewModelTests.cs
T
adminandClaude Sonnet 5 d6dee72acc 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>
2026-08-15 21:59:07 +02:00

143 lines
5.8 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_ErzeugtZweiStundenAmSelbenTagMitUnterschiedlicherStundennummer()
{
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(2, vm.Result!.Created);
var created = lessons.GetByGroupAndRange(groupId, from, from).Select(l => l.LessonNumber).OrderBy(n => n).ToList();
Assert.Equal([3, 4], 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);
}
}