CI / build-and-test (push) Canceled after 0s
Nachschreibarbeiten nutzen die Wiederholungs-Verknüpfung, ersetzen aber nur fehlende Noten; mehrere Folgearbeiten je erster Arbeit sind möglich. Exam.Kind trennt Klausuren (schriftlich) von Tests u. Ä. (Sonstige). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
142 lines
5.5 KiB
C#
142 lines
5.5 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 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)));
|
|
}
|
|
}
|