From 28f738ba433fb1012f693866dc4b3f521fd824b5 Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Tue, 2 Jul 2024 01:57:46 +0200 Subject: Authenticated media foundations --- ArcaneLibs | 2 +- LibMatrix/Extensions/MatrixHttpClient.Single.cs | 3 +- .../Homeservers/AuthenticatedHomeserverGeneric.cs | 32 ++++++++++++++++++++++ LibMatrix/Homeservers/RemoteHomeServer.cs | 1 + LibMatrix/RoomTypes/GenericRoom.cs | 17 +----------- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/ArcaneLibs b/ArcaneLibs index d63d758..3fb65c1 160000 --- a/ArcaneLibs +++ b/ArcaneLibs @@ -1 +1 @@ -Subproject commit d63d7587b2e97a8925675c67a84f5ea22f6a3474 +Subproject commit 3fb65c126b591ca05e76394d4c40f74cbb70de44 diff --git a/LibMatrix/Extensions/MatrixHttpClient.Single.cs b/LibMatrix/Extensions/MatrixHttpClient.Single.cs index c9cd260..39eb7e5 100644 --- a/LibMatrix/Extensions/MatrixHttpClient.Single.cs +++ b/LibMatrix/Extensions/MatrixHttpClient.Single.cs @@ -26,7 +26,8 @@ public class MatrixHttpClient { EnableMultipleHttp2Connections = true }; Client = new HttpClient(handler) { - DefaultRequestVersion = new Version(3, 0) + DefaultRequestVersion = new Version(3, 0), + Timeout = TimeSpan.FromDays(1) }; } catch (PlatformNotSupportedException e) { diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index c729a44..40fdef3 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -61,15 +61,18 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { return rooms; } + [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, IEnumerable data, string contentType = "application/octet-stream") { return await UploadFile(fileName, data.ToArray(), contentType); } + [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, byte[] data, string contentType = "application/octet-stream") { await using var ms = new MemoryStream(data); return await UploadFile(fileName, ms, contentType); } + [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { var req = new HttpRequestMessage(HttpMethod.Post, $"/_matrix/media/v3/upload?filename={fileName}"); req.Content = new StreamContent(fileStream); @@ -406,4 +409,33 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { public NamedFilterCache FilterCache { get; init; } public NamedFileCache FileCache { get; init; } } + +#region Authenticated Media + + // TODO: implement /_matrix/client/v1/media/config when it's actually useful - https://spec.matrix.org/v1.11/client-server-api/#get_matrixclientv1mediaconfig + + private (string ServerName, string MediaId) ParseMxcUri(string mxcUri) { + if (!mxcUri.StartsWith("mxc://")) throw new ArgumentException("Matrix Content URIs must start with 'mxc://'", nameof(mxcUri)); + var parts = mxcUri[6..].Split('/'); + if (parts.Length != 2) throw new ArgumentException($"Invalid Matrix Content URI '{mxcUri}' passed! Matrix Content URIs must exist of only 2 parts!", nameof(mxcUri)); + return (parts[0], parts[1]); + } + + public async Task GetMediaStreamAsync(string mxcUri, int timeout = 0) { + var (serverName, mediaId) = ParseMxcUri(mxcUri); + try { + var res = await ClientHttpClient.GetAsync($"/_matrix/client/v1/media/download/{serverName}/{mediaId}"); + return await res.Content.ReadAsStreamAsync(); + } + catch (LibMatrixException e) { + Console.WriteLine($"Failed to get media stream: {e.Message}"); + throw; + } + + // return default; + } + + + +#endregion } \ No newline at end of file diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs index ecf3e3a..f9e3d04 100644 --- a/LibMatrix/Homeservers/RemoteHomeServer.cs +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs @@ -107,6 +107,7 @@ public class RemoteHomeserver { #endregion + [Obsolete("This call uses the deprecated unauthenticated media endpoints, please switch to the relevant AuthenticatedHomeserver methods instead.", true)] public string? ResolveMediaUri(string? mxcUri) { if (mxcUri is null) return null; if (mxcUri.StartsWith("https://")) return mxcUri; diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index fe2ee8d..b22ce2f 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -316,6 +316,7 @@ public class GenericRoom { public Task GetPowerLevelsAsync() => GetStateAsync("m.room.power_levels"); + [Obsolete("This method will be merged into GetNameAsync() in the future.")] public async Task GetNameOrFallbackAsync(int maxMemberNames = 2) { try { return await GetNameAsync(); @@ -352,22 +353,6 @@ public class GenericRoom { return Task.WhenAll(tasks); } - public async Task GetResolvedRoomAvatarUrlAsync(bool useOriginHomeserver = false) { - var avatar = await GetAvatarUrlAsync(); - if (avatar?.Url is null) return null; - if (!avatar.Url.StartsWith("mxc://")) return avatar.Url; - if (useOriginHomeserver) - try { - var hs = avatar.Url.Split('/', 3)[1]; - return await new HomeserverResolverService(NullLogger.Instance).ResolveMediaUri(hs, avatar.Url); - } - catch (Exception e) { - Console.WriteLine(e); - } - - return Homeserver.ResolveMediaUri(avatar.Url); - } - #endregion #region Simple calls -- cgit 1.4.1 From 3346c55e34d4f3f847dfe8113cb367e4bc72a2e5 Mon Sep 17 00:00:00 2001 From: Rory& Date: Mon, 16 Sep 2024 08:46:54 +0200 Subject: Fix room joining, power levels --- .../Spec/State/Policy/PolicyRuleStateEventContent.cs | 1 + .../Spec/State/RoomInfo/RoomPowerLevelEventContent.cs | 9 +++++---- LibMatrix/RoomTypes/GenericRoom.cs | 9 +++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs index 6006048..89e2fdb 100644 --- a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs @@ -79,6 +79,7 @@ public abstract class PolicyRuleEventContent : EventContent { /// [JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")] [FriendlyName(Name = "Expires at")] + [TableHide] public DateTime? ExpiryDateTime { get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime; set { diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs index 49a1b62..eb156b3 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs @@ -57,12 +57,13 @@ public class RoomPowerLevelEventContent : EventContent { return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault ?? 0); } - public bool UserHasStatePermission(string userId, string eventType) { + public bool UserHasStatePermission(string userId, string eventType, bool log = false) { ArgumentNullException.ThrowIfNull(userId); var userLevel = GetUserPowerLevel(userId); var eventLevel = GetStateEventPowerLevel(eventType); - - Console.WriteLine($"{userId}={userLevel} >= {eventType}={eventLevel} = {userLevel >= eventLevel}"); + + if (log) + Console.WriteLine($"{userId}={userLevel} >= {eventType}={eventLevel} = {userLevel >= eventLevel}"); return userLevel >= eventLevel; } @@ -78,7 +79,7 @@ public class RoomPowerLevelEventContent : EventContent { if (Events is null) return StateDefault ?? 0; return Events.TryGetValue(eventType, out var level) ? level : StateDefault ?? 0; } - + public long GetTimelineEventPowerLevel(string eventType) { ArgumentNullException.ThrowIfNull(eventType); if (Events is null) return EventsDefault ?? 0; diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index b22ce2f..4641349 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -210,10 +210,11 @@ public class GenericRoom { public async Task JoinAsync(string[]? homeservers = null, string? reason = null, bool checkIfAlreadyMember = true) { if (checkIfAlreadyMember) try { - _ = await GetCreateEventAsync(); - return new RoomIdResponse { - RoomId = RoomId - }; + var ser = await GetStateEventOrNullAsync(RoomMemberEventContent.EventId, Homeserver.UserId); + if (ser?.TypedContent is RoomMemberEventContent { Membership: "join" }) + return new RoomIdResponse { + RoomId = RoomId + }; } catch { } //ignore -- cgit 1.4.1 From 1713936ce7a0811de8b2c3022cf08a63fc62b966 Mon Sep 17 00:00:00 2001 From: Rory& Date: Tue, 17 Sep 2024 13:54:51 +0200 Subject: Fix unit tests, add authenticated media --- .../Homeservers/AuthenticatedHomeserverGeneric.cs | 97 ++++++++++++-- LibMatrix/RoomTypes/GenericRoom.cs | 2 +- .../Abstractions/HomeserverAbstraction.cs | 16 ++- Tests/LibMatrix.Tests/Tests/AuthMediaTests.cs | 56 ++++++++ Tests/LibMatrix.Tests/Tests/AuthTests.cs | 19 ++- Tests/LibMatrix.Tests/Tests/TestCleanup.cs | 148 ++++++++++----------- 6 files changed, 240 insertions(+), 98 deletions(-) create mode 100644 Tests/LibMatrix.Tests/Tests/AuthMediaTests.cs diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index 40fdef3..6be49b9 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -61,18 +61,15 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { return rooms; } - [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, IEnumerable data, string contentType = "application/octet-stream") { return await UploadFile(fileName, data.ToArray(), contentType); } - [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, byte[] data, string contentType = "application/octet-stream") { await using var ms = new MemoryStream(data); return await UploadFile(fileName, ms, contentType); } - [Obsolete("Use UploadMedia instead, as this method is deprecated.")] public virtual async Task UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { var req = new HttpRequestMessage(HttpMethod.Post, $"/_matrix/media/v3/upload?filename={fileName}"); req.Content = new StreamContent(fileStream); @@ -420,22 +417,100 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { if (parts.Length != 2) throw new ArgumentException($"Invalid Matrix Content URI '{mxcUri}' passed! Matrix Content URIs must exist of only 2 parts!", nameof(mxcUri)); return (parts[0], parts[1]); } - - public async Task GetMediaStreamAsync(string mxcUri, int timeout = 0) { + + public async Task GetMediaStreamAsync(string mxcUri, string? filename = null, int? timeout = null) { var (serverName, mediaId) = ParseMxcUri(mxcUri); try { - var res = await ClientHttpClient.GetAsync($"/_matrix/client/v1/media/download/{serverName}/{mediaId}"); + var uri = $"/_matrix/client/v1/media/download/{serverName}/{mediaId}"; + if (!string.IsNullOrWhiteSpace(filename)) uri += $"/{HttpUtility.UrlEncode(filename)}"; + if (timeout is not null) uri += $"?timeout_ms={timeout}"; + var res = await ClientHttpClient.GetAsync(uri); return await res.Content.ReadAsStreamAsync(); } - catch (LibMatrixException e) { - Console.WriteLine($"Failed to get media stream: {e.Message}"); - throw; + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNKNOWN" }) throw; } + //fallback to legacy media + try { + var uri = $"/_matrix/media/v1/download/{serverName}/{mediaId}"; + if (!string.IsNullOrWhiteSpace(filename)) uri += $"/{HttpUtility.UrlEncode(filename)}"; + if (timeout is not null) uri += $"?timeout_ms={timeout}"; + var res = await ClientHttpClient.GetAsync(uri); + return await res.Content.ReadAsStreamAsync(); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNKNOWN" }) throw; + } + + throw new LibMatrixException() { + ErrorCode = LibMatrixException.ErrorCodes.M_UNSUPPORTED, + Error = "Failed to download media" + }; // return default; } - - + + public async Task GetThumbnailStreamAsync(string mxcUri, int width, int height, string? method = null, int? timeout = null) { + var (serverName, mediaId) = ParseMxcUri(mxcUri); + try { + var uri = new Uri($"/_matrix/client/v1/thumbnail/{serverName}/{mediaId}"); + uri = uri.AddQuery("width", width.ToString()); + uri = uri.AddQuery("height", height.ToString()); + if (!string.IsNullOrWhiteSpace(method)) uri = uri.AddQuery("method", method); + if (timeout is not null) uri = uri.AddQuery("timeout_ms", timeout.ToString()); + + var res = await ClientHttpClient.GetAsync(uri.ToString()); + return await res.Content.ReadAsStreamAsync(); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNKNOWN" }) throw; + } + + //fallback to legacy media + try { + var uri = new Uri($"/_matrix/media/v1/thumbnail/{serverName}/{mediaId}"); + uri = uri.AddQuery("width", width.ToString()); + uri = uri.AddQuery("height", height.ToString()); + if (!string.IsNullOrWhiteSpace(method)) uri = uri.AddQuery("method", method); + if (timeout is not null) uri = uri.AddQuery("timeout_ms", timeout.ToString()); + + var res = await ClientHttpClient.GetAsync(uri.ToString()); + return await res.Content.ReadAsStreamAsync(); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNKNOWN" }) throw; + } + + throw new LibMatrixException() { + ErrorCode = LibMatrixException.ErrorCodes.M_UNSUPPORTED, + Error = "Failed to download media" + }; + // return default; + } + + public async Task?> GetUrlPreviewAsync(string url) { + try { + var res = await ClientHttpClient.GetAsync($"/_matrix/client/v1/media/preview_url?url={HttpUtility.UrlEncode(url)}"); + return await res.Content.ReadFromJsonAsync>(); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNRECOGNIZED" }) throw; + } + + //fallback to legacy media + try { + var res = await ClientHttpClient.GetAsync($"/_matrix/media/v1/preview_url?url={HttpUtility.UrlEncode(url)}"); + return await res.Content.ReadFromJsonAsync>(); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_UNRECOGNIZED" }) throw; + } + + throw new LibMatrixException() { + ErrorCode = LibMatrixException.ErrorCodes.M_UNSUPPORTED, + Error = "Failed to download URL preview" + }; + } #endregion } \ No newline at end of file diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index 4641349..349ccb5 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -379,7 +379,7 @@ public class GenericRoom { new UserIdAndReason { UserId = userId }); public async Task InviteUserAsync(string userId, string? reason = null, bool skipExisting = true) { - if (skipExisting && await GetStateAsync("m.room.member", userId) is not null) + if (skipExisting && await GetStateOrNullAsync("m.room.member", userId) is not null) return; await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason)); } diff --git a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs index c9727d6..13b5c1b 100644 --- a/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs +++ b/Tests/LibMatrix.Tests/Abstractions/HomeserverAbstraction.cs @@ -1,14 +1,17 @@ using ArcaneLibs.Extensions; using LibMatrix.Homeservers; using LibMatrix.Responses; +using LibMatrix.Services; +using Microsoft.Extensions.Logging.Abstractions; namespace LibMatrix.Tests.Abstractions; public static class HomeserverAbstraction { + private static HomeserverResolverService _hsResolver = new HomeserverResolverService(NullLogger.Instance); + private static HomeserverProviderService _hsProvider = new HomeserverProviderService(NullLogger.Instance, _hsResolver); + public static async Task GetHomeserver() { - var rhs = await RemoteHomeserver.Create("https://matrixunittests.rory.gay"); - // string username = Guid.NewGuid().ToString(); - // string password = Guid.NewGuid().ToString(); + var rhs = await _hsProvider.GetRemoteHomeserver("matrixunittests.rory.gay"); var username = "@f1a2d2d6-1924-421b-91d0-893b347b2a49:matrixunittests.rory.gay"; var password = "d6d782d6-8bc9-4fac-9cd8-78e101b4298b"; LoginResponse reg; @@ -23,8 +26,7 @@ public static class HomeserverAbstraction { else throw new Exception("Failed to register", e); } - var hs = await reg.GetAuthenticatedHomeserver("https://matrixunittests.rory.gay"); - + var hs = await _hsProvider.GetAuthenticatedWithToken(reg.Homeserver, reg.AccessToken); //var rooms = await hs.GetJoinedRooms(); // var disbandRoomTasks = rooms.Select(async room => { @@ -45,9 +47,9 @@ public static class HomeserverAbstraction { } public static async Task GetRandomHomeserver() { - var rhs = await RemoteHomeserver.Create("https://matrixunittests.rory.gay"); + var rhs = await _hsProvider.GetRemoteHomeserver("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 hs = await _hsProvider.GetAuthenticatedWithToken(reg.Homeserver, reg.AccessToken); // var rooms = await hs.GetJoinedRooms(); // diff --git a/Tests/LibMatrix.Tests/Tests/AuthMediaTests.cs b/Tests/LibMatrix.Tests/Tests/AuthMediaTests.cs new file mode 100644 index 0000000..b2f5627 --- /dev/null +++ b/Tests/LibMatrix.Tests/Tests/AuthMediaTests.cs @@ -0,0 +1,56 @@ +using ArcaneLibs.Extensions; +using ArcaneLibs.Extensions.Streams; +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 AuthMediaTests : TestBed { + private readonly TestFixture _fixture; + private readonly HomeserverResolverService _resolver; + private readonly Config _config; + private readonly HomeserverProviderService _provider; + + public AuthMediaTests(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { + _fixture = fixture; + _resolver = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}"); + _config = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}"); + _provider = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}"); + } + + private async Task GetHomeserver() => await HomeserverAbstraction.GetHomeserver(); + + [Fact] + public async Task UploadFileAsync() { + var hs = await HomeserverAbstraction.GetHomeserver(); + + var mxcUri = await hs.UploadFile("test", "LibMatrix test file".AsBytes()); + Assert.NotNull(mxcUri); + } + + [Fact] + public async Task DownloadFileAsync() { + var hs = await HomeserverAbstraction.GetHomeserver(); + + var mxcUri = await hs.UploadFile("test", "LibMatrix test file".AsBytes()); + Assert.NotNull(mxcUri); + + var file = await hs.GetMediaStreamAsync(mxcUri); + Assert.NotNull(file); + + var data = file!.ReadToEnd().AsString(); + Assert.Equal("LibMatrix test file", data); + } + + [SkippableFact(typeof(LibMatrixException))] // This test will fail if the homeserver does not support URL previews + public async Task GetUrlPreviewAsync() { + var hs = await HomeserverAbstraction.GetHomeserver(); + var preview = await hs.GetUrlPreviewAsync("https://matrix.org"); + + Assert.NotNull(preview); + } +} \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/AuthTests.cs b/Tests/LibMatrix.Tests/Tests/AuthTests.cs index f331dd0..3ffadf0 100644 --- a/Tests/LibMatrix.Tests/Tests/AuthTests.cs +++ b/Tests/LibMatrix.Tests/Tests/AuthTests.cs @@ -26,7 +26,13 @@ public class AuthTests : TestBed { 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 rhs = await _provider.GetRemoteHomeserver(_config.TestHomeserver); + var username = Guid.NewGuid().ToString(); + var password = Guid.NewGuid().ToString(); + + var reg = await rhs.RegisterAsync(username, password, "Unit tests!"); + + var login = await _provider.Login(_config.TestHomeserver!, username, password); Assert.NotNull(login); var hs = await _provider.GetAuthenticatedWithToken(_config.TestHomeserver!, login.AccessToken); Assert.NotNull(hs); @@ -40,10 +46,13 @@ public class AuthTests : TestBed { 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 rhs = await _provider.GetRemoteHomeserver(_config.TestHomeserver); + var username = Guid.NewGuid().ToString(); + var password = Guid.NewGuid().ToString(); + + var reg = await rhs.RegisterAsync(username, password, "Unit tests!"); + + var hs = await _provider.GetAuthenticatedWithToken(_config.TestHomeserver!, reg.AccessToken); Assert.NotNull(hs); Assert.NotNull(hs.WhoAmI); hs.WhoAmI.VerifyRequiredFields(); diff --git a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs index 7fc7c64..d9bea94 100644 --- a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs +++ b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs @@ -1,74 +1,74 @@ -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 { - // private readonly TestFixture _fixture; - private readonly HomeserverResolverService _resolver; - private readonly Config _config; - private readonly HomeserverProviderService _provider; - private readonly ILogger _logger; - - public TestCleanup(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { - // _fixture = fixture; - _resolver = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}"); - _config = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}"); - _provider = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}"); - _logger = _fixture.GetService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(ILogger)}"); - } - - [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 { +// // private readonly TestFixture _fixture; +// private readonly HomeserverResolverService _resolver; +// private readonly Config _config; +// private readonly HomeserverProviderService _provider; +// private readonly ILogger _logger; +// +// public TestCleanup(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { +// // _fixture = fixture; +// _resolver = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}"); +// _config = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}"); +// _provider = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}"); +// _logger = _fixture.GetService>(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(ILogger)}"); +// } +// +// [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 -- cgit 1.4.1