Unterrichtsplanung: Einheiten, Verlaufsplan-Editor, Kürzel-Katalog (Kapitel 4.1/4.2)
Neuer Tab "Planung" in GroupDetailView ersetzt den Platzhalter: Einheiten anlegen/bearbeiten/ als Vorlage in andere Gruppe kopieren, Stunden je Einheit mit Verschieben (inkl. Nachrücken der Folgestunden). Stundeneditor als tabellarischer Verlaufsplan (Phase/Dauer/Tätigkeit/ Material/Kurzsymbol je Zeile, Uhrzeit aus optionalem Stundenbeginn abgeleitet) statt eines einzelnen Phase-Felds mit Methoden-/Materialien-Chips — Kurzsymbol als Freitext mit Vorschlägen aus neuem Kürzel-Katalog (Einstellungen) plus bisher verwendeten Werten. Schema-Migrationen v1-v3 überführen bestehende Daten verlustfrei. 4.2.5 bewusst offen gelassen (hängt an Stundenplan, Kapitel 4.3). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Desktop.ViewModels.Groups;
|
||||
using Xunit;
|
||||
|
||||
namespace LehrerApp.Desktop.Tests;
|
||||
|
||||
public sealed class LessonDialogViewModelTests
|
||||
{
|
||||
private static LessonDialogViewModel BuildVm(Guid unitId, Guid groupId, Lesson? editing = null) =>
|
||||
new(new FakeLessons(), new FakeShorthandCodes([]), unitId, groupId, [], [], editing);
|
||||
|
||||
[Fact]
|
||||
public void AddPhase_FuegtZeileMitStandardwertenHinzu()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
|
||||
Assert.Single(vm.Phases);
|
||||
Assert.Equal(5, vm.Phases[0].DurationMinutes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemovePhase_EntferntZeileUndAktualisiertGesamtdauer()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[0].DurationMinutes = 20;
|
||||
|
||||
vm.Phases[0].RemoveCommand.Execute(null);
|
||||
|
||||
Assert.Empty(vm.Phases);
|
||||
Assert.Equal("0 Minuten gesamt", vm.TotalDurationDisplay);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveDown_VertauschtReihenfolgeDerPhasen()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[0].Name = "Einstieg";
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[1].Name = "Erarbeitung";
|
||||
|
||||
vm.Phases[0].MoveDownCommand.Execute(null);
|
||||
|
||||
Assert.Equal("Erarbeitung", vm.Phases[0].Name);
|
||||
Assert.Equal("Einstieg", vm.Phases[1].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shorthand_IstFreitextOhneErzwungeneVonNachStruktur()
|
||||
{
|
||||
// Kurzsymbol muss nicht immer ein Materialfluss-Pfeil sein — manchmal nur eine
|
||||
// Sozialform ohne Pfeil (z.B. "Plenum", "LDE").
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
var phase = vm.Phases[0];
|
||||
|
||||
phase.Shorthand = "Plenum";
|
||||
Assert.Equal("Plenum", phase.Shorthand);
|
||||
|
||||
phase.Shorthand = "AB001->S";
|
||||
Assert.Equal("AB001->S", phase.Shorthand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShorthandSuggestions_KombiniertKatalogUndBisherigeStundenwerte()
|
||||
{
|
||||
var codes = new FakeShorthandCodes([new ShorthandCode { Code = "Tb" }, new ShorthandCode { Code = "SH" }]);
|
||||
var vm = new LessonDialogViewModel(new FakeLessons(), codes, Guid.NewGuid(), Guid.NewGuid(),
|
||||
[], ["Plenum", "LDE", "Tb"], null); // "Tb" doppelt (Katalog + Historie), soll nur einmal erscheinen
|
||||
|
||||
Assert.Equal(["LDE", "Plenum", "SH", "Tb"], vm.ShorthandSuggestions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecomputeTimes_LeitetUhrzeitJePhaseAusBeginnUndKumulierterDauerAb()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.StartTimeText = "12:00";
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[0].DurationMinutes = 15;
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[1].DurationMinutes = 10;
|
||||
|
||||
Assert.Equal("ab 12:00", vm.Phases[0].ComputedTimeDisplay);
|
||||
Assert.Equal("ab 12:15", vm.Phases[1].ComputedTimeDisplay);
|
||||
Assert.Equal("25 Minuten gesamt", vm.TotalDurationDisplay);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecomputeTimes_OhneBeginnBleibtDieUhrzeitanzeigeLeer()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[0].DurationMinutes = 15;
|
||||
|
||||
Assert.Equal("", vm.Phases[0].ComputedTimeDisplay);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Save_ErfordertThemaUndGueltigesDatum()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.Topic = ""; vm.DateText = "keinDatum";
|
||||
|
||||
vm.SaveCommand.Execute(null);
|
||||
|
||||
Assert.Null(vm.Result);
|
||||
Assert.NotEqual("", vm.TopicError);
|
||||
Assert.NotEqual("", vm.DateTextError);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Save_UngueltigesBeginnFormatWirdAbgelehnt()
|
||||
{
|
||||
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||
vm.Topic = "Thema"; vm.DateText = "01.09.2025"; vm.StartTimeText = "nicht-uhrzeit";
|
||||
|
||||
vm.SaveCommand.Execute(null);
|
||||
|
||||
Assert.Null(vm.Result);
|
||||
Assert.NotEqual("", vm.StartTimeTextError);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Save_SetztUnitIdGroupIdUndUebernimmtPhasenUndBeginn()
|
||||
{
|
||||
var unitId = Guid.NewGuid();
|
||||
var groupId = Guid.NewGuid();
|
||||
var lessons = new FakeLessons();
|
||||
var vm = new LessonDialogViewModel(lessons, new FakeShorthandCodes([]), unitId, groupId, [], [], null)
|
||||
{
|
||||
Topic = "Brechung", DateText = "01.09.2025", StartTimeText = "11:45",
|
||||
};
|
||||
vm.AddPhaseCommand.Execute(null);
|
||||
vm.Phases[0].Name = "Einstieg";
|
||||
vm.Phases[0].DurationMinutes = 10;
|
||||
vm.Phases[0].Activity = "Begrüßung";
|
||||
vm.Phases[0].Material = "AB01";
|
||||
vm.Phases[0].Shorthand = "L->AB01";
|
||||
|
||||
vm.SaveCommand.Execute(null);
|
||||
|
||||
Assert.NotNull(vm.Result);
|
||||
Assert.Equal(unitId, vm.Result!.UnitId);
|
||||
Assert.Equal(groupId, vm.Result.GroupId);
|
||||
Assert.Equal(new TimeOnly(11, 45), vm.Result.StartTime);
|
||||
Assert.Single(vm.Result.Phases);
|
||||
Assert.Equal("Einstieg", vm.Result.Phases[0].Name);
|
||||
Assert.Equal(10, vm.Result.Phases[0].DurationMinutes);
|
||||
Assert.Equal("L->AB01", vm.Result.Phases[0].Shorthand);
|
||||
Assert.Single(lessons.GetByUnit(unitId));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user