Files
LehrerApp/LehrerApp.Desktop.Tests/StudentGroupGeneratorViewModelTests.cs
T
admin d4b1419f9a
CI / build-and-test (push) Canceled after 0s
Add configurable student group generator
2026-09-29 14:22:59 +02:00

186 lines
7.5 KiB
C#

using LehrerApp.Core.Models;
using LehrerApp.Desktop.ViewModels.Groups;
using Xunit;
namespace LehrerApp.Desktop.Tests;
public sealed class StudentGroupGeneratorViewModelTests
{
private static (StudentGroupGeneratorViewModel Vm, List<Student> Students, LearningGroup Group,
FakeSessions Sessions, FakeEntries Entries) Build(int studentCount = 10)
{
var group = new LearningGroup { Name = "8a", GradingSystem = GradingSystem.Grades1To6 };
var students = Enumerable.Range(1, studentCount).Select(i => new Student
{
FirstName = $"Kind{i:00}", LastName = "Test",
}).ToList();
var memberships = students.Select(s => new GroupMembership
{
GroupId = group.Id, StudentId = s.Id,
}).ToList();
var sessions = new FakeSessions([]);
var entries = new FakeEntries();
var vm = new StudentGroupGeneratorViewModel(
new FakeStudents(students), new FakeGroups([group]), new FakeMemberships(memberships),
sessions, entries, new FakeGrades(), group.Id, new Random(7));
return (vm, students, group, sessions, entries);
}
[Fact]
public void FesteZielgroesse_ErzeugtPassendeAnzahlMitKleinerAusnahme()
{
var (vm, _, _, _, _) = Build(10);
vm.TargetGroupSize = 4;
vm.TargetGroupCount = 2;
vm.SizePriority = 100;
vm.CountPriority = 20;
vm.GenerateCommand.Execute(null);
Assert.Equal(3, vm.GeneratedGroups.Count);
Assert.Equal(new[] { 3, 3, 4 }, vm.GeneratedGroups.Select(g => g.Members.Count).OrderBy(x => x));
Assert.Contains("nicht gleichzeitig", vm.WarningText);
}
[Fact]
public void FesteGruppenanzahl_HatVorrangVorZielgroesse()
{
var (vm, _, _, _, _) = Build(10);
vm.TargetGroupSize = 3;
vm.TargetGroupCount = 2;
vm.SizePriority = 20;
vm.CountPriority = 100;
vm.GenerateCommand.Execute(null);
Assert.Equal(2, vm.GeneratedGroups.Count);
Assert.All(vm.GeneratedGroups, group => Assert.Equal(5, group.Members.Count));
}
[Fact]
public void AdHoc_SchliesstHeuteAbwesendeAus()
{
var (vm, students, group, sessions, entries) = Build(6);
var session = new ParticipationSession { GroupId = group.Id, Date = DateOnly.FromDateTime(DateTime.Today) };
sessions.Save(session);
entries.Add(new ParticipationEntry
{
SessionId = session.Id, StudentId = students[0].Id, Attendance = AttendanceStatus.Excused,
});
vm.ParticipantModeName = StudentGroupGeneratorViewModel.AdHocModeLabel;
vm.TargetGroupCount = 2;
vm.CountPriority = 100;
vm.GenerateCommand.Execute(null);
var names = vm.GeneratedGroups.SelectMany(g => g.Members).Select(m => m.Name).ToList();
Assert.Equal(5, names.Count);
Assert.DoesNotContain(students[0].FullName, names);
Assert.Contains("fehlt heute", vm.WarningText);
}
[Fact]
public void AdHoc_OhneHeutigeErfassung_WarntUndNutztAlleAktiven()
{
var (vm, students, _, _, _) = Build(6);
vm.ParticipantModeName = StudentGroupGeneratorViewModel.AdHocModeLabel;
vm.GenerateCommand.Execute(null);
Assert.Equal(students.Count, vm.GeneratedGroups.SelectMany(g => g.Members).Count());
Assert.Contains("keine Anwesenheit", vm.WarningText);
}
[Fact]
public void Leistungsverteilung_UnterscheidetHomogeneUndHeterogeneGruppen()
{
var group = new LearningGroup { Name = "Kurs", GradingSystem = GradingSystem.Grades1To6 };
var students = new[] { "A", "B", "C", "D" }.Select(name => new Student
{
FirstName = name, LastName = "Test",
}).ToList();
var memberships = students.Select(s => new GroupMembership { GroupId = group.Id, StudentId = s.Id }).ToList();
var grades = new FakeGrades();
var values = new[] { "1", "2", "5", "6" };
for (var i = 0; i < students.Count; i++)
grades.Add(new Grade { GroupId = group.Id, StudentId = students[i].Id, Value = values[i] });
var vm = new StudentGroupGeneratorViewModel(
new FakeStudents(students), new FakeGroups([group]), new FakeMemberships(memberships),
new FakeSessions([]), new FakeEntries(), grades, group.Id, new Random(3))
{
TargetGroupCount = 2,
CountPriority = 100,
PerformanceDistribution = -100,
};
vm.GenerateCommand.Execute(null);
var homogeneousFirst = vm.GeneratedGroups[0].Members.Select(m => m.Name).ToHashSet();
Assert.Contains(students[0].FullName, homogeneousFirst);
Assert.Contains(students[1].FullName, homogeneousFirst);
vm.PerformanceDistribution = 100;
vm.GenerateCommand.Execute(null);
Assert.All(vm.GeneratedGroups, generated =>
{
var names = generated.Members.Select(m => m.Name).ToHashSet();
Assert.True(names.Overlaps([students[0].FullName, students[1].FullName]));
Assert.True(names.Overlaps([students[2].FullName, students[3].FullName]));
});
}
[Fact]
public void Paarregeln_ErzwingenZusammenUndTrennenMitHoherPrioritaet()
{
var (vm, students, _, _, _) = Build(6);
vm.TargetGroupCount = 2;
vm.CountPriority = 100;
vm.PerformanceDistribution = 0;
vm.ForcedPairPriority = 100;
vm.SelectedPairStudentA = vm.PairCandidates.Single(s => s.Id == students[0].Id);
vm.SelectedPairStudentB = vm.PairCandidates.Single(s => s.Id == students[1].Id);
vm.AddForcedPairCommand.Execute(null);
vm.SelectedPairStudentA = vm.PairCandidates.Single(s => s.Id == students[2].Id);
vm.SelectedPairStudentB = vm.PairCandidates.Single(s => s.Id == students[3].Id);
vm.AddExcludedPairCommand.Execute(null);
vm.GenerateCommand.Execute(null);
var groupByName = vm.GeneratedGroups.SelectMany((group, index) =>
group.Members.Select(member => (member.Name, index)))
.ToDictionary(x => x.Name, x => x.index);
Assert.Equal(groupByName[students[0].FullName], groupByName[students[1].FullName]);
Assert.NotEqual(groupByName[students[2].FullName], groupByName[students[3].FullName]);
}
[Fact]
public void FoerderschuelerWerdenMoeglichstGleichmaessigVerteilt()
{
var group = new LearningGroup { Name = "Kurs" };
var students = Enumerable.Range(1, 8).Select(i => new Student
{
FirstName = $"Kind{i}", LastName = "Test",
}).ToList();
var memberships = students.Select((student, index) => new GroupMembership
{
GroupId = group.Id,
StudentId = student.Id,
Niveau = index < 4 ? Niveau.Foerder : null,
}).ToList();
var vm = new StudentGroupGeneratorViewModel(
new FakeStudents(students), new FakeGroups([group]), new FakeMemberships(memberships),
new FakeSessions([]), new FakeEntries(), new FakeGrades(), group.Id, new Random(4))
{
TargetGroupCount = 2,
CountPriority = 100,
PerformanceDistribution = -100,
DistributeSupportStudents = true,
};
vm.GenerateCommand.Execute(null);
var supportNames = students.Take(4).Select(s => s.FullName).ToHashSet();
Assert.All(vm.GeneratedGroups, generated =>
Assert.Equal(2, generated.Members.Count(member => supportNames.Contains(member.Name))));
}
}