feat(api): add account workspaces and signed content events
This commit is contained in:
1 parent
937b774a93
commit
7b8d61d1ba
63 files changed
+5407
-370
No files matched your search
@@ -41,6 +41,7 @@ public class ChannelServiceTests : IDisposable
|
||||
var dup = new CreateChannelRequest
|
||||
{
|
||||
Id = ch.Id.ToBase64Url(), Mode = ChannelMode.Enc,
|
||||
Settings = new ChannelSettings { Name = "Duplicate" },
|
||||
ReadHash = Codec.Encode(TokenHash.Compute(ch.ReadToken)),
|
||||
OwnerHash = Codec.Encode(TokenHash.Compute(ch.OwnerToken)),
|
||||
};
|
||||
@@ -51,9 +52,9 @@ public class ChannelServiceTests : IDisposable
|
||||
public void CreateEnforcesModeSpecificHashes()
|
||||
{
|
||||
string h() => Codec.Encode(TokenHash.Compute(TestEnv.Random(32)));
|
||||
var rawWithRead = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Raw, ReadHash = h(), OwnerHash = h() };
|
||||
var encNoRead = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Enc, OwnerHash = h() };
|
||||
var noOwner = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Raw };
|
||||
var rawWithRead = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Raw, Settings = new ChannelSettings { Name = "Raw space" }, ReadHash = h(), OwnerHash = h() };
|
||||
var encNoRead = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Enc, Settings = new ChannelSettings { Name = "Enc space" }, OwnerHash = h() };
|
||||
var noOwner = new CreateChannelRequest { Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Raw, Settings = new ChannelSettings { Name = "No owner space" } };
|
||||
|
||||
AssertCode(ErrorCode.BadRequest, () => Svc.CreateChannel(rawWithRead, _ownerEp, "owner"));
|
||||
AssertCode(ErrorCode.BadRequest, () => Svc.CreateChannel(encNoRead, _ownerEp, "owner"));
|
||||
@@ -106,6 +107,32 @@ public class ChannelServiceTests : IDisposable
|
||||
Assert.Equal(1, _env.Events.Seats); // 只有真正新增时才通知
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AccountMembersUseOneLimitAcrossUnlimitedDevices()
|
||||
{
|
||||
var ch = _env.Create(_ownerEp, settings: new ChannelSettings { Seats = 2 });
|
||||
var memberOne = TestEnv.Endpoint();
|
||||
var memberTwo = TestEnv.Endpoint();
|
||||
var ownerTwo = TestEnv.Endpoint();
|
||||
Credentials alice(byte[] endpoint, string device) => new(Role.Read, ch.ReadToken, endpoint, "alice", device);
|
||||
|
||||
Assert.Equal(2, Svc.Join(ch.Id, alice(memberOne, "alice-1")).SeatsUsed);
|
||||
Assert.Equal(2, Svc.Join(ch.Id, alice(memberTwo, "alice-2")).SeatsUsed);
|
||||
Assert.Equal(2, Svc.Join(ch.Id, ch.Owner(ownerTwo)).SeatsUsed);
|
||||
Assert.Equal(4, Svc.ListSeats(ch.Id, ch.Owner(_ownerEp)).Count); // 设备仍单独登记,但不计入成员人数
|
||||
|
||||
var bob = new Credentials(Role.Read, ch.ReadToken, TestEnv.Endpoint(), "bob", "bob-1");
|
||||
AssertCode(ErrorCode.SeatsFull, () => Svc.Join(ch.Id, bob));
|
||||
|
||||
Svc.ReleaseSeat(ch.Id, ch.Owner(_ownerEp), memberOne);
|
||||
Assert.Equal(2, Svc.GetChannel(ch.Id, ch.Owner(_ownerEp)).SeatsUsed); // 移除一台设备不会释放账号成员名额
|
||||
AssertCode(ErrorCode.SeatsFull, () => Svc.Join(ch.Id, bob with { EndpointHash = TestEnv.Endpoint() }));
|
||||
|
||||
Svc.RevokeInvitation(ch.Id, ch.Owner(_ownerEp), "alice");
|
||||
Assert.Equal(1, Svc.GetChannel(ch.Id, ch.Owner(_ownerEp)).SeatsUsed);
|
||||
Assert.Equal(2, Svc.Join(ch.Id, bob with { EndpointHash = TestEnv.Endpoint() }).SeatsUsed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DataOperationsRequireASeat()
|
||||
{
|
||||
@@ -114,6 +141,28 @@ public class ChannelServiceTests : IDisposable
|
||||
await AssertCode(ErrorCode.NotJoined, () => LogOf(ch, ch.Reader(_memberEp)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
public void CreateRequiresSpaceName(string? name)
|
||||
{
|
||||
var request = new CreateChannelRequest
|
||||
{
|
||||
Id = TestEnv.NewId().ToBase64Url(), Mode = ChannelMode.Raw,
|
||||
Settings = new ChannelSettings { Name = name },
|
||||
OwnerHash = Codec.Encode(TokenHash.Compute(TestEnv.Random(32))),
|
||||
};
|
||||
AssertCode(ErrorCode.SpaceNameRequired, () => Svc.CreateChannel(request, _ownerEp, "owner"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateTrimsSpaceName()
|
||||
{
|
||||
var channel = _env.Create(_ownerEp, settings: new ChannelSettings { Name = " Team space " });
|
||||
Assert.Equal("Team space", Svc.GetChannel(channel.Id, channel.Owner(_ownerEp)).Settings.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ItemIdsAndFramesAreScopedToTheirChannel()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user