diff options
Diffstat (limited to '')
19 files changed, 1132 insertions, 464 deletions
diff --git a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs index c9727d6..401223c 100644 --- a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs +++ b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs @@ -1,71 +1,96 @@ using ArcaneLibs.Extensions; using LibMatrix.Homeservers; using LibMatrix.Responses; +using LibMatrix.Services; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Xunit.Abstractions; +using Xunit.Sdk; namespace LibMatrix.Tests.Abstractions; -public static class HomeserverAbstraction { - public static async Task<AuthenticatedHomeserverGeneric> GetHomeserver() { - var rhs = await RemoteHomeserver.Create("https://matrixunittests.rory.gay"); - // string username = Guid.NewGuid().ToString(); - // string password = Guid.NewGuid().ToString(); - var username = "@f1a2d2d6-1924-421b-91d0-893b347b2a49:matrixunittests.rory.gay"; - var password = "d6d782d6-8bc9-4fac-9cd8-78e101b4298b"; +public class HomeserverAbstraction(HomeserverProviderService _hsProvider, Config _config, ILogger<HomeserverAbstraction> _logger) { + // private static readonly HomeserverResolverService _hsResolver = new HomeserverResolverService(NullLogger<HomeserverResolverService>.Instance); + // private static readonly HomeserverProviderService _hsProvider = new HomeserverProviderService(NullLogger<HomeserverProviderService>.Instance, _hsResolver); + + private static AuthenticatedHomeserverGeneric? ConfiguredHomeserver { get; set; } + private static readonly SemaphoreSlim _lock = new(1, 1); + + public async Task<AuthenticatedHomeserverGeneric> GetConfiguredHomeserver(ITestOutputHelper? testOutputHelper = null) { + Assert.False(string.IsNullOrWhiteSpace(_config.TestHomeserver)); + Assert.False(string.IsNullOrWhiteSpace(_config.TestUsername)); + Assert.False(string.IsNullOrWhiteSpace(_config.TestPassword)); + + _logger.LogDebug("Using homeserver '{0}' with login '{1}' '{2}", _config.TestHomeserver, _config.TestUsername, _config.TestPassword); + testOutputHelper?.WriteLine($"Using homeserver '{_config.TestHomeserver}' with login '{_config.TestUsername}' '{_config.TestPassword}'"); + + await _lock.WaitAsync(); + if (ConfiguredHomeserver is not null) { + _lock.Release(); + return ConfiguredHomeserver; + } + + var rhs = await _hsProvider.GetRemoteHomeserver(_config.TestHomeserver); + LoginResponse reg; try { - reg = await rhs.LoginAsync(username, password); + reg = await rhs.LoginAsync(_config.TestUsername, _config.TestPassword); } catch (MatrixException e) { if (e.ErrorCode == "M_FORBIDDEN") { await rhs.RegisterAsync(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "Unit tests!"); - reg = await rhs.RegisterAsync(username, password, "Unit tests!"); + reg = await rhs.RegisterAsync(_config.TestUsername, _config.TestPassword, "Unit tests!"); } else throw new Exception("Failed to register", e); } - 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); - - // foreach (var room in rooms) { - // // await room.DisbandRoomAsync(); - // await room.LeaveAsync(); - // await room.ForgetAsync(); - // } + var hs = await _hsProvider.GetAuthenticatedWithToken(reg.Homeserver, reg.AccessToken); + ConfiguredHomeserver = hs; + _lock.Release(); return hs; } - public static async Task<AuthenticatedHomeserverGeneric> GetRandomHomeserver() { - var rhs = await RemoteHomeserver.Create("https://matrixunittests.rory.gay"); - var 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); - + public async Task<AuthenticatedHomeserverGeneric> GetNewHomeserver() { + Assert.False(string.IsNullOrWhiteSpace(_config.TestHomeserver)); + var username = Guid.NewGuid().ToString(); + var password = Guid.NewGuid().ToString(); + + _logger.LogDebug("Creating new homeserver '{0}' with login '{1}' '{2}'", _config.TestHomeserver, username, password); + + var rhs = await _hsProvider.GetRemoteHomeserver(_config.TestHomeserver); + var reg = await rhs.RegisterAsync(username, password, "Unit tests!"); + var hs = await _hsProvider.GetAuthenticatedWithToken(reg.Homeserver, reg.AccessToken); + return hs; } - public static async IAsyncEnumerable<AuthenticatedHomeserverGeneric> GetRandomHomeservers(int count = 1) { + public async IAsyncEnumerable<AuthenticatedHomeserverGeneric> GetNewHomeservers(int count = 1) { var createRandomUserTasks = Enumerable .Range(0, count) - .Select(_ => GetRandomHomeserver()).ToAsyncEnumerable(); + .Select(_ => GetNewHomeserver()).ToAsyncEnumerable(); await foreach (var hs in createRandomUserTasks) yield return hs; } + + public async Task<(string username, string password, string token)> GetKnownCredentials() { + Assert.False(string.IsNullOrWhiteSpace(_config.TestHomeserver)); + var rhs = await _hsProvider.GetRemoteHomeserver(_config.TestHomeserver); + + var username = _config.TestUsername; + var password = _config.TestPassword; + + LoginResponse reg; + try { + reg = await rhs.LoginAsync(username, password); + } + catch (MatrixException e) { + if (e.ErrorCode == "M_FORBIDDEN") { + await rhs.RegisterAsync(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "Unit tests!"); + reg = await rhs.RegisterAsync(username, password, "Unit tests!"); + } + else throw new Exception("Failed to log in", e); + } + + return (username, password, reg.AccessToken); + } } \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs index 2a380fc..88b6758 100644 --- a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs +++ b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec.State; using LibMatrix.EventTypes.Spec.State.RoomInfo; @@ -16,28 +17,28 @@ public static class RoomAbstraction { }; crq.InitialState ??= new List<StateEvent>(); crq.InitialState.Add(new StateEvent() { - Type = "m.room.topic", + Type = RoomTopicEventContent.EventId, StateKey = "", TypedContent = new RoomTopicEventContent() { Topic = "LibMatrix Test Room " + DateTime.Now.ToString("O") } }); crq.InitialState.Add(new StateEvent() { - Type = "m.room.name", + Type = RoomNameEventContent.EventId, StateKey = "", TypedContent = new RoomNameEventContent() { Name = "LibMatrix Test Room " + DateTime.Now.ToString("O") } }); crq.InitialState.Add(new StateEvent() { - Type = "m.room.avatar", + Type = RoomAvatarEventContent.EventId, StateKey = "", TypedContent = new RoomAvatarEventContent() { Url = "mxc://conduit.rory.gay/r9KiT0f9eQbv8pv4RxwBZFuzhfKjGWHx" } }); crq.InitialState.Add(new StateEvent() { - Type = "m.room.aliases", + Type = RoomAliasEventContent.EventId, StateKey = "", TypedContent = new RoomAliasEventContent() { Aliases = Enumerable diff --git a/Tests/LibMatrix.Tests/Config.cs b/Tests/LibMatrix.Tests/Config.cs index ddbf705..045ea40 100644 --- a/Tests/LibMatrix.Tests/Config.cs +++ b/Tests/LibMatrix.Tests/Config.cs @@ -1,18 +1,41 @@ +using Microsoft.Extensions.Configuration; + namespace LibMatrix.Tests; public class Config { + public Config(IConfiguration? config) { + config.GetSection("Configuration").Bind(this); + } + public string? TestHomeserver { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_HOMESERVER") ?? null; - public string? TestUsername { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_USERNAME") ?? null; - public string? TestPassword { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_PASSWORD") ?? null; - public string? TestRoomId { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_ROOM_ID") ?? null; - public string? TestRoomAlias { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_ROOM_ALIAS") ?? null; + public string? TestUsername { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_USERNAME") ?? Guid.NewGuid().ToString(); + + public string? TestPassword { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_PASSWORD") ?? Guid.NewGuid().ToString(); + // public string? TestRoomId { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_ROOM_ID") ?? null; + // public string? TestRoomAlias { get; set; } = Environment.GetEnvironmentVariable("LIBMATRIX_TEST_ROOM_ALIAS") ?? null; - public Dictionary<string, string> ExpectedHomeserverMappings { get; set; } = new() { + public Dictionary<string, string> ExpectedHomeserverClientMappings { get; set; } = new() { { "matrix.org", "https://matrix-client.matrix.org" }, - { "rory.gay", "https://matrix.rory.gay" } + { "rory.gay", "https://matrix.rory.gay" }, + { "feline.support", "https://matrix.feline.support" }, + { "transfem.dev", "https://matrix.transfem.dev" }, + { "the-apothecary.club", "https://the-apothecary.club" }, + { "nixos.org", "https://matrix.nixos.org" }, + { "fedora.im", "https://fedora.ems.host" } + }; + + public Dictionary<string, string> ExpectedHomeserverFederationMappings { get; set; } = new() { + { "rory.gay", "https://matrix.rory.gay:443" }, + { "matrix.org", "https://matrix-federation.matrix.org:443" }, + { "feline.support", "https://matrix.feline.support:8448" }, + { "transfem.dev", "https://matrix.transfem.dev:443" }, + { "the-apothecary.club", "https://the-apothecary.club:443" }, + { "nixos.org", "https://matrix.nixos.org:443" }, + { "fedora.im", "https://fedora.ems.host:443" } }; public Dictionary<string, string> ExpectedAliasMappings { get; set; } = new() { - { "#libmatrix:rory.gay", "!tuiLEoMqNOQezxILzt:rory.gay" } + { "#libmatrix:rory.gay", "!tuiLEoMqNOQezxILzt:rory.gay" }, + { "#matrix:matrix.org", "!OGEhHVWSdvArJzumhm:matrix.org" } }; } \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Fixtures/TestFixture.cs b/Tests/LibMatrix.Tests/Fixtures/TestFixture.cs index 35c8704..01a0d2f 100644 --- a/Tests/LibMatrix.Tests/Fixtures/TestFixture.cs +++ b/Tests/LibMatrix.Tests/Fixtures/TestFixture.cs @@ -1,5 +1,6 @@ using ArcaneLibs.Extensions; using LibMatrix.Services; +using LibMatrix.Tests.Abstractions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Xunit.Microsoft.DependencyInjection; @@ -8,24 +9,19 @@ using Xunit.Microsoft.DependencyInjection.Abstracts; namespace LibMatrix.Tests.Fixtures; public class TestFixture : TestBedFixture { - protected override void AddServices(IServiceCollection services, IConfiguration? configuration) { - services.AddSingleton<TieredStorageService>(x => - new TieredStorageService( - null, - null - ) - ); + protected override void AddServices(IServiceCollection services, IConfiguration configuration) { + // services.AddSingleton<TieredStorageService>(x => + // new TieredStorageService( + // null, + // null + // ) + // ); + services.AddSingleton(configuration); services.AddRoryLibMatrixServices(); - - services.AddSingleton<Config>(config => { - var conf = new Config(); - configuration?.GetSection("Configuration").Bind(conf); - - File.WriteAllText("configuration.json", conf.ToJson()); - - return conf; - }); + services.AddLogging(); + services.AddSingleton<HomeserverAbstraction>(); + services.AddSingleton<Config>(); } protected override ValueTask DisposeAsyncCore() diff --git a/Tests/LibMatrix.Tests/LibMatrix.Tests.csproj b/Tests/LibMatrix.Tests/LibMatrix.Tests.csproj index 095985a..52bec9f 100644 --- a/Tests/LibMatrix.Tests/LibMatrix.Tests.csproj +++ b/Tests/LibMatrix.Tests/LibMatrix.Tests.csproj @@ -13,9 +13,9 @@ <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> - <PackageReference Include="xunit" Version="2.8.1" /> + <PackageReference Include="xunit" Version="2.8.0" /> <PackageReference Include="Xunit.Microsoft.DependencyInjection" Version="8.1.0" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.8.1"> + <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> diff --git a/Tests/LibMatrix.Tests/Tests/AuthTests.cs b/Tests/LibMatrix.Tests/Tests/AuthTests.cs index f331dd0..633c842 100644 --- a/Tests/LibMatrix.Tests/Tests/AuthTests.cs +++ b/Tests/LibMatrix.Tests/Tests/AuthTests.cs @@ -1,4 +1,5 @@ using LibMatrix.Services; +using LibMatrix.Tests.Abstractions; using LibMatrix.Tests.DataTests; using LibMatrix.Tests.Fixtures; using Xunit.Abstractions; @@ -7,43 +8,29 @@ using Xunit.Microsoft.DependencyInjection.Abstracts; namespace LibMatrix.Tests.Tests; public class AuthTests : TestBed<TestFixture> { - private readonly TestFixture _fixture; - private readonly HomeserverResolverService _resolver; private readonly Config _config; private readonly HomeserverProviderService _provider; + private readonly HomeserverAbstraction _hsAbstraction; public AuthTests(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)}"); + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); } - + [Fact] public async Task LoginWithPassword() { - 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 server = await _resolver.ResolveHomeserverFromWellKnown(_config.TestHomeserver!); - var login = await _provider.Login(_config.TestHomeserver!, _config.TestUsername!, _config.TestPassword!); + var credentials = await _hsAbstraction.GetKnownCredentials(); + + var login = await _provider.Login(_config.TestHomeserver!, credentials.username, credentials.password); Assert.NotNull(login); - var hs = await _provider.GetAuthenticatedWithToken(_config.TestHomeserver!, login.AccessToken); - Assert.NotNull(hs); - await hs.Logout(); + Assert.NotNull(login.AccessToken); } [Fact] public async Task LoginWithToken() { - 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 server = await _resolver.ResolveHomeserverFromWellKnown(_config.TestHomeserver!); - var login = await _provider.Login(_config.TestHomeserver!, _config.TestUsername!, _config.TestPassword!); - Assert.NotNull(login); - - var hs = await _provider.GetAuthenticatedWithToken(_config.TestHomeserver!, login.AccessToken); + var credentials = await _hsAbstraction.GetKnownCredentials(); + var hs = await _provider.GetAuthenticatedWithToken(_config.TestHomeserver!, credentials.token); Assert.NotNull(hs); Assert.NotNull(hs.WhoAmI); hs.WhoAmI.VerifyRequiredFields(); @@ -54,7 +41,7 @@ public class AuthTests : TestBed<TestFixture> { [Fact] public async Task RegisterAsync() { - var rhs = await _provider.GetRemoteHomeserver("matrixunittests.rory.gay"); + var rhs = await _provider.GetRemoteHomeserver(_config.TestHomeserver); var reg = await rhs.RegisterAsync(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "Unit tests!"); Assert.NotNull(reg); Assert.NotNull(reg.AccessToken); diff --git a/Tests/LibMatrix.Tests/Tests/CanonicalJsonTests.cs b/Tests/LibMatrix.Tests/Tests/CanonicalJsonTests.cs new file mode 100644 index 0000000..c7fde54 --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/CanonicalJsonTests.cs @@ -0,0 +1,53 @@ +using System.Collections.Frozen; +using System.Diagnostics; +using System.Text.Json; +using LibMatrix.Extensions; +using LibMatrix.Services; +using LibMatrix.Tests.Abstractions; +using LibMatrix.Tests.DataTests; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; +using Xunit.Sdk; + +namespace LibMatrix.Tests.Tests; + +public class CanonicalJsonTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : TestBed<TestFixture>(testOutputHelper, fixture) { + // Test cases from https://spec.matrix.org/v1.11/appendices/#examples + private static readonly FrozenDictionary<string, string> testCases = new Dictionary<string, string>() { + ["{}"] = "{}", + ["{\n \"one\": 1,\n \"two\": \"Two\"\n}\n"] = "{\"one\":1,\"two\":\"Two\"}", + ["{\n \"b\": \"2\",\n \"a\": \"1\"\n}\n"] = "{\"a\":\"1\",\"b\":\"2\"}", + ["{\"b\":\"2\",\"a\":\"1\"}"] = "{\"a\":\"1\",\"b\":\"2\"}", + ["{\n \"auth\": {\n \"success\": true,\n \"mxid\": \"@john.doe:example.com\",\n \"profile\": {\n \"display_name\": \"John Doe\",\n \"three_pids\": [\n {\n \"medium\": \"email\",\n \"address\": \"[email protected]\"\n },\n {\n \"medium\": \"msisdn\",\n \"address\": \"123456789\"\n }\n ]\n }\n }\n}\n"] = + "{\"auth\":{\"mxid\":\"@john.doe:example.com\",\"profile\":{\"display_name\":\"John Doe\",\"three_pids\":[{\"address\":\"[email protected]\",\"medium\":\"email\"},{\"address\":\"123456789\",\"medium\":\"msisdn\"}]},\"success\":true}}", + ["{\n \"a\": \"日本語\"\n}\n"] = "{\"a\":\"日本語\"}", + ["{\n \"本\": 2,\n \"日\": 1\n}\n"] = "{\"日\":1,\"本\":2}", + ["{\n \"a\": \"\\u65E5\"\n}\n"] = "{\"a\":\"日\"}", + ["{\n \"a\": null\n}\n"] = "{\"a\":null}", + ["{\n \"a\": -0,\n \"b\": 1e10\n}\n"] = "{\"a\":0,\"b\":10000000000}" + }.ToFrozenDictionary(); + + [Fact] + public void SpecTests() { + var i = 0; + foreach (var (input, expected) in testCases) { + var deserialised = JsonSerializer.Deserialize<Dictionary<string, object>>(input); + var actual = CanonicalJsonSerializer.Serialize(deserialised); + Assert.Equal(expected, actual); + // testOutputHelper.WriteLine($"Test case {i++} successful!"); + } + } + + [Fact] + public void RepeatTests() { + var sw = Stopwatch.StartNew(); + for (int i = 0; i < 1_000_000; i++) { + SpecTests(); + if (i % 10000 == 0) { + testOutputHelper.WriteLine($"{i} loops successful! Delta: {sw.Elapsed}"); + sw.Restart(); + } + } + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/HomeserverResolverTests.cs b/Tests/LibMatrix.Tests/Tests/HomeserverResolverTests.cs new file mode 100644 index 0000000..ef2426d --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/HomeserverResolverTests.cs @@ -0,0 +1,43 @@ +using LibMatrix.Services; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace LibMatrix.Tests.Tests; + +public class HomeserverResolverTests : TestBed<TestFixture> { + private readonly Config _config; + private readonly HomeserverResolverService _resolver; + + public HomeserverResolverTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _config = _fixture.GetService<Config>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}"); + _resolver = _fixture.GetService<HomeserverResolverService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}"); + } + + [Fact] + public async Task ResolveServerClient() { + var tasks = _config.ExpectedHomeserverClientMappings.Select(async mapping => { + var server = await _resolver.ResolveHomeserverFromWellKnown(mapping.Key); + Assert.Equal(mapping.Value, server.Client); + return server; + }).ToList(); + await Task.WhenAll(tasks); + } + + [Fact] + public async Task ResolveServerServer() { + var tasks = _config.ExpectedHomeserverFederationMappings.Select(async mapping => { + var server = await _resolver.ResolveHomeserverFromWellKnown(mapping.Key); + Assert.Equal(mapping.Value, server.Server); + return server; + }).ToList(); + await Task.WhenAll(tasks); + } + + [Fact] + public async Task ResolveMedia() { + var media = await _resolver.ResolveMediaUri("matrix.org", "mxc://matrix.org/eqwrRZRoPpNbcMeUwyXAuVRo"); + + Assert.Equal("https://matrix-client.matrix.org/_matrix/media/v3/download/matrix.org/eqwrRZRoPpNbcMeUwyXAuVRo", media); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/ResolverTest.cs b/Tests/LibMatrix.Tests/Tests/RemoteHomeserverTests.cs index 700aa96..03f3c24 100644 --- a/Tests/LibMatrix.Tests/Tests/ResolverTest.cs +++ b/Tests/LibMatrix.Tests/Tests/RemoteHomeserverTests.cs @@ -5,13 +5,13 @@ using Xunit.Microsoft.DependencyInjection.Abstracts; namespace LibMatrix.Tests.Tests; -public class ResolverTest : TestBed<TestFixture> { +public class RemoteHomeserverTests : TestBed<TestFixture> { private readonly TestFixture _fixture; private readonly HomeserverResolverService _resolver; private readonly Config _config; private readonly HomeserverProviderService _provider; - public ResolverTest(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + public RemoteHomeserverTests(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)}"); @@ -19,29 +19,30 @@ public class ResolverTest : TestBed<TestFixture> { } [Fact] - public async Task ResolveServer() { - foreach (var (domain, expected) in _config.ExpectedHomeserverMappings) { - var server = await _resolver.ResolveHomeserverFromWellKnown(domain); - Assert.Equal(expected, server.Client); - } - } - - [Fact] public async Task ResolveMedia() { - var media = await _resolver.ResolveMediaUri("matrix.org", "mxc://matrix.org/eqwrRZRoPpNbcMeUwyXAuVRo"); + var hs = await _provider.GetRemoteHomeserver("matrix.org"); + var media = hs.ResolveMediaUri("mxc://matrix.org/eqwrRZRoPpNbcMeUwyXAuVRo"); + Assert.Equal("https://matrix-client.matrix.org/_matrix/media/v3/download/matrix.org/eqwrRZRoPpNbcMeUwyXAuVRo", media); } [Fact] public async Task ResolveRoomAliasAsync() { - var hs = await _provider.GetRemoteHomeserver("matrix.org"); - var alias = await hs.ResolveRoomAliasAsync("#matrix:matrix.org"); - Assert.Equal("!OGEhHVWSdvArJzumhm:matrix.org", alias.RoomId); + // var hs = await _provider.GetRemoteHomeserver("matrix.org"); + // var alias = await hs.ResolveRoomAliasAsync("#matrix:matrix.org"); + // Assert.Equal("!OGEhHVWSdvArJzumhm:matrix.org", alias.RoomId); + var tasks = _config.ExpectedAliasMappings.Select(async mapping => { + var hs = await _provider.GetRemoteHomeserver("matrix.org"); + var alias = await hs.ResolveRoomAliasAsync(mapping.Key); + Assert.Equal(mapping.Value, alias.RoomId); + return alias; + }).ToList(); + await Task.WhenAll(tasks); } [Fact] public async Task GetClientVersionsAsync() { - var hs = await _provider.GetRemoteHomeserver("matrix.org"); + var hs = await _provider.GetRemoteHomeserver(_config.TestHomeserver); var versions = await hs.GetClientVersionsAsync(); Assert.NotNull(versions); } diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests.cs deleted file mode 100644 index 4c8dcb4..0000000 --- a/Tests/LibMatrix.Tests/Tests/RoomTests.cs +++ /dev/null @@ -1,248 +0,0 @@ -using System.Text; -using LibMatrix.EventTypes.Spec.State; -using LibMatrix.Homeservers; -using LibMatrix.Responses; -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 RoomTests : TestBed<TestFixture> { - private readonly TestFixture _fixture; - private readonly HomeserverResolverService _resolver; - private readonly Config _config; - private readonly HomeserverProviderService _provider; - - public RoomTests(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() => await HomeserverAbstraction.GetHomeserver(); - - [Fact] - public async Task GetJoinedRoomsAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - //make 100 rooms - 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.True(rooms.Count >= 10, "Not enough rooms were found"); - - await hs.Logout(); - } - - [Fact] - public async Task GetMembersAsync() { - Assert.True(StateEvent.KnownStateEventTypes is { Count: > 0 }, "StateEvent.KnownStateEventTypes is empty!"); - Assert.True(StateEvent.KnownStateEventTypesByName is { Count: > 0 }, "StateEvent.KnownStateEventTypesByName is empty!"); - - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - var members = room.GetMembersEnumerableAsync(); - Assert.NotNull(members); - var hitMembers = false; - await foreach (var member in members) { - Assert.NotNull(member); - Assert.NotNull(member.StateKey); - Assert.NotEmpty(member.StateKey); - Assert.NotNull(member.Sender); - Assert.NotEmpty(member.Sender); - Assert.NotNull(member.RawContent); - Assert.NotEmpty(member.RawContent); - Assert.NotNull(member.TypedContent); - Assert.IsType<RoomMemberEventContent>(member.TypedContent); - var content = (RoomMemberEventContent)member.TypedContent; - Assert.NotNull(content); - Assert.NotNull(content.Membership); - Assert.NotEmpty(content.Membership); - hitMembers = true; - } - - Assert.True(hitMembers, "No members were found in the room"); - } - - [Fact] - public async Task JoinAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - var id = await room.JoinAsync(); - Assert.NotNull(id); - Assert.NotNull(id.RoomId); - Assert.NotEmpty(id.RoomId); - } - - [Fact] - public async Task ForgetAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - await room.ForgetAsync(); - } - - [Fact] - public async Task LeaveAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - await room.LeaveAsync(); - } - - [Fact] - public async Task KickAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var hs2 = await HomeserverAbstraction.GetRandomHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - await room.InviteUserAsync(hs2.UserId, "Unit test!"); - await hs2.GetRoom(room.RoomId).JoinAsync(); - await room.KickAsync(hs2.UserId, "test"); - var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); - Assert.NotNull(banState); - Assert.Equal("leave", banState.Membership); - } - - [Fact] - public async Task BanAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var hs2 = await HomeserverAbstraction.GetRandomHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - await room.BanAsync(hs2.UserId, "test"); - var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); - Assert.NotNull(banState); - Assert.Equal("ban", banState.Membership); - } - - [Fact] - public async Task UnbanAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var hs2 = await HomeserverAbstraction.GetRandomHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - await room.BanAsync(hs2.UserId, "test"); - var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); - Assert.NotNull(banState); - Assert.Equal("ban", banState.Membership); - await room.UnbanAsync(hs2.UserId); - var unbanState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); - Assert.NotNull(unbanState); - Assert.Equal("leave", unbanState.Membership); - } - - [SkippableFact(typeof(MatrixException))] - public async Task SendStateEventAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - - await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", new UserProfileResponse() { - DisplayName = "wee_woo", - AvatarUrl = "no" - }); - await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", "state_key_maybe", new UserProfileResponse() { - DisplayName = "wee_woo", - AvatarUrl = "yes" - }); - } - - [SkippableFact(typeof(MatrixException))] - public async Task SendAndGetStateEventAsync() { - await SendStateEventAsync(); - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - - await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", new UserProfileResponse() { - DisplayName = "wee_woo", - AvatarUrl = "no" - }); - await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", "state_key_maybe", new UserProfileResponse() { - DisplayName = "wee_woo", - AvatarUrl = "yes" - }); - - var state1 = await room.GetStateAsync<UserProfileResponse>("gay.rory.libmatrix.unit_tests"); - Assert.NotNull(state1); - Assert.NotNull(state1.DisplayName); - Assert.NotEmpty(state1.DisplayName); - Assert.NotNull(state1.AvatarUrl); - Assert.NotEmpty(state1.AvatarUrl); - Assert.Equal("wee_woo", state1.DisplayName); - Assert.Equal("no", state1.AvatarUrl); - - var state2 = await room.GetStateAsync<UserProfileResponse>("gay.rory.libmatrix.unit_tests", "state_key_maybe"); - Assert.NotNull(state2); - Assert.NotNull(state2.DisplayName); - Assert.NotEmpty(state2.DisplayName); - Assert.NotNull(state2.AvatarUrl); - Assert.NotEmpty(state2.AvatarUrl); - Assert.Equal("wee_woo", state2.DisplayName); - Assert.Equal("yes", state2.AvatarUrl); - } - - [Fact] - public async Task DisbandAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - - await room.PermanentlyBrickRoomAsync(); - } - - [Fact] - public async Task SendFileAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var room = await RoomAbstraction.GetTestRoom(hs); - Assert.NotNull(room); - - var res = await room.SendFileAsync("test.txt", new MemoryStream(Encoding.UTF8.GetBytes("This test was written by Emma [it/its], member of the Rory& system." + - "\nIf you are reading this on matrix, it means the unit test for uploading a file works!"))); - Assert.NotNull(res); - Assert.NotNull(res.EventId); - } - - [Fact] - public async Task GetSpaceChildrenAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); - var space = await RoomAbstraction.GetTestSpace(hs, 2, false, 1); - Assert.NotNull(space); - var children = space.GetChildrenAsync(); - Assert.NotNull(children); - var found = 0; - await foreach (var room in children) found++; - Assert.Equal(2, found); - } - - [Fact] - public async Task InviteAndJoinAsync() { - 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) - tasks.Add(Task.Run(async () => { - await room.InviteUserAsync(otherUser.UserId); - await otherUser.GetRoom(room.RoomId).JoinAsync(); - })); - await Task.WhenAll(tasks); - - var states = await room.GetMembersListAsync(false); - Assert.Equal(16, states.Count); - } -} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/OtherRoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/OtherRoomTests.cs new file mode 100644 index 0000000..1ae195d --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/OtherRoomTests.cs @@ -0,0 +1,101 @@ +using LibMatrix.Tests.Abstractions; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace LibMatrix.Tests.Tests.BasicRoomEventTests; + +public class OtherRoomTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public OtherRoomTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [SkippableFact(typeof(MatrixException))] + public async Task GetCanonicalAliasAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + 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); + } + + [Fact] + public async Task GetJoinRuleAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + var rule = await room.GetJoinRuleAsync(); + Assert.NotNull(rule); + Assert.NotNull(rule.JoinRuleValue); + Assert.NotEmpty(rule.JoinRuleValue); + } + + [Fact] + public async Task GetHistoryVisibilityAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + 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 _hsAbstraction.GetConfiguredHomeserver(); + 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 _hsAbstraction.GetConfiguredHomeserver(); + 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 _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.GetRoomType(); + } + + [Fact] + public async Task GetPowerLevelsAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + 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); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomAvatarTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomAvatarTests.cs new file mode 100644 index 0000000..78f007c --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomAvatarTests.cs @@ -0,0 +1,27 @@ +using LibMatrix.Tests.Abstractions; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace LibMatrix.Tests.Tests.BasicRoomEventTests; + +public class RoomAvatarTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public RoomAvatarTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [SkippableFact(typeof(MatrixException))] + public async Task GetAvatarUrlAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + 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); + + await room.LeaveAsync(); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomNameTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomNameTests.cs new file mode 100644 index 0000000..1ea3e18 --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomNameTests.cs @@ -0,0 +1,42 @@ +using LibMatrix.EventTypes.Spec.State; +using LibMatrix.Tests.Abstractions; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace LibMatrix.Tests.Tests.BasicRoomEventTests; + +public class RoomNameTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public RoomNameTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [Fact] + public async Task GetNameAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + var name = await room.GetNameAsync(); + Assert.NotNull(name); + Assert.NotEmpty(name); + + await room.LeaveAsync(); + } + + [Fact] + public async Task SetNameAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + var name = Guid.NewGuid().ToString(); + await room.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent { Name = name }); + var newName = await room.GetNameAsync(); + Assert.Equal(name, newName); + + await room.LeaveAsync(); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomTopicTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomTopicTests.cs new file mode 100644 index 0000000..6610035 --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/BasicRoomEventTests/RoomTopicTests.cs @@ -0,0 +1,27 @@ +using LibMatrix.Tests.Abstractions; +using LibMatrix.Tests.Fixtures; +using Xunit.Abstractions; +using Xunit.Microsoft.DependencyInjection.Abstracts; + +namespace LibMatrix.Tests.Tests.BasicRoomEventTests; + +public class RoomTopicTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public RoomTopicTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [SkippableFact(typeof(MatrixException))] + public async Task GetTopicAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + 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); + + await room.LeaveAsync(); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomEventTests.cs index 932909f..9081a5a 100644 --- a/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomEventTests.cs @@ -8,23 +8,16 @@ 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; + private readonly HomeserverAbstraction _hsAbstraction; 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)}"); + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); } - private async Task<AuthenticatedHomeserverGeneric> GetHomeserver() => await HomeserverAbstraction.GetHomeserver(); - [Fact] public async Task GetNameAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); var name = await room.GetNameAsync(); @@ -34,7 +27,7 @@ public class RoomEventTests : TestBed<TestFixture> { [SkippableFact(typeof(MatrixException))] public async Task GetTopicAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); var topic = await room.GetTopicAsync(); @@ -44,19 +37,8 @@ public class RoomEventTests : TestBed<TestFixture> { } [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 hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); var alias = await room.GetCanonicalAliasAsync(); @@ -67,40 +49,46 @@ public class RoomEventTests : TestBed<TestFixture> { [SkippableFact(typeof(MatrixException))] public async Task GetAvatarUrlAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); 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); + + await room.LeaveAsync(); } [Fact] public async Task GetJoinRuleAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); var rule = await room.GetJoinRuleAsync(); Assert.NotNull(rule); Assert.NotNull(rule.JoinRuleValue); Assert.NotEmpty(rule.JoinRuleValue); + + await room.LeaveAsync(); } [Fact] public async Task GetHistoryVisibilityAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); 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); + + await room.LeaveAsync(); } [Fact] public async Task GetGuestAccessAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); try { @@ -113,30 +101,36 @@ public class RoomEventTests : TestBed<TestFixture> { if (e is not MatrixException exception) throw; Assert.Equal("M_NOT_FOUND", exception.ErrorCode); } + + await room.LeaveAsync(); } [Fact] public async Task GetCreateEventAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); 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!); + + await room.LeaveAsync(); } [Fact] public async Task GetRoomType() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); await room.GetRoomType(); + + await room.LeaveAsync(); } [Fact] public async Task GetPowerLevelsAsync() { - var hs = await HomeserverAbstraction.GetHomeserver(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); var power = await room.GetPowerLevelsAsync(); @@ -150,5 +144,7 @@ public class RoomEventTests : TestBed<TestFixture> { Assert.NotNull(power.UsersDefault); Assert.NotNull(power.Users); // Assert.NotNull(power.Events); + + await room.LeaveAsync(); } } \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/RoomMembershipTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomMembershipTests.cs new file mode 100644 index 0000000..2e552e2 --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomMembershipTests.cs @@ -0,0 +1,178 @@ +using System.Diagnostics; +using System.Text; +using ArcaneLibs.Extensions; +using LibMatrix.EventTypes.Spec.State; +using LibMatrix.Homeservers; +using LibMatrix.Responses; +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 RoomMembershipTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public RoomMembershipTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [Fact] + public async Task GetMembersAsync() { + Assert.True(StateEvent.KnownStateEventTypes is { Count: > 0 }, "StateEvent.KnownStateEventTypes is empty!"); + Assert.True(StateEvent.KnownStateEventTypesByName is { Count: > 0 }, "StateEvent.KnownStateEventTypesByName is empty!"); + + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + var members = room.GetMembersEnumerableAsync(); + Assert.NotNull(members); + var hitMembers = false; + await foreach (var member in members) { + Assert.NotNull(member); + Assert.NotNull(member.StateKey); + Assert.NotEmpty(member.StateKey); + Assert.NotNull(member.Sender); + Assert.NotEmpty(member.Sender); + Assert.NotNull(member.RawContent); + Assert.NotEmpty(member.RawContent); + Assert.NotNull(member.TypedContent); + Assert.IsType<RoomMemberEventContent>(member.TypedContent); + var content = (RoomMemberEventContent)member.TypedContent; + Assert.NotNull(content); + Assert.NotNull(content.Membership); + Assert.NotEmpty(content.Membership); + hitMembers = true; + } + + Assert.True(hitMembers, "No members were found in the room"); + + await room.LeaveAsync(); + } + + [Fact] + public async Task JoinAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(_testOutputHelper); + var hs2 = await _hsAbstraction.GetNewHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() { + JoinRule = RoomJoinRulesEventContent.JoinRules.Public + }); + // var id = await room.JoinAsync(); + var id = await hs2.GetRoom(room.RoomId).JoinAsync(); + Assert.NotNull(id); + Assert.NotNull(id.RoomId); + Assert.NotEmpty(id.RoomId); + + await room.LeaveAsync(); + } + + [Fact] + public async Task ForgetAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.ForgetAsync(); + } + + [Fact] + public async Task LeaveAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.LeaveAsync(); + } + + [Fact] + public async Task KickAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var hs2 = await _hsAbstraction.GetNewHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.InviteUserAsync(hs2.UserId, "Unit test!"); + await hs2.GetRoom(room.RoomId).JoinAsync(); + await room.KickAsync(hs2.UserId, "test"); + var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); + Assert.NotNull(banState); + Assert.Equal("leave", banState.Membership); + Assert.Equal("test", banState.Reason); + + await room.LeaveAsync(); + } + + [Fact] + public async Task BanAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var hs2 = await _hsAbstraction.GetNewHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.BanAsync(hs2.UserId, "test"); + var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); + Assert.NotNull(banState); + Assert.Equal("ban", banState.Membership); + + await room.LeaveAsync(); + } + + [Fact] + public async Task UnbanAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var hs2 = await _hsAbstraction.GetNewHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + await room.BanAsync(hs2.UserId, "test"); + var banState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); + Assert.NotNull(banState); + Assert.Equal("ban", banState.Membership); + await room.UnbanAsync(hs2.UserId, "testing"); + + var unbanState = await room.GetStateAsync<RoomMemberEventContent>("m.room.member", hs2.UserId); + Assert.NotNull(unbanState); + Assert.Equal("leave", unbanState.Membership); + Assert.Equal("testing", unbanState.Reason); + + await room.LeaveAsync(); + } + + [Fact] + public async Task InviteAndJoinAsync() { + int count = 5; + + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + var otherUsers = _hsAbstraction.GetNewHomeservers(count); + Assert.NotNull(room); + + // var expectedCount = 1; + + // var tasks = new List<Task>(); + // await foreach (var otherUser in otherUsers) + // tasks.AddRange([ + // room.InviteUserAsync(otherUser.UserId), + // otherUser.GetRoom(room.RoomId).JoinAsync() + // ]); + + Dictionary<AuthenticatedHomeserverGeneric, Task> tasks = new(); + await foreach (var otherUser in otherUsers) { + _testOutputHelper.WriteLine($"Inviting {otherUser.UserId} to {room.RoomId}"); + tasks.Add(otherUser, room.InviteUserAsync(otherUser.UserId, "Unit test!")); + } + + await foreach (var otherUser in tasks.ToAsyncEnumerable()) { + _testOutputHelper.WriteLine($"Joining {otherUser.UserId} to {room.RoomId}"); + await otherUser.GetRoom(room.RoomId).JoinAsync(reason: "Unit test!"); + } + + var states = await room.GetMembersListAsync(false); + Assert.Equal(count + 1, states.Count); + + await room.LeaveAsync(); + await foreach (var authenticatedHomeserverGeneric in otherUsers) + { + await authenticatedHomeserverGeneric.GetRoom(room.RoomId).LeaveAsync(); + } + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/RoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomTests.cs new file mode 100644 index 0000000..401b24f --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/RoomTests.cs @@ -0,0 +1,320 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; +using ArcaneLibs.Extensions; +using LibMatrix.EventTypes.Spec; +using LibMatrix.EventTypes.Spec.State; +using LibMatrix.Homeservers; +using LibMatrix.Responses; +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 RoomTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public RoomTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [Fact] + public async Task GetJoinedRoomsAsync() { + var hs = await _hsAbstraction.GetNewHomeserver(); + //make 100 rooms + 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.True(rooms.Count >= 10, "Not enough rooms were found"); + Assert.Equal(10, rooms.Count); + await hs.Logout(); + } + + [Fact] + public async Task GetMembersAsync() { + Assert.True(StateEvent.KnownStateEventTypes is { Count: > 0 }, "StateEvent.KnownStateEventTypes is empty!"); + Assert.True(StateEvent.KnownStateEventTypesByName is { Count: > 0 }, "StateEvent.KnownStateEventTypesByName is empty!"); + + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + var members = room.GetMembersEnumerableAsync(); + Assert.NotNull(members); + var hitMembers = false; + await foreach (var member in members) { + Assert.NotNull(member); + Assert.NotNull(member.StateKey); + Assert.NotEmpty(member.StateKey); + Assert.NotNull(member.Sender); + Assert.NotEmpty(member.Sender); + Assert.NotNull(member.RawContent); + Assert.NotEmpty(member.RawContent); + Assert.NotNull(member.TypedContent); + Assert.IsType<RoomMemberEventContent>(member.TypedContent); + var content = (RoomMemberEventContent)member.TypedContent; + Assert.NotNull(content); + Assert.NotNull(content.Membership); + Assert.NotEmpty(content.Membership); + hitMembers = true; + } + + Assert.True(hitMembers, "No members were found in the room"); + + await room.LeaveAsync(); + } + + [SkippableFact(typeof(MatrixException))] + public async Task SendStateEventAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", new UserProfileResponse() { + DisplayName = "wee_woo", + AvatarUrl = "no" + }); + await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", "state_key_maybe", new UserProfileResponse() { + DisplayName = "wee_woo", + AvatarUrl = "yes" + }); + + await room.LeaveAsync(); + } + + [SkippableFact(typeof(MatrixException))] + public async Task SendAndGetStateEventAsync() { + await SendStateEventAsync(); + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", new UserProfileResponse() { + DisplayName = "wee_woo", + AvatarUrl = "no" + }); + await room.SendStateEventAsync("gay.rory.libmatrix.unit_tests", "state_key_maybe", new UserProfileResponse() { + DisplayName = "wee_woo", + AvatarUrl = "yes" + }); + + var state1 = await room.GetStateAsync<UserProfileResponse>("gay.rory.libmatrix.unit_tests"); + Assert.NotNull(state1); + Assert.NotNull(state1.DisplayName); + Assert.NotEmpty(state1.DisplayName); + Assert.NotNull(state1.AvatarUrl); + Assert.NotEmpty(state1.AvatarUrl); + Assert.Equal("wee_woo", state1.DisplayName); + Assert.Equal("no", state1.AvatarUrl); + + var state2 = await room.GetStateAsync<UserProfileResponse>("gay.rory.libmatrix.unit_tests", "state_key_maybe"); + Assert.NotNull(state2); + Assert.NotNull(state2.DisplayName); + Assert.NotEmpty(state2.DisplayName); + Assert.NotNull(state2.AvatarUrl); + Assert.NotEmpty(state2.AvatarUrl); + Assert.Equal("wee_woo", state2.DisplayName); + Assert.Equal("yes", state2.AvatarUrl); + + await room.LeaveAsync(); + } + + [Fact] + public async Task DisbandAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + await room.PermanentlyBrickRoomAsync(); + + await room.LeaveAsync(); + } + + [Fact] + public async Task SendFileAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var res = await room.SendFileAsync("test.txt", new MemoryStream(Encoding.UTF8.GetBytes("This test was written by Emma [it/its], member of the Rory& system." + + "\nIf you are reading this on matrix, it means the unit test for uploading a file works!"))); + Assert.NotNull(res); + Assert.NotNull(res.EventId); + + await room.LeaveAsync(); + } + + [Fact] + public async Task GetFullStateAsListAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var state = await room.GetFullStateAsListAsync(); + Assert.NotNull(state); + Assert.NotEmpty(state); + Assert.All(state, Assert.NotNull); + Assert.All(state, s => { + Assert.NotNull(s.EventId); + Assert.NotEmpty(s.EventId); + Assert.NotNull(s.Sender); + Assert.NotEmpty(s.Sender); + Assert.NotNull(s.RawContent); + Assert.NotNull(s.TypedContent); + }); + + await room.LeaveAsync(); + } + + [SkippableFact(typeof(LibMatrixException))] + public async Task GetStateEventAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var state = await room.GetStateEventAsync("m.room.name"); + Assert.NotNull(state); + Assert.NotNull(state.EventId); + Assert.NotEmpty(state.EventId); + Assert.NotNull(state.Sender); + Assert.NotEmpty(state.Sender); + Assert.NotNull(state.RawContent); + Assert.NotEmpty(state.RawContent); + Assert.NotNull(state.TypedContent); + + await room.LeaveAsync(); + } + + [Fact] + public async Task GetStateEventIdAsync() { + var hs = await _hsAbstraction.GetNewHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var state = await room.GetStateEventIdAsync("m.room.name"); + Assert.NotNull(state); + Assert.NotEmpty(state); + + await room.LeaveAsync(); + } + + [SkippableFact(typeof(LibMatrixException))] + public async Task GetStateEventOrNullAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var state = await room.GetStateEventOrNullAsync("m.room.name"); + Assert.NotNull(state); + Assert.NotNull(state.EventId); + Assert.NotEmpty(state.EventId); + Assert.NotNull(state.Sender); + Assert.NotEmpty(state.Sender); + Assert.NotNull(state.RawContent); + Assert.NotEmpty(state.RawContent); + Assert.NotNull(state.TypedContent); + + await room.LeaveAsync(); + } + + [Fact] + public async Task GetMessagesAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var messages = await room.GetMessagesAsync(); + Assert.NotNull(messages); + Assert.NotNull(messages.Chunk); + Assert.NotEmpty(messages.Chunk); + Assert.All(messages.Chunk, Assert.NotNull); + Assert.All(messages.Chunk, m => { + Assert.NotNull(m.EventId); + Assert.NotEmpty(m.EventId); + Assert.NotNull(m.Sender); + Assert.NotEmpty(m.Sender); + Assert.NotNull(m.RawContent); + Assert.NotNull(m.TypedContent); + }); + + await room.LeaveAsync(); + + await File.WriteAllTextAsync("test.json", messages.ToJson()); + } + + [Fact] + public async Task GetManyMessagesAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var messages = room.GetManyMessagesAsync(chunkSize: 2); + await foreach (var resp in messages) { + Assert.NotNull(resp); + Assert.NotNull(resp.Chunk); + // Assert.NotEmpty(resp.Chunk); + Assert.All(resp.Chunk, Assert.NotNull); + Assert.All(resp.Chunk, m => { + Assert.NotNull(m.EventId); + Assert.NotEmpty(m.EventId); + Assert.NotNull(m.Sender); + Assert.NotEmpty(m.Sender); + Assert.NotNull(m.RawContent); + Assert.NotNull(m.TypedContent); + }); + } + + await room.LeaveAsync(); + } + + [Fact] + public async Task SendMessageEventAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var res = await room.SendMessageEventAsync(new RoomMessageEventContent(body: "This test was written by Emma [it/its], member of the Rory& system." + + "\nIf you are reading this on matrix, it means the unit test for sending a message works!", messageType: "m.text")); + Assert.NotNull(res); + Assert.NotNull(res.EventId); + + await room.LeaveAsync(); + } + + [Fact] + public async Task InviteUsersAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var room = await RoomAbstraction.GetTestRoom(hs); + Assert.NotNull(room); + + var users = _hsAbstraction.GetNewHomeservers(32).ToBlockingEnumerable().ToList(); + Assert.NotNull(users); + Assert.NotEmpty(users); + Assert.All(users, Assert.NotNull); + Assert.All(users, u => { + Assert.NotNull(u); + Assert.NotNull(u.UserId); + Assert.NotEmpty(u.UserId); + }); + + await room.InviteUsersAsync(users.Select(u => u.UserId)); + var members = await room.GetMembersListAsync(false); + Assert.NotNull(members); + Assert.NotEmpty(members); + Assert.All(members, Assert.NotNull); + Assert.All(members, m => { + Assert.NotNull(m); + Assert.NotNull(m.StateKey); + Assert.NotEmpty(m.StateKey); + }); + Assert.All(users, u => Assert.Contains(u.UserId, members.Select(m => m.StateKey))); + + await room.LeaveAsync(); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests/SpaceTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests/SpaceTests.cs new file mode 100644 index 0000000..148b5fe --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/RoomTests/SpaceTests.cs @@ -0,0 +1,101 @@ +using System.Diagnostics; +using System.Text; +using ArcaneLibs.Extensions; +using LibMatrix.EventTypes.Spec.State; +using LibMatrix.Homeservers; +using LibMatrix.Responses; +using LibMatrix.RoomTypes; +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 SpaceTests : TestBed<TestFixture> { + private readonly HomeserverAbstraction _hsAbstraction; + + public SpaceTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); + } + + [Fact] + public async Task AddChildAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var crq = new CreateRoomRequest() { + Name = "Test space" + }; + crq.CreationContent["type"] = SpaceRoom.TypeName; + var space = (await hs.CreateRoom(crq)).AsSpace; + + var child = await hs.CreateRoom(new CreateRoomRequest() { + Name = "Test child" + }); + + await space.AddChildAsync(child); + + //validate children + var children = space.GetChildrenAsync().ToBlockingEnumerable().ToList(); + Assert.NotNull(children); + Assert.NotEmpty(children); + Assert.Single(children, x => x.RoomId == child.RoomId); + } + + [Fact] + public async Task AddChildByIdAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var crq = new CreateRoomRequest() { + Name = "Test space" + }; + crq.CreationContent["type"] = SpaceRoom.TypeName; + var space = (await hs.CreateRoom(crq)).AsSpace; + + var child = await hs.CreateRoom(new CreateRoomRequest() { + Name = "Test child" + }); + + await space.AddChildByIdAsync(child.RoomId); + + //validate children + var children = space.GetChildrenAsync().ToBlockingEnumerable().ToList(); + Assert.NotNull(children); + Assert.NotEmpty(children); + Assert.Single(children, x => x.RoomId == child.RoomId); + } + + [Fact] + public async Task GetChildrenAsync() { + var hs = await _hsAbstraction.GetConfiguredHomeserver(); + var expectedChildren = Enumerable.Range(0, 10).Select(async _ => { + var room = await hs.CreateRoom(new CreateRoomRequest() { + Name = "Test child" + }); + return room; + }).ToAsyncEnumerable().ToBlockingEnumerable().ToList(); + + var crq = new CreateRoomRequest() { + Name = "Test space", + InitialState = expectedChildren.Select(c => new StateEvent() { + Type = "m.space.child", + StateKey = c.RoomId, + TypedContent = new SpaceChildEventContent() { + Via = new List<string> { + c.RoomId.Split(":")[1] + } + } + }).ToList() + }; + crq.CreationContent["type"] = SpaceRoom.TypeName; + var space = (await hs.CreateRoom(crq)).AsSpace; + + var children = space.GetChildrenAsync().ToBlockingEnumerable().ToList(); + Assert.NotNull(children); + Assert.NotEmpty(children); + Assert.Equal(expectedChildren.Count, children.Count); + foreach (var expectedChild in expectedChildren) + { + Assert.Single(children, x => x.RoomId == expectedChild.RoomId); + } + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs index 7fc7c64..1c5747c 100644 --- a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs +++ b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs @@ -1,74 +1,69 @@ -using System.Diagnostics; -using LibMatrix.Helpers; -using LibMatrix.Services; -using LibMatrix.Tests.Abstractions; -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(); - } -} \ No newline at end of file +// using System.Diagnostics; +// using LibMatrix.Helpers; +// using LibMatrix.Services; +// using LibMatrix.Tests.Abstractions; +// 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 HomeserverAbstraction _hsAbstraction; +// private readonly ILogger<TestCleanup> _logger; +// +// public TestCleanup(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { +// // _fixture = fixture; +// _logger = _fixture.GetService<ILogger<TestCleanup>>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(ILogger<TestCleanup>)}"); +// _hsAbstraction = _fixture.GetService<HomeserverAbstraction>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverAbstraction)}"); +// } +// +// [SkippableFact(typeof(MatrixException))] +// 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 _hsAbstraction.GetConfiguredHomeserver(); +// 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 tasks2 = response.Rooms.Leave.Select(async room => { +// await hs.GetRoom(room.Key).ForgetAsync(); +// return room; +// }).ToList(); +// await Task.WhenAll(tasks2); +// } +// }); +// await syncHelper.RunSyncLoopAsync(cancellationToken: cancellationTokenSource.Token); +// +// Assert.NotNull(hs); +// await hs.Logout(); +// } +// } \ No newline at end of file |