about summary refs log tree commit diff
path: root/Tests/LibMatrix.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/LibMatrix.Tests')
-rw-r--r--Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs42
-rw-r--r--Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs34
-rw-r--r--Tests/LibMatrix.Tests/Tests/RoomEventTests.cs160
-rw-r--r--Tests/LibMatrix.Tests/Tests/RoomTests.cs145
-rw-r--r--Tests/LibMatrix.Tests/Tests/TestCleanup.cs76
5 files changed, 300 insertions, 157 deletions
diff --git a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs
index abd3e99..e23d4f4 100644
--- a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs
+++ b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs
@@ -6,7 +6,7 @@ namespace LibMatrix.Tests.Abstractions;
 
 public static class HomeserverAbstraction {
     public static async Task<AuthenticatedHomeserverGeneric> GetHomeserver() {
-        var rhs = new RemoteHomeServer("https://matrixunittests.rory.gay");
+        var rhs = await RemoteHomeServer.Create("https://matrixunittests.rory.gay");
         // string username = Guid.NewGuid().ToString();
         // string password = Guid.NewGuid().ToString();
         string username = "@f1a2d2d6-1924-421b-91d0-893b347b2a49:matrixunittests.rory.gay";
@@ -25,15 +25,15 @@ public static class HomeserverAbstraction {
 
         var hs = await reg.GetAuthenticatedHomeserver("https://matrixunittests.rory.gay");
 
-        var rooms = await hs.GetJoinedRooms();
+        //var rooms = await hs.GetJoinedRooms();
 
-        var disbandRoomTasks = rooms.Select(async room => {
-            // await room.DisbandRoomAsync();
-            await room.LeaveAsync();
-            await room.ForgetAsync();
-            return room;
-        }).ToList();
-        await Task.WhenAll(disbandRoomTasks);
+        // var disbandRoomTasks = rooms.Select(async room => {
+        //     // await room.DisbandRoomAsync();
+        //     await room.LeaveAsync();
+        //     await room.ForgetAsync();
+        //     return room;
+        // }).ToList();
+        // await Task.WhenAll(disbandRoomTasks);
 
         // foreach (var room in rooms) {
         //     // await room.DisbandRoomAsync();
@@ -45,28 +45,28 @@ public static class HomeserverAbstraction {
     }
 
     public static async Task<AuthenticatedHomeserverGeneric> GetRandomHomeserver() {
-        var rhs = new RemoteHomeServer("https://matrixunittests.rory.gay");
+        var rhs = await RemoteHomeServer.Create("https://matrixunittests.rory.gay");
         LoginResponse reg = await rhs.RegisterAsync(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "Unit tests!");
         var hs = await reg.GetAuthenticatedHomeserver("https://matrixunittests.rory.gay");
 
-        var rooms = await hs.GetJoinedRooms();
-
-        var disbandRoomTasks = rooms.Select(async room => {
-            // await room.DisbandRoomAsync();
-            await room.LeaveAsync();
-            await room.ForgetAsync();
-            return room;
-        }).ToList();
-        await Task.WhenAll(disbandRoomTasks);
+        // var rooms = await hs.GetJoinedRooms();
+        //
+        // var disbandRoomTasks = rooms.Select(async room => {
+        //     // await room.DisbandRoomAsync();
+        //     await room.LeaveAsync();
+        //     await room.ForgetAsync();
+        //     return room;
+        // }).ToList();
+        // await Task.WhenAll(disbandRoomTasks);
 
         return hs;
     }
 
     public static async IAsyncEnumerable<AuthenticatedHomeserverGeneric> GetRandomHomeservers(int count = 1) {
-        var createSpaceTasks = Enumerable
+        var createRandomUserTasks = Enumerable
             .Range(0, count)
             .Select(_ => GetRandomHomeserver()).ToAsyncEnumerable();
-        await foreach (var hs in createSpaceTasks) {
+        await foreach (var hs in createRandomUserTasks) {
             yield return hs;
         }
     }
diff --git a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs
index 44c35da..76b8c8c 100644
--- a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs
+++ b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs
@@ -8,11 +8,43 @@ namespace LibMatrix.Tests.Abstractions;
 
 public static class RoomAbstraction {
     public static async Task<GenericRoom> GetTestRoom(AuthenticatedHomeserverGeneric hs) {
-        var testRoom = await hs.CreateRoom(new CreateRoomRequest() {
+        var crq = new CreateRoomRequest() {
             Name = "LibMatrix Test Room",
             // Visibility = CreateRoomVisibility.Public,
             RoomAliasName = Guid.NewGuid().ToString()
+        };
+        crq.InitialState ??= new();
+        crq.InitialState.Add(new StateEvent() {
+            Type = "m.room.topic",
+            StateKey = "",
+            TypedContent = new RoomTopicEventContent() {
+                Topic = "LibMatrix Test Room " + DateTime.Now.ToString("O")
+            }
+        });
+        crq.InitialState.Add(new StateEvent() {
+            Type = "m.room.name",
+            StateKey = "",
+            TypedContent = new RoomNameEventContent() {
+                Name = "LibMatrix Test Room " + DateTime.Now.ToString("O")
+            }
+        });
+        crq.InitialState.Add(new StateEvent() {
+            Type = "m.room.avatar",
+            StateKey = "",
+            TypedContent = new RoomAvatarEventContent() {
+                Url = "mxc://conduit.rory.gay/r9KiT0f9eQbv8pv4RxwBZFuzhfKjGWHx"
+            }
+        });
+        crq.InitialState.Add(new StateEvent() {
+            Type = "m.room.aliases",
+            StateKey = "",
+            TypedContent = new RoomAliasEventContent() {
+                Aliases = Enumerable
+                    .Range(0, 100)
+                    .Select(_ => $"#{Guid.NewGuid()}:matrixunittests.rory.gay").ToList()
+            }
         });
+        var testRoom = await hs.CreateRoom(crq);
 
         await testRoom.SendStateEventAsync("gay.rory.libmatrix.unit_test_room", new());
 
diff --git a/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs b/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs
new file mode 100644
index 0000000..6828087
--- /dev/null
+++ b/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs
@@ -0,0 +1,160 @@
+using System.Text;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Homeservers;
+using LibMatrix.Services;
+using LibMatrix.Tests.Abstractions;
+using LibMatrix.Tests.Fixtures;
+using Xunit.Abstractions;
+using Xunit.Microsoft.DependencyInjection.Abstracts;
+
+namespace LibMatrix.Tests.Tests;
+
+public class RoomEventTests : TestBed<TestFixture> {
+    private readonly TestFixture _fixture;
+    private readonly HomeserverResolverService _resolver;
+    private readonly Config _config;
+    private readonly HomeserverProviderService _provider;
+
+    public RoomEventTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) {
+        _fixture = fixture;
+        _resolver = _fixture.GetService<HomeserverResolverService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}");
+        _config = _fixture.GetService<Config>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}");
+        _provider = _fixture.GetService<HomeserverProviderService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}");
+    }
+
+    private async Task<AuthenticatedHomeserverGeneric> GetHomeserver() {
+        return await HomeserverAbstraction.GetHomeserver();
+    }
+
+    [Fact]
+    public async Task GetNameAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var name = await room.GetNameAsync();
+        Assert.NotNull(name);
+        Assert.NotEmpty(name);
+    }
+
+    [SkippableFact(typeof(MatrixException))]
+    public async Task GetTopicAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var topic = await room.GetTopicAsync();
+        Assert.NotNull(topic);
+        Assert.NotNull(topic.Topic);
+        Assert.NotEmpty(topic.Topic);
+    }
+
+    [SkippableFact(typeof(MatrixException))]
+    public async Task GetAliasesAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var aliases = await room.GetAliasesAsync();
+        Assert.NotNull(aliases);
+        Assert.NotEmpty(aliases);
+        Assert.All(aliases, Assert.NotNull);
+    }
+
+    [SkippableFact(typeof(MatrixException))]
+    public async Task GetCanonicalAliasAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var alias = await room.GetCanonicalAliasAsync();
+        Assert.NotNull(alias);
+        Assert.NotNull(alias.Alias);
+        Assert.NotEmpty(alias.Alias);
+    }
+
+    [SkippableFact(typeof(MatrixException))]
+    public async Task GetAvatarUrlAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var url = await room.GetAvatarUrlAsync();
+        Assert.NotNull(url);
+        Assert.NotNull(url.Url);
+        Assert.NotEmpty(url.Url);
+    }
+
+    [Fact]
+    public async Task GetJoinRuleAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var rule = await room.GetJoinRuleAsync();
+        Assert.NotNull(rule);
+        Assert.NotNull(rule.JoinRule);
+        Assert.NotEmpty(rule.JoinRule);
+    }
+
+    [Fact]
+    public async Task GetHistoryVisibilityAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var visibility = await room.GetHistoryVisibilityAsync();
+        Assert.NotNull(visibility);
+        Assert.NotNull(visibility.HistoryVisibility);
+        Assert.NotEmpty(visibility.HistoryVisibility);
+    }
+
+    [Fact]
+    public async Task GetGuestAccessAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        try {
+            var access = await room.GetGuestAccessAsync();
+            Assert.NotNull(access);
+            Assert.NotNull(access.GuestAccess);
+            Assert.NotEmpty(access.GuestAccess);
+        }
+        catch (Exception e) {
+            if (e is not MatrixException exception) throw;
+            Assert.Equal("M_NOT_FOUND", exception.ErrorCode);
+        }
+    }
+
+    [Fact]
+    public async Task GetCreateEventAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var create = await room.GetCreateEventAsync();
+        Assert.NotNull(create);
+        Assert.NotNull(create.Creator);
+        Assert.NotEmpty(create.RoomVersion!);
+    }
+
+    [Fact]
+    public async Task GetRoomType() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        await room.GetRoomType();
+    }
+
+    [Fact]
+    public async Task GetPowerLevelsAsync() {
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        var room = await RoomAbstraction.GetTestRoom(hs);
+        Assert.NotNull(room);
+        var power = await room.GetPowerLevelsAsync();
+        Assert.NotNull(power);
+        Assert.NotNull(power.Ban);
+        Assert.NotNull(power.Kick);
+        Assert.NotNull(power.Invite);
+        Assert.NotNull(power.Redact);
+        Assert.NotNull(power.StateDefault);
+        Assert.NotNull(power.EventsDefault);
+        Assert.NotNull(power.UsersDefault);
+        Assert.NotNull(power.Users);
+        // Assert.NotNull(power.Events);
+    }
+
+}
diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests.cs
index 17c219d..72a2775 100644
--- a/Tests/LibMatrix.Tests/Tests/RoomTests.cs
+++ b/Tests/LibMatrix.Tests/Tests/RoomTests.cs
@@ -31,38 +31,18 @@ public class RoomTests : TestBed<TestFixture> {
     public async Task GetJoinedRoomsAsync() {
         var hs = await HomeserverAbstraction.GetHomeserver();
         //make 100 rooms
-        var createRoomTasks = Enumerable.Range(0, 100).Select(_ => RoomAbstraction.GetTestRoom(hs)).ToList();
+        var createRoomTasks = Enumerable.Range(0, 10).Select(_ => RoomAbstraction.GetTestRoom(hs)).ToList();
         await Task.WhenAll(createRoomTasks);
 
         var rooms = await hs.GetJoinedRooms();
         Assert.NotNull(rooms);
         Assert.NotEmpty(rooms);
         Assert.All(rooms, Assert.NotNull);
-        Assert.Equal(100, rooms.Count);
+        Assert.True(rooms.Count >= 10, "Not enough rooms were found");
 
         await hs.Logout();
     }
 
-    [Fact]
-    public async Task GetNameAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var name = await room.GetNameAsync();
-        Assert.NotNull(name);
-        Assert.NotEmpty(name);
-    }
-
-    [SkippableFact(typeof(MatrixException))]
-    public async Task GetTopicAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var topic = await room.GetTopicAsync();
-        Assert.NotNull(topic);
-        Assert.NotNull(topic.Topic);
-        Assert.NotEmpty(topic.Topic);
-    }
 
     [Fact]
     public async Task GetMembersAsync() {
@@ -106,115 +86,6 @@ public class RoomTests : TestBed<TestFixture> {
         Assert.NotEmpty(id.RoomId);
     }
 
-    [SkippableFact(typeof(MatrixException))]
-    public async Task GetAliasesAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var aliases = await room.GetAliasesAsync();
-        Assert.NotNull(aliases);
-        Assert.NotEmpty(aliases);
-        Assert.All(aliases, Assert.NotNull);
-    }
-
-    [SkippableFact(typeof(MatrixException))]
-    public async Task GetCanonicalAliasAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var alias = await room.GetCanonicalAliasAsync();
-        Assert.NotNull(alias);
-        Assert.NotNull(alias.Alias);
-        Assert.NotEmpty(alias.Alias);
-    }
-
-    [SkippableFact(typeof(MatrixException))]
-    public async Task GetAvatarUrlAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var url = await room.GetAvatarUrlAsync();
-        Assert.NotNull(url);
-        Assert.NotNull(url.Url);
-        Assert.NotEmpty(url.Url);
-    }
-
-    [Fact]
-    public async Task GetJoinRuleAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var rule = await room.GetJoinRuleAsync();
-        Assert.NotNull(rule);
-        Assert.NotNull(rule.JoinRule);
-        Assert.NotEmpty(rule.JoinRule);
-    }
-
-    [Fact]
-    public async Task GetHistoryVisibilityAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var visibility = await room.GetHistoryVisibilityAsync();
-        Assert.NotNull(visibility);
-        Assert.NotNull(visibility.HistoryVisibility);
-        Assert.NotEmpty(visibility.HistoryVisibility);
-    }
-
-    [Fact]
-    public async Task GetGuestAccessAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        try {
-            var access = await room.GetGuestAccessAsync();
-            Assert.NotNull(access);
-            Assert.NotNull(access.GuestAccess);
-            Assert.NotEmpty(access.GuestAccess);
-        }
-        catch (Exception e) {
-            if (e is not MatrixException exception) throw;
-            Assert.Equal("M_NOT_FOUND", exception.ErrorCode);
-        }
-    }
-
-    [Fact]
-    public async Task GetCreateEventAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var create = await room.GetCreateEventAsync();
-        Assert.NotNull(create);
-        Assert.NotNull(create.Creator);
-        Assert.NotEmpty(create.RoomVersion!);
-    }
-
-    [Fact]
-    public async Task GetRoomType() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        await room.GetRoomType();
-    }
-
-    [Fact]
-    public async Task GetPowerLevelsAsync() {
-        var hs = await HomeserverAbstraction.GetHomeserver();
-        var room = await RoomAbstraction.GetTestRoom(hs);
-        Assert.NotNull(room);
-        var power = await room.GetPowerLevelsAsync();
-        Assert.NotNull(power);
-        Assert.NotNull(power.Ban);
-        Assert.NotNull(power.Kick);
-        Assert.NotNull(power.Invite);
-        Assert.NotNull(power.Redact);
-        Assert.NotNull(power.StateDefault);
-        Assert.NotNull(power.EventsDefault);
-        Assert.NotNull(power.UsersDefault);
-        Assert.NotNull(power.Users);
-        // Assert.NotNull(power.Events);
-    }
-
     [Fact]
     public async Task ForgetAsync() {
         var hs = await HomeserverAbstraction.GetHomeserver();
@@ -361,17 +232,21 @@ public class RoomTests : TestBed<TestFixture> {
 
     [Fact]
     public async Task InviteAndJoinAsync() {
-        var otherUsers = HomeserverAbstraction.GetRandomHomeservers(7);
         var hs = await HomeserverAbstraction.GetHomeserver();
         var room = await RoomAbstraction.GetTestRoom(hs);
+        var otherUsers = HomeserverAbstraction.GetRandomHomeservers(15);
         Assert.NotNull(room);
 
         // var expectedCount = 1;
 
+        var tasks = new List<Task>();
         await foreach(var otherUser in otherUsers) {
-            await room.InviteUserAsync(otherUser.UserId);
-            await otherUser.GetRoom(room.RoomId).JoinAsync();
+            tasks.Add(Task.Run(async () => {
+                await room.InviteUserAsync(otherUser.UserId);
+                await otherUser.GetRoom(room.RoomId).JoinAsync();
+            }));
         }
+        await Task.WhenAll(tasks);
 
         var states = room.GetMembersAsync(false);
         var count = 0;
@@ -379,6 +254,6 @@ public class RoomTests : TestBed<TestFixture> {
             count++;
         }
         // Assert.Equal(++expectedCount, count);
-        Assert.Equal(8, count);
+        Assert.Equal(16, count);
     }
 }
diff --git a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs
new file mode 100644
index 0000000..e93de3d
--- /dev/null
+++ b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs
@@ -0,0 +1,76 @@
+using System.Diagnostics;
+using ArcaneLibs.Extensions;
+using LibMatrix.Helpers;
+using LibMatrix.Services;
+using LibMatrix.Tests.Abstractions;
+using LibMatrix.Tests.DataTests;
+using LibMatrix.Tests.Fixtures;
+using Microsoft.Extensions.Logging;
+using Xunit.Abstractions;
+using Xunit.Microsoft.DependencyInjection.Abstracts;
+
+namespace LibMatrix.Tests.Tests;
+
+public class TestCleanup : TestBed<TestFixture> {
+    private readonly TestFixture _fixture;
+    private readonly HomeserverResolverService _resolver;
+    private readonly Config _config;
+    private readonly HomeserverProviderService _provider;
+    private readonly ILogger<TestCleanup> _logger;
+
+    public TestCleanup(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) {
+        _fixture = fixture;
+        _resolver = _fixture.GetService<HomeserverResolverService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}");
+        _config = _fixture.GetService<Config>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}");
+        _provider = _fixture.GetService<HomeserverProviderService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}");
+        _logger = _fixture.GetService<ILogger<TestCleanup>>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(ILogger<TestCleanup>)}");
+    }
+
+    [Fact]
+    public async Task Cleanup() {
+        Assert.False(string.IsNullOrWhiteSpace(_config.TestHomeserver), $"{nameof(_config.TestHomeserver)} must be set in appsettings!");
+        Assert.False(string.IsNullOrWhiteSpace(_config.TestUsername), $"{nameof(_config.TestUsername)} must be set in appsettings!");
+        Assert.False(string.IsNullOrWhiteSpace(_config.TestPassword), $"{nameof(_config.TestPassword)} must be set in appsettings!");
+
+        var hs = await HomeserverAbstraction.GetHomeserver();
+        Assert.NotNull(hs);
+
+        var syncHelper = new SyncHelper(hs, _logger) {
+            Timeout = 3000
+        };
+        _testOutputHelper.WriteLine("Starting sync loop");
+        var cancellationTokenSource = new CancellationTokenSource();
+        var sw = Stopwatch.StartNew();
+        syncHelper.SyncReceivedHandlers.Add(async response => {
+            if (sw.ElapsedMilliseconds >= 3000) {
+                _testOutputHelper.WriteLine("Cancelling sync loop");
+
+                var tasks = (await hs.GetJoinedRooms()).Select(async room => {
+                    _logger.LogInformation("Leaving room: {}", room.RoomId);
+                    await room.LeaveAsync();
+                    await room.ForgetAsync();
+                    return room;
+                }).ToList();
+                await Task.WhenAll(tasks);
+
+                cancellationTokenSource.Cancel();
+            }
+
+            sw.Restart();
+            if (response.Rooms?.Leave is { Count: > 0 }) {
+                // foreach (var room in response.Rooms.Leave) {
+                    // await hs.GetRoom(room.Key).ForgetAsync();
+                // }
+                var tasks = response.Rooms.Leave.Select(async room => {
+                    await hs.GetRoom(room.Key).ForgetAsync();
+                    return room;
+                }).ToList();
+                await Task.WhenAll(tasks);
+            }
+        });
+        await syncHelper.RunSyncLoopAsync(cancellationToken: cancellationTokenSource.Token);
+
+        Assert.NotNull(hs);
+        await hs.Logout();
+    }
+}