Files
LehrerApp/LehrerApp.Sync.Tests/SyncEventPublisherTests.cs
adminandClaude Sonnet 5 038337997f feat: Anhänge je Stunde, Klausur-Sitzplan mischen, Gefährdungsbeurteilungs-Assistent
Lesson bekommt dieselbe Anhang-Infrastruktur wie Documentation (Material,
Arbeitsblätter, Experimentunterlagen), samt Fix einer Sync-Lücke, die Anhang-
Dateibytes bisher nur für Documentation statt generisch übertragen hat
(IHasAttachments). Sitzplan-Tab bekommt einen "Plätze mischen"-Button für
Klausursitzpläne. Neu: mehrschrittiger Gefährdungsbeurteilungs-Assistent mit
optionalem KI-Entwurf (ai-backend/gbu.php) und PDF-Export, Format bewusst als
JSON-Anhang statt eigener Datenbank-Entität. Details und Architekturentscheidungen
in TODO.md (4.2, 7.1.5, 10.1.8).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 17:13:14 +02:00

71 lines
2.6 KiB
C#

using LehrerApp.Core.Models;
using LehrerApp.Sync.Crypto;
using Xunit;
namespace LehrerApp.Sync.Tests;
public sealed class SyncEventPublisherTests
{
private static readonly byte[] Key = SyncCrypto.GenerateKey();
[Fact]
public void Publish_DocumentationMitAnhang_ReihtIhnZumHochladenEin()
{
using var temp = new TempEventQueue();
var publisher = new SyncEventPublisher(temp.Queue, "desktop-1", Key);
var doc = new Documentation { StudentId = Guid.NewGuid(), Title = "Elternbrief" };
doc.Attachments.Add(new DocumentAttachment { StorageId = "abc", FileName = "brief.pdf" });
publisher.Publish(nameof(Documentation), doc.Id.ToString(), "Save", doc);
Assert.Equal(["abc"], temp.Queue.GetPendingAttachmentUploads());
}
/// Regressionstest für die Verallgemeinerung von "nur Documentation" auf
/// <see cref="IHasAttachments"/> — Anhänge an einer <see cref="Lesson"/> müssen genauso in die
/// Upload-Warteliste eingereiht werden.
[Fact]
public void Publish_LessonMitAnhang_ReihtIhnZumHochladenEin()
{
using var temp = new TempEventQueue();
var publisher = new SyncEventPublisher(temp.Queue, "desktop-1", Key);
var lesson = new Lesson { UnitId = Guid.NewGuid(), GroupId = Guid.NewGuid(), Topic = "Brechung" };
lesson.Attachments.Add(new DocumentAttachment { StorageId = "gbu-1", FileName = "gbu.pdf" });
publisher.Publish(nameof(Lesson), lesson.Id.ToString(), "Save", lesson);
Assert.Equal(["gbu-1"], temp.Queue.GetPendingAttachmentUploads());
}
[Fact]
public void Publish_EntitaetOhneAnhaenge_ReihtNichtsZumHochladenEin()
{
using var temp = new TempEventQueue();
var publisher = new SyncEventPublisher(temp.Queue, "desktop-1", Key);
var student = new Student { FirstName = "Anna", LastName = "Beispiel" };
publisher.Publish(nameof(Student), student.Id.ToString(), "Save", student);
Assert.Empty(temp.Queue.GetPendingAttachmentUploads());
}
private sealed class TempEventQueue : IDisposable
{
private readonly string _directory = Path.Combine(
Path.GetTempPath(), $"lehrerapp-sync-tests-publisher-{Guid.NewGuid():N}");
public EventQueue Queue { get; }
public TempEventQueue()
{
Directory.CreateDirectory(_directory);
Queue = new EventQueue(Path.Combine(_directory, "queue.db"));
}
public void Dispose()
{
Queue.Dispose();
if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true);
}
}
}