Files
LehrerApp/LehrerApp.Sync.Tests/AttachmentSyncerTests.cs
T

79 lines
3.2 KiB
C#

using LehrerApp.Data;
using LehrerApp.Sync.Crypto;
using Xunit;
namespace LehrerApp.Sync.Tests;
public sealed class AttachmentSyncerTests
{
private static LiteDbContext NewInMemoryContext() => new(new MemoryStream());
private static readonly byte[] Key = SyncCrypto.GenerateKey();
[Fact]
public async Task UploadPendingAsync_LaedtVerschluesselteBytesHochUndMarkiertAlsErledigt()
{
using var temp = new TempEventQueue();
using var db = NewInMemoryContext();
var storageId = Guid.NewGuid().ToString("N");
db.Attachments.Upload(storageId, "brief.pdf", new MemoryStream([1, 2, 3, 4]));
temp.Queue.QueueAttachmentUpload(storageId);
// Bytes MÜSSEN synchron innerhalb des Handler-Callbacks gelesen werden: AttachmentSyncer
// disposed sein ByteArrayContent direkt nach dem PostAsync-Aufruf (eigenes "using"),
// ein Zugriff auf request.Content danach würde ObjectDisposedException werfen.
byte[]? uploadedEncrypted = null;
var handler = new FakeHttpMessageHandler(req =>
{
uploadedEncrypted = req.Content!.ReadAsByteArrayAsync().GetAwaiter().GetResult();
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
});
var http = new HttpClient(handler) { BaseAddress = new Uri("https://example.invalid") };
var syncer = new AttachmentSyncer(db, http, Key);
await syncer.UploadPendingAsync(temp.Queue);
var request = Assert.Single(handler.Requests);
Assert.Equal(HttpMethod.Post, request.Method);
Assert.Equal($"/api/sync/attachments/{storageId}", request.RequestUri!.AbsolutePath);
Assert.Equal(SyncProtocol.CurrentVersion,
request.Headers.GetValues(SyncProtocol.VersionHeaderName).Single());
Assert.NotNull(uploadedEncrypted);
Assert.Equal([1, 2, 3, 4], SyncCrypto.Decrypt(uploadedEncrypted!, Key));
Assert.Empty(temp.Queue.GetPendingAttachmentUploads());
}
[Fact]
public async Task UploadPendingAsync_LokalNichtMehrVorhandenerAnhang_WirdOhneUploadAlsErledigtMarkiert()
{
using var temp = new TempEventQueue();
using var db = NewInMemoryContext();
temp.Queue.QueueAttachmentUpload("laengst-geloescht");
var handler = new FakeHttpMessageHandler(_ => new HttpResponseMessage(System.Net.HttpStatusCode.OK));
var http = new HttpClient(handler) { BaseAddress = new Uri("https://example.invalid") };
var syncer = new AttachmentSyncer(db, http, Key);
await syncer.UploadPendingAsync(temp.Queue);
Assert.Empty(handler.Requests);
Assert.Empty(temp.Queue.GetPendingAttachmentUploads());
}
private sealed class TempEventQueue : IDisposable
{
private readonly string _directory = Path.Combine(
Path.GetTempPath(), $"lehrerapp-sync-tests-attachments-{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);
}
}
}