Files
LehrerApp/LehrerApp.Tests/ExamScoringServiceTests.cs
T
adminandClaude Sonnet 5.5 651c9cddf8 Förderarbeit als dritte Folgearbeits-Art ergänzen
Neben Wiederholung und Nachschreibarbeit gibt es im Arbeitsdialog die Art
Förderarbeit (Exam.IsSupportWork). Sie darf am Tag der ersten Arbeit liegen,
übernimmt dessen Datum als Vorschlag und ersetzt wie eine Nachschreibarbeit
nur fehlende Noten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:55:27 +02:00

155 lines
6.1 KiB
C#

using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
using Xunit;
namespace LehrerApp.Tests;
public class ExamScoringServiceTests
{
[Fact]
public void BonusUndFassungen_VerwendenJeweilsDenRichtigenGrundwert()
{
var tasks = new List<ExamTask>
{
new() { MaxPoints = 10 },
new() { MaxPoints = 5, Variant = ExamVariant.A },
new() { MaxPoints = 8, Variant = ExamVariant.B },
new() { MaxPoints = 2, IsBonus = true },
};
Assert.Equal(15, ExamScoringService.Maximum(tasks, ExamVariant.A));
Assert.Equal(18, ExamScoringService.Maximum(tasks, ExamVariant.B));
Assert.Equal(17, ExamScoringService.Achieved(tasks, [10, 5, 8, 2], ExamVariant.A));
Assert.Equal(20, ExamScoringService.Achieved(tasks, [10, 5, 8, 2], ExamVariant.B));
}
[Fact]
public void TaskLabels_ZählenBonusaufgabenNichtMit()
{
var tasks = new List<ExamTask>
{
new() { Nr = 1 },
new() { Nr = 2, IsBonus = true },
new() { Nr = 3, Title = "Titration" },
new() { Nr = 4, IsBonus = true, Title = "Knobelei" },
};
Assert.Equal(["1", "Bonus 1", "2", "Bonus 2"],
ExamScoringService.TaskNumbers(tasks.Select(t => t.IsBonus)));
Assert.Equal(["Aufgabe 1", "Bonus 1", "2. Titration", "Bonus 2: Knobelei"],
ExamScoringService.TaskLabels(tasks));
}
[Fact]
public void TaskNumbers_EinzelneBonusaufgabeHeisstNurBonus() =>
Assert.Equal(["1", "Bonus", "2"], ExamScoringService.TaskNumbers([false, true, false]));
[Theory]
[InlineData(RepeatGradeRule.Better, GradingSystem.Grades1To6, "2", "4", "2")]
[InlineData(RepeatGradeRule.Better, GradingSystem.Points0To15, "8", "11", "11")]
[InlineData(RepeatGradeRule.Repeat, GradingSystem.Grades1To6, "2", "4", "4")]
[InlineData(RepeatGradeRule.Original, GradingSystem.Grades1To6, "2", "4", "2")]
public void Wiederholung_ZaehltGenauEinmalNachRegel(RepeatGradeRule rule,
GradingSystem system, string first, string second, string expected)
{
var original = new Exam();
var repeat = new Exam { RepeatOfExamId = original.Id, RepeatGradeRule = rule };
var other = new Exam();
var grades = ExamScoringService.EffectiveGrades(
[(original, first), (repeat, second), (other, "3")], system);
Assert.Equal(2, grades.Count);
Assert.Contains(expected, grades);
Assert.Contains("3", grades);
}
[Fact]
public void Wiederholung_BessereNoteBeruecksichtigtTendenzUndFehlendesErgebnis()
{
var original = new Exam();
var repeat = new Exam { RepeatOfExamId = original.Id };
Assert.Equal(["2+"], ExamScoringService.EffectiveGrades(
[(original, "2"), (repeat, "2+")], GradingSystem.Grades1To6));
Assert.Equal(["2"], ExamScoringService.EffectiveGrades(
[(original, "2")], GradingSystem.Grades1To6));
}
[Fact]
public void Nachschreibarbeit_ErsetztFehlendeNote()
{
var original = new Exam();
var makeUp = new Exam { RepeatOfExamId = original.Id, IsMakeUp = true };
// Schüler war bei der ersten Arbeit abwesend: nur die Nachschreibarbeit liegt vor.
Assert.Equal(["4"], ExamScoringService.EffectiveGrades([(makeUp, "4")], GradingSystem.Grades1To6));
}
[Fact]
public void Nachschreibarbeit_VerdraengtErsteNoteNie()
{
var original = new Exam();
var makeUp = new Exam { RepeatOfExamId = original.Id, IsMakeUp = true };
// Hat der Schüler beide geschrieben, zählt die erste — auch wenn die zweite besser ist.
Assert.Equal(["4"], ExamScoringService.EffectiveGrades(
[(original, "4"), (makeUp, "1")], GradingSystem.Grades1To6));
}
[Fact]
public void Foerderarbeit_ErsetztNurFehlendeNote()
{
var original = new Exam();
var support = new Exam { RepeatOfExamId = original.Id, IsSupportWork = true };
// Förderschüler hat die erste Arbeit nicht geschrieben: die Förderarbeit zählt allein.
Assert.Equal(["3"], ExamScoringService.EffectiveGrades([(support, "3")], GradingSystem.Grades1To6));
// Liegen beide Noten vor, zählt die erste — auch wenn die Förderarbeit besser ist.
Assert.Equal(["4"], ExamScoringService.EffectiveGrades(
[(original, "4"), (support, "1")], GradingSystem.Grades1To6));
}
[Fact]
public void MehrereFolgearbeiten_ZaehlenGenauEinmal()
{
var original = new Exam { Date = new DateOnly(2026, 9, 1) };
var makeUp = new Exam { RepeatOfExamId = original.Id, IsMakeUp = true, Date = new DateOnly(2026, 9, 15) };
var repeat = new Exam { RepeatOfExamId = original.Id, Date = new DateOnly(2026, 10, 1) };
// Original versäumt, Nachschreiben mit 4, Wiederholung mit 3 (Regel "Bessere") → eine Note.
Assert.Equal(["3"], ExamScoringService.EffectiveGrades(
[(makeUp, "4"), (repeat, "3")], GradingSystem.Grades1To6));
// Alle drei geschrieben: Original 3, Nachschreiben ignoriert, Wiederholung 2 → 2.
Assert.Equal(["2"], ExamScoringService.EffectiveGrades(
[(original, "3"), (makeUp, "1"), (repeat, "2")], GradingSystem.Grades1To6));
}
[Fact]
public void EffectiveGradesByKind_TrenntKlausurenVonTests()
{
var klausur = new Exam();
var test = new Exam { Kind = ExamKind.Test };
var testMakeUp = new Exam { Kind = ExamKind.Test, RepeatOfExamId = test.Id, IsMakeUp = true };
var (written, other) = ExamScoringService.EffectiveGradesByKind(
[(klausur, "2"), (test, "3"), (testMakeUp, "5")], GradingSystem.Grades1To6);
Assert.Equal(["2"], written);
Assert.Equal(["3"], other);
}
[Fact]
public void ExamWeekLoad_ZaehltTestsNichtAlsKlausur()
{
var monday = new DateOnly(2026, 9, 7);
var exams = new[]
{
new Exam { Date = monday },
new Exam { Date = monday.AddDays(1), Kind = ExamKind.Test },
};
Assert.Equal(1, ExamWeekLoadService.CountInSameWeek(exams, monday.AddDays(2)));
}
}