Zwei neue Buttons ("Mitarbeit", "Anwesenheit/Hausaufgabe") öffnen die
bestehenden Schnellbewertungs-Dialoge direkt aus dem Unterrichtsmodus, ohne
zum Mitarbeit-Tab wechseln zu müssen — TeachingModeViewModel bekommt dafür
eine eigene ParticipationTabViewModel-Instanz, vorselektiert auf die zu
dieser Stunde gehörende Sitzung. Die linke Spalte zeigt jetzt zusätzlich die
Hausaufgabe der letzten Stunde mit Kontrolliert-Checkbox sowie die
Hausaufgabe dieser Stunde als editierbares Feld, statt nur lesbar.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
204 lines
9.6 KiB
C#
204 lines
9.6 KiB
C#
using LehrerApp.Core.Models;
|
|
using LehrerApp.Desktop.ViewModels.Groups;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Desktop.Tests;
|
|
|
|
public sealed class TeachingModeViewModelTests
|
|
{
|
|
private static SeatingPlanTabViewModel BuildSeatingPlan(Guid groupId, FakeSessions? sessions = null,
|
|
List<Student>? students = null, List<GroupMembership>? memberships = null,
|
|
List<SeatingPlan>? plans = null) =>
|
|
new(new FakeSeatingPlans(plans ?? [new SeatingPlan { GroupId = groupId, Name = "Standard", Rows = 1, Columns = 1 }]),
|
|
new FakeStudents(students ?? []), new FakeMemberships(memberships ?? []),
|
|
sessions ?? new FakeSessions([]), new FakeEntries(), new FakeAspects());
|
|
|
|
/// Dieselben Fakes wie <see cref="BuildSeatingPlan"/>, aber für ParticipationTabViewModel —
|
|
/// beide brauchen eigene IParticipationSessionRepository/IParticipationRepository-Instanzen
|
|
/// im Produktivcode (siehe TeachingModeWindow-Kommentar zu ReloadSeatBadgesFromRepository),
|
|
/// hier reicht für die Tests aber eine gemeinsame FakeSessions-Instanz, damit beide
|
|
/// ViewModels dieselbe verknüpfte Sitzung sehen.
|
|
private static ParticipationTabViewModel BuildParticipation(LearningGroup group,
|
|
FakeSessions? sessions = null) =>
|
|
new(sessions ?? new FakeSessions([]), new FakeEntries(), new FakeAspects(),
|
|
new FakeStudents([]), new FakeMemberships([]), new FakeGroups([group]),
|
|
new FakeCompetencyDomains());
|
|
|
|
[Fact]
|
|
public void Konstruktor_LaedtVerlaufsplanUndInitialisiertSitzplanFuerDieGruppe()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var lesson = new Lesson
|
|
{
|
|
GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox",
|
|
Phases = [new LessonPhaseStep { Name = "Einstieg", DurationMinutes = 10, Activity = "Impuls" }],
|
|
};
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
new FakeLessons(), seatingPlan, BuildParticipation(group));
|
|
|
|
Assert.Equal("Q1 Chemie", vm.GroupName);
|
|
Assert.Equal("Redox", vm.LessonInfo.Topic);
|
|
Assert.Single(vm.LessonInfo.PhaseGroups.Single().Phases);
|
|
Assert.True(vm.SeatingPlan.HasSelectedPlan);
|
|
}
|
|
|
|
[Fact]
|
|
public void Konstruktor_VerknuepftDieSitzungMitDieserStunde()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var lesson = new Lesson
|
|
{ GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
|
|
var sessions = new FakeSessions([]);
|
|
var seatingPlan = BuildSeatingPlan(group.Id, sessions);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
new FakeLessons(), seatingPlan, BuildParticipation(group, sessions));
|
|
|
|
var created = Assert.Single(sessions.GetByGroup(group.Id));
|
|
Assert.Equal(lesson.Id, created.LessonId);
|
|
Assert.Equal(vm.SeatingPlan.SelectedSession?.Id, created.Id);
|
|
}
|
|
|
|
/// Nutzer-Feedback: Schnellbewertungs-Dialoge (Mitarbeit, Anwesenheit/Hausaufgabe) sollen sich
|
|
/// im Unterrichtsmodus direkt öffnen lassen — das setzt voraus, dass die dafür verwendete
|
|
/// ParticipationTabViewModel-Instanz von Anfang an auf der zu dieser Stunde gehörenden
|
|
/// Sitzung steht, nicht auf einer beliebigen anderen Sitzung der Gruppe.
|
|
[Fact]
|
|
public void Konstruktor_SelektiertDieselbeSitzungAuchInDerParticipationViewModel()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var lesson = new Lesson
|
|
{ GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
|
|
var otherSession = new ParticipationSession
|
|
{ GroupId = group.Id, Date = lesson.Date.AddDays(-1), Comment = "Andere Stunde" };
|
|
var sessions = new FakeSessions([otherSession]);
|
|
var seatingPlan = BuildSeatingPlan(group.Id, sessions);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
new FakeLessons(), seatingPlan, BuildParticipation(group, sessions));
|
|
|
|
Assert.NotNull(vm.SeatingPlan.SelectedSession);
|
|
Assert.Equal(vm.SeatingPlan.SelectedSession!.Id, vm.Participation.SelectedSession?.Id);
|
|
Assert.NotEqual(otherSession.Id, vm.Participation.SelectedSession?.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Konstruktor_BereitsExistierendeVerknuepfteSitzung_WirdWiederverwendet()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var lesson = new Lesson
|
|
{ GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
|
|
var existing = new ParticipationSession
|
|
{ GroupId = group.Id, Date = lesson.Date, LessonId = lesson.Id, Comment = "Redox" };
|
|
var sessions = new FakeSessions([existing]);
|
|
var seatingPlan = BuildSeatingPlan(group.Id, sessions);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
new FakeLessons(), seatingPlan, BuildParticipation(group, sessions));
|
|
|
|
Assert.Single(sessions.GetByGroup(group.Id));
|
|
Assert.Equal(existing.Id, vm.SeatingPlan.SelectedSession?.Id);
|
|
}
|
|
|
|
/// Eine archivierte Gruppe darf im Unterrichtsmodus nicht bearbeitbar sein - genau wie in der
|
|
/// normalen Gruppenansicht (GroupDetailViewModel.IsReadOnly).
|
|
[Fact]
|
|
public void Konstruktor_ArchivierteGruppe_InitialisiertSitzplanSchreibgeschuetzt()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie", IsActive = false };
|
|
var lesson = new Lesson
|
|
{ GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
new FakeLessons(), seatingPlan, BuildParticipation(group));
|
|
|
|
Assert.False(vm.SeatingPlan.IsEditable);
|
|
}
|
|
|
|
// ── Hausaufgabe: letzte Stunde ansehen/abhaken, aktuelle einsehen/ändern ─────
|
|
|
|
[Fact]
|
|
public void Konstruktor_FindetHausaufgabeDerVorherigenStunde()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var today = DateOnly.FromDateTime(DateTime.Today);
|
|
var previous = new Lesson
|
|
{
|
|
GroupId = group.Id, Date = today.AddDays(-7), Topic = "Säuren",
|
|
Homework = "S. 42, Aufgabe 3", HomeworkChecked = false,
|
|
};
|
|
var lesson = new Lesson { GroupId = group.Id, Date = today, Topic = "Redox" };
|
|
var lessons = new FakeLessons();
|
|
lessons.Add(previous);
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
lessons, seatingPlan, BuildParticipation(group));
|
|
|
|
Assert.True(vm.Homework.HasPreviousHomework);
|
|
Assert.Equal("S. 42, Aufgabe 3", vm.Homework.PreviousHomeworkText);
|
|
Assert.Contains("Säuren", vm.Homework.PreviousLessonLabel);
|
|
Assert.False(vm.Homework.PreviousHomeworkChecked);
|
|
}
|
|
|
|
[Fact]
|
|
public void Konstruktor_IgnoriertVorherigeStundeOhneHausaufgabe()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var today = DateOnly.FromDateTime(DateTime.Today);
|
|
var previous = new Lesson { GroupId = group.Id, Date = today.AddDays(-7), Topic = "Säuren" };
|
|
var lesson = new Lesson { GroupId = group.Id, Date = today, Topic = "Redox" };
|
|
var lessons = new FakeLessons();
|
|
lessons.Add(previous);
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
lessons, seatingPlan, BuildParticipation(group));
|
|
|
|
Assert.False(vm.Homework.HasPreviousHomework);
|
|
}
|
|
|
|
[Fact]
|
|
public void PreviousHomeworkChecked_SpeichertSofortAnDerVorherigenStunde()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var today = DateOnly.FromDateTime(DateTime.Today);
|
|
var previous = new Lesson
|
|
{ GroupId = group.Id, Date = today.AddDays(-7), Topic = "Säuren", Homework = "S. 42" };
|
|
var lesson = new Lesson { GroupId = group.Id, Date = today, Topic = "Redox" };
|
|
var lessons = new FakeLessons();
|
|
lessons.Add(previous);
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
lessons, seatingPlan, BuildParticipation(group));
|
|
|
|
vm.Homework.PreviousHomeworkChecked = true;
|
|
|
|
var saved = Assert.Single(lessons.GetByGroupAndRange(group.Id, today.AddDays(-120), today.AddDays(-1)));
|
|
Assert.True(saved.HomeworkChecked);
|
|
}
|
|
|
|
[Fact]
|
|
public void SaveCurrentHomework_SchreibtAufDieAktuelleStunde()
|
|
{
|
|
var group = new LearningGroup { Name = "Q1 Chemie" };
|
|
var lesson = new Lesson
|
|
{ GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
|
|
var lessons = new FakeLessons();
|
|
lessons.Add(lesson);
|
|
var seatingPlan = BuildSeatingPlan(group.Id);
|
|
var vm = new TeachingModeViewModel(lesson, group, new FakeAlternativeLessonPaths([]),
|
|
lessons, seatingPlan, BuildParticipation(group));
|
|
|
|
vm.Homework.CurrentHomework = "AB 7 fertigstellen";
|
|
vm.Homework.SaveCurrentHomeworkCommand.Execute(null);
|
|
|
|
var saved = Assert.Single(lessons.GetByGroupAndRange(group.Id, lesson.Date, lesson.Date));
|
|
Assert.Equal("AB 7 fertigstellen", saved.Homework);
|
|
Assert.Equal("Gespeichert.", vm.Homework.SaveStatus);
|
|
}
|
|
}
|