aufräumen

This commit is contained in:
2026-08-12 17:45:02 +02:00
parent 0823a023c9
commit a1e722ace1
27 changed files with 542 additions and 197 deletions
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LehrerApp.Data\LehrerApp.Data.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
+135
View File
@@ -0,0 +1,135 @@
using LehrerApp.Core.Models;
using LiteDB;
using Xunit;
namespace LehrerApp.Data.Tests;
public sealed class LiteDbContextTests
{
[Fact]
public void MigratesLegacyEnrollmentAndSubjectTextWithoutLosingData()
{
using var temp = new TempDatabase();
var groupId = Guid.NewGuid();
var studentId = Guid.NewGuid();
var membershipId = Guid.NewGuid();
var examId = Guid.NewGuid();
var gradeId = Guid.NewGuid();
var entryId = Guid.NewGuid();
var addedOn = new DateOnly(2026, 6, 23);
using (var legacy = new LiteDatabase(temp.Path))
{
legacy.GetCollection<Subject>("subjects").Insert(new Subject { Name = "mathematik" });
legacy.GetCollection<BsonDocument>("groups").Insert(new BsonDocument
{
["_id"] = groupId,
[nameof(LearningGroup.Name)] = "Mathe G",
["Subject"] = "Mathematik",
[nameof(LearningGroup.SchoolYear)] = "2025/26",
});
legacy.GetCollection<BsonDocument>("enrollments").Insert(new BsonDocument
{
["_id"] = membershipId,
[nameof(GroupMembership.StudentId)] = studentId,
[nameof(GroupMembership.GroupId)] = groupId,
["SchoolYear"] = "2025/26",
["EnrolledAt"] = BsonMapper.Global.Serialize(addedOn),
});
legacy.GetCollection<BsonDocument>("exams").Insert(new BsonDocument
{
["_id"] = examId,
[nameof(Exam.GroupId)] = groupId,
["Subject"] = "Mathematik",
});
legacy.GetCollection<BsonDocument>("grades").Insert(new BsonDocument
{
["_id"] = gradeId,
[nameof(Grade.StudentId)] = studentId,
[nameof(Grade.GroupId)] = groupId,
["SchoolYear"] = "2025/26",
});
legacy.GetCollection<BsonDocument>("participation").Insert(new BsonDocument
{
["_id"] = entryId,
[nameof(ParticipationEntry.SessionId)] = Guid.NewGuid(),
[nameof(ParticipationEntry.StudentId)] = studentId,
["GroupId"] = groupId,
["Date"] = BsonMapper.Global.Serialize(addedOn),
});
}
using (var context = new LiteDbContext(temp.Path))
{
var group = context.Groups.FindById(groupId);
var membership = context.Memberships.FindById(membershipId);
Assert.NotNull(group);
Assert.NotNull(group.SubjectId);
Assert.Equal("mathematik", context.Subjects.FindById(group.SubjectId.Value)?.Name);
Assert.Equal(1, context.Subjects.Count());
Assert.NotNull(membership);
Assert.Equal(addedOn, membership.AddedOn);
}
using var migrated = new LiteDatabase(temp.Path);
Assert.DoesNotContain("enrollments", migrated.GetCollectionNames());
Assert.Contains("group_memberships", migrated.GetCollectionNames());
var rawGroup = migrated.GetCollection<BsonDocument>("groups").FindById(groupId);
var rawMembership = migrated.GetCollection<BsonDocument>("group_memberships").FindById(membershipId);
var rawExam = migrated.GetCollection<BsonDocument>("exams").FindById(examId);
var rawGrade = migrated.GetCollection<BsonDocument>("grades").FindById(gradeId);
var rawEntry = migrated.GetCollection<BsonDocument>("participation").FindById(entryId);
Assert.False(rawGroup.ContainsKey("Subject"));
Assert.False(rawMembership.ContainsKey("SchoolYear"));
Assert.False(rawMembership.ContainsKey("EnrolledAt"));
Assert.True(rawMembership.ContainsKey(nameof(GroupMembership.AddedOn)));
Assert.False(rawExam.ContainsKey("Subject"));
Assert.False(rawGrade.ContainsKey("SchoolYear"));
Assert.False(rawEntry.ContainsKey("GroupId"));
Assert.False(rawEntry.ContainsKey("Date"));
}
[Fact]
public void RejectsASecondMembershipForTheSameStudentAndGroup()
{
using var temp = new TempDatabase();
using var context = new LiteDbContext(temp.Path);
var studentId = Guid.NewGuid();
var groupId = Guid.NewGuid();
context.Memberships.Insert(new GroupMembership { StudentId = studentId, GroupId = groupId });
Assert.Throws<LiteException>(() => context.Memberships.Insert(
new GroupMembership { StudentId = studentId, GroupId = groupId }));
}
[Fact]
public void RejectsASecondExamResultForTheSameStudentAndExam()
{
using var temp = new TempDatabase();
using var context = new LiteDbContext(temp.Path);
var studentId = Guid.NewGuid();
var examId = Guid.NewGuid();
context.ExamResults.Insert(new ExamResult { StudentId = studentId, ExamId = examId });
Assert.Throws<LiteException>(() => context.ExamResults.Insert(
new ExamResult { StudentId = studentId, ExamId = examId }));
}
private sealed class TempDatabase : IDisposable
{
private readonly string _directory = System.IO.Path.Combine(
System.IO.Path.GetTempPath(), $"lehrerapp-tests-{Guid.NewGuid():N}");
public string Path { get; }
public TempDatabase()
{
Directory.CreateDirectory(_directory);
Path = System.IO.Path.Combine(_directory, "test.db");
}
public void Dispose()
{
if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true);
}
}
}