feat: integrate client and server sharing workflows

This commit is contained in:
justme committed 2026-10-02 10:49:45 +08:00
1 parent 42b93ae2d8
commit 7406e2fe37
101 files changed
+3153 -253

No files matched your search

@@ -119,6 +119,37 @@ public sealed class ShareTests(ServerFixture server) : IClassFixture<ServerFixtu
await AssertErrorAsync(shareCollision, 409, "conflict");
}
[Fact]
public async Task ResumeWithoutAnInitialDownloadCannotBypassShareDownloadLimit()
{
var share = new ShareClient(NewId());
using (var created = await CreateShare(share)) Assert.Equal(HttpStatusCode.Created, created.StatusCode);
string manifestId = NewId();
using (var manifest = await SendFrame(share, share.Owner, Frame(manifestId, 0, FinalEnc, EncPayload)))
Assert.Equal(HttpStatusCode.Created, manifest.StatusCode);
string itemId = NewId();
using (var first = await SendFrame(share, share.Owner, Frame(itemId, 0, GatedEnc, EncPayload), "1"))
Assert.Equal(HttpStatusCode.Created, first.StatusCode);
using (var last = await SendFrame(share, share.Owner, Frame(itemId, 1, GatedFinalEnc, EncPayload)))
Assert.Equal(HttpStatusCode.Created, last.StatusCode);
using (var finish = await server.Http.SendAsync(server.Req(HttpMethod.Post,
$"/api/v1/shares/{share.Id}/finish", share.Owner, JsonBody(new { manifest_item_id = manifestId }))))
Assert.Equal(HttpStatusCode.OK, finish.StatusCode);
string path = $"/api/v1/shares/{share.Id}/items/{itemId}/frames";
await AssertErrorAsync(await server.Http.SendAsync(server.Req(HttpMethod.Get, path + "?from=1", share.OtherVisitor)), 410, "gone");
var (initialResponse, initialBytes) = await server.GetBytesAsync(path, share.Visitor);
using (initialResponse) Assert.Equal(Frame(itemId, 0, GatedEnc, EncPayload, 0x42).Concat(Frame(itemId, 1, GatedFinalEnc, EncPayload, 0x42)), initialBytes);
var (resumeResponse, resumedBytes) = await server.GetBytesAsync(path + "?from=1", share.Visitor);
using (resumeResponse) Assert.Equal(Frame(itemId, 1, GatedFinalEnc, EncPayload, 0x42), resumedBytes);
using var infoResponse = await server.Http.SendAsync(server.Req(HttpMethod.Get, $"/api/v1/shares/{share.Id}", share.CreatorReader));
var item = (await ReadJsonAsync(infoResponse)).GetProperty("items").EnumerateArray().Single();
Assert.Equal(0, item.GetProperty("downloads_left").GetInt32());
}
private async Task<HttpResponseMessage> CreateShare(ShareClient share)
{
using var req = server.Req(HttpMethod.Post, "/api/v1/shares", share.Owner, JsonBody(new