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:
2026-08-14 00:50:57 +02:00
co-authored by Claude Sonnet 5
parent 27359794f7
commit de6ea001e7
28 changed files with 2372 additions and 32 deletions
+64
View File
@@ -424,4 +424,68 @@ public sealed class RepositoryTests
Assert.Null(db.Documentation.FindById(doc.Id));
Assert.Null(storage.OpenRead(attachmentId));
}
// ── LessonRepository ──────────────────────────────────────────────────────
[Fact]
public void LessonRepository_GetByUnit_SortiertNachDatumDannStundennummer()
{
using var db = NewInMemoryContext();
var repo = new LessonRepository(db);
var unitId = Guid.NewGuid();
var groupId = Guid.NewGuid();
// Doppelstunde am selben Tag: Stunde 2 vor Stunde 1 eingefügt, muss trotzdem
// nach LessonNumber sortiert erscheinen.
repo.Save(new Lesson { UnitId = unitId, GroupId = groupId, Date = new DateOnly(2025, 9, 8), LessonNumber = 2 });
repo.Save(new Lesson { UnitId = unitId, GroupId = groupId, Date = new DateOnly(2025, 9, 8), LessonNumber = 1 });
repo.Save(new Lesson { UnitId = unitId, GroupId = groupId, Date = new DateOnly(2025, 9, 1), LessonNumber = 1 });
var result = repo.GetByUnit(unitId);
Assert.Equal(new DateOnly(2025, 9, 1), result[0].Date);
Assert.Equal(new DateOnly(2025, 9, 8), result[1].Date);
Assert.Equal(1, result[1].LessonNumber);
Assert.Equal(new DateOnly(2025, 9, 8), result[2].Date);
Assert.Equal(2, result[2].LessonNumber);
}
// ── ShorthandCodeRepository ───────────────────────────────────────────────
[Fact]
public void ShorthandCodeRepository_Save_LehntDuplikatCodeAb()
{
using var db = NewInMemoryContext();
var repo = new ShorthandCodeRepository(db);
repo.Save(new ShorthandCode { Code = "Tb", Label = "Tafelbild" });
Assert.Throws<InvalidOperationException>(() =>
repo.Save(new ShorthandCode { Code = "tb", Label = "Anderes Tafelbild" }));
}
[Fact]
public void ShorthandCodeRepository_GetAll_SortiertNachCode()
{
using var db = NewInMemoryContext();
var repo = new ShorthandCodeRepository(db);
repo.Save(new ShorthandCode { Code = "SH", Label = "Schülerheft" });
repo.Save(new ShorthandCode { Code = "AB", Label = "Arbeitsblatt" });
var result = repo.GetAll();
Assert.Equal(["AB", "SH"], result.Select(c => c.Code));
}
[Fact]
public void ShorthandCodeRepository_Delete_EntferntEintrag()
{
using var db = NewInMemoryContext();
var repo = new ShorthandCodeRepository(db);
repo.Save(new ShorthandCode { Code = "Tb", Label = "Tafelbild" });
var id = repo.GetAll().Single().Id;
repo.Delete(id);
Assert.Empty(repo.GetAll());
}
}