From 715123804c88f639da55659bb3d5eb8d48b42c30 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 15:39:02 +0100 Subject: [PATCH 01/33] Renamed shared test proj --- PinguApps.Appwrite.sln | 2 +- tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs | 2 +- .../PinguApps.Appwrite.Client.Tests.csproj | 2 +- tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs | 2 +- .../PinguApps.Appwrite.Server.Tests.csproj | 2 +- .../Constants.cs | 2 +- .../PinguApps.Appwrite.Shared.Tests.csproj} | 0 7 files changed, 6 insertions(+), 6 deletions(-) rename tests/{PinguApps.Appwrite.Tests.Shared => PinguApps.Appwrite.Shared.Tests}/Constants.cs (98%) rename tests/{PinguApps.Appwrite.Tests.Shared/PinguApps.Appwrite.Tests.Shared.csproj => PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj} (100%) diff --git a/PinguApps.Appwrite.sln b/PinguApps.Appwrite.sln index 6ef20be7..02e9cf76 100644 --- a/PinguApps.Appwrite.sln +++ b/PinguApps.Appwrite.sln @@ -19,7 +19,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PinguApps.Appwrite.Server.T EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PinguApps.Appwrite.Client.Tests", "tests\PinguApps.Appwrite.Client.Tests\PinguApps.Appwrite.Client.Tests.csproj", "{71C1431E-8098-4B9B-9CFA-A49F77242C79}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PinguApps.Appwrite.Tests.Shared", "tests\PinguApps.Appwrite.Tests.Shared\PinguApps.Appwrite.Tests.Shared.csproj", "{5AED345C-1E3E-4397-807C-8EFC22B786FA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PinguApps.Appwrite.Shared.Tests", "tests\PinguApps.Appwrite.Shared.Tests\PinguApps.Appwrite.Shared.Tests.csproj", "{5AED345C-1E3E-4397-807C-8EFC22B786FA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs b/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs index 4bd271d6..c314f8ed 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs @@ -1,7 +1,7 @@ using System.Net; using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Shared.Requests; -using PinguApps.Appwrite.Tests.Shared; +using PinguApps.Appwrite.Shared.Tests; using Refit; using RichardSzalay.MockHttp; diff --git a/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj b/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj index 3ff0562d..67240f04 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj +++ b/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs b/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs index 52a673f1..241436d0 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Server.Servers; using PinguApps.Appwrite.Shared.Requests; -using PinguApps.Appwrite.Tests.Shared; +using PinguApps.Appwrite.Shared.Tests; using Refit; using RichardSzalay.MockHttp; diff --git a/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj b/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj index 9587cc39..79aceb35 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj +++ b/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/tests/PinguApps.Appwrite.Tests.Shared/Constants.cs b/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs similarity index 98% rename from tests/PinguApps.Appwrite.Tests.Shared/Constants.cs rename to tests/PinguApps.Appwrite.Shared.Tests/Constants.cs index 56be3181..80ae2e24 100644 --- a/tests/PinguApps.Appwrite.Tests.Shared/Constants.cs +++ b/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs @@ -1,4 +1,4 @@ -namespace PinguApps.Appwrite.Tests.Shared; +namespace PinguApps.Appwrite.Shared.Tests; public static class Constants { diff --git a/tests/PinguApps.Appwrite.Tests.Shared/PinguApps.Appwrite.Tests.Shared.csproj b/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj similarity index 100% rename from tests/PinguApps.Appwrite.Tests.Shared/PinguApps.Appwrite.Tests.Shared.csproj rename to tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj From 4f63172fbb37c4273ac39b4c1bdd0bcf8ac32d81 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 15:47:01 +0100 Subject: [PATCH 02/33] Added tests for appwrite result --- .../AppwriteResultTests.cs | 40 +++++++++++++++++++ .../PinguApps.Appwrite.Shared.Tests.csproj | 22 +++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/AppwriteResultTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/AppwriteResultTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/AppwriteResultTests.cs new file mode 100644 index 00000000..bfb6d3f1 --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/AppwriteResultTests.cs @@ -0,0 +1,40 @@ +using OneOf; + +namespace PinguApps.Appwrite.Shared.Tests; + +public class AppwriteResultTests +{ + [Fact] + public void Constructor_WithTResult_SuccessIsTrue() + { + var result = new AppwriteResult(OneOf.FromT0("Success")); + + Assert.True(result.Success); + Assert.False(result.IsError); + Assert.False(result.IsAppwriteError); + Assert.False(result.IsInternalError); + Assert.True(result.Result.AsT0 == "Success"); + } + + [Fact] + public void Constructor_WithAppwriteError_IsAppwriteErrorIsTrue() + { + var result = new AppwriteResult(OneOf.FromT1(new AppwriteError("Message", 500, "Type", "Version"))); + + Assert.False(result.Success); + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + Assert.False(result.IsInternalError); + } + + [Fact] + public void Constructor_WithInternalError_IsInternalErrorIsTrue() + { + var result = new AppwriteResult(OneOf.FromT2(new InternalError("Message"))); + + Assert.False(result.Success); + Assert.True(result.IsError); + Assert.False(result.IsAppwriteError); + Assert.True(result.IsInternalError); + } +} diff --git a/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj b/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj index fa71b7ae..91503aea 100644 --- a/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj +++ b/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj @@ -1,9 +1,29 @@ - + net8.0 enable enable + + false + true + + + + + + + + + + + + + + + + + From a5822a241afee46237e03d0775eea3eff8624f3a Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 15:52:03 +0100 Subject: [PATCH 03/33] Added tests for id utils --- .../IdUtilsTests.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs new file mode 100644 index 00000000..cf6c3f89 --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs @@ -0,0 +1,64 @@ +using PinguApps.Appwrite.Shared.Utils; + +namespace PinguApps.Appwrite.Shared.Tests; +public class IdUtilsTests +{ + [Fact] + public void GetHexTimestamp_Returns_ValidHexFormat() + { + // Act + var hexTimestamp = IdUtils.GetHexTimestamp(); + + // Assert + Assert.Matches("^[a-fA-F0-9]+$", hexTimestamp); + } + + [Fact] + public void GetHexTimestamp_Returns_ExpectedLength() + { + // Act + var hexTimestamp = IdUtils.GetHexTimestamp(); + + // Assert + // Assuming the length is the hex representation of seconds (at least 5 chars) plus 5 chars of milliseconds + Assert.True(hexTimestamp.Length >= 10); + } + + [Theory] + [InlineData(5)] + [InlineData(7)] + [InlineData(10)] + public void GenerateUniqueId_WithPadding_Returns_CorrectLength(int padding) + { + // Act + var uniqueId = IdUtils.GenerateUniqueId(padding); + + // Assert + // Length of the base ID plus the padding + var expectedLength = IdUtils.GetHexTimestamp().Length + padding; + Assert.Equal(expectedLength, uniqueId.Length); + } + + [Fact] + public void GenerateUniqueId_WithoutPadding_Returns_DefaultLength() + { + // Act + var uniqueId = IdUtils.GenerateUniqueId(); + + // Assert + // Default padding is 7 + var expectedLength = IdUtils.GetHexTimestamp().Length + 7; + Assert.Equal(expectedLength, uniqueId.Length); + } + + [Fact] + public void GenerateUniqueId_Returns_UniqueValues() + { + // Act + var id1 = IdUtils.GenerateUniqueId(); + var id2 = IdUtils.GenerateUniqueId(); + + // Assert + Assert.NotEqual(id1, id2); + } +} From fa85a9f8b6d61848b320c0fcebf1628b073bebab Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 16:17:42 +0100 Subject: [PATCH 04/33] Added header handler tests --- Directory.Build.targets | 22 ++++++++++ .../HeaderHandlerTests.cs | 44 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 Directory.Build.targets create mode 100644 tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 00000000..331cc769 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,22 @@ + + + + + + + + + + + <_Parameter1>%(InternalsVisibleTo.Identity) + + + + + + + <_Parameter1>$(AssemblyName)%(InternalsVisibleToSuffix.Identity) + + + + diff --git a/tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs b/tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs new file mode 100644 index 00000000..dba8dd63 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs @@ -0,0 +1,44 @@ +using Moq; +using Moq.Protected; +using PinguApps.Appwrite.Server.Handlers; +using PinguApps.Appwrite.Shared.Tests; + +namespace PinguApps.Appwrite.Server.Tests; +public class HeaderHandlerTests +{ + [Fact] + public async Task SendAsync_AddsRequiredHeaders() + { + // Arrange + var mockInnerHandler = new Mock(); + mockInnerHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny() + ) + .ReturnsAsync(new HttpResponseMessage()) + .Verifiable(); + + var headerHandler = new HeaderHandler(Constants.ProjectId, Constants.ApiKey) + { + InnerHandler = mockInnerHandler.Object + }; + var httpClient = new HttpClient(headerHandler); + + // Act + await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://test.com")); + + // Assert + mockInnerHandler.Protected().Verify( + "SendAsync", + Times.Once(), + ItExpr.Is(req => + req.Headers.Contains("x-appwrite-project") && + req.Headers.GetValues("x-appwrite-project").Contains(Constants.ProjectId) && + req.Headers.Contains("x-appwrite-key") && + req.Headers.GetValues("x-appwrite-key").Contains(Constants.ApiKey)), + ItExpr.IsAny() + ); + } +} From 517f6fa6bfde8418a3091ebf4d863def30da05b1 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 17:40:34 +0100 Subject: [PATCH 05/33] Added Response Utils Tests to Server proj --- .../Utils/ResponseUtils.cs | 2 +- .../ResponseUtilsTests.cs | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs diff --git a/src/PinguApps.Appwrite.Server/Utils/ResponseUtils.cs b/src/PinguApps.Appwrite.Server/Utils/ResponseUtils.cs index 727a0015..a31c654a 100644 --- a/src/PinguApps.Appwrite.Server/Utils/ResponseUtils.cs +++ b/src/PinguApps.Appwrite.Server/Utils/ResponseUtils.cs @@ -18,7 +18,7 @@ internal static AppwriteResult GetApiResponse(this IApiResponse result) return new AppwriteResult(result.Content); } - if (result.Error?.Content is null) + if (result.Error?.Content is null || string.IsNullOrEmpty(result.Error.Content)) { throw new Exception("Unknown error encountered."); } diff --git a/tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs b/tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs new file mode 100644 index 00000000..57165c31 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs @@ -0,0 +1,80 @@ +using System.Net; +using Moq; +using PinguApps.Appwrite.Server.Utils; +using PinguApps.Appwrite.Shared.Tests; +using Refit; + +namespace PinguApps.Appwrite.Server.Tests; +public class ResponseUtilsTests +{ + [Fact] + public void GetApiResponse_Success_ReturnsContent() + { + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(true); + mockApiResponse.SetupGet(r => r.Content).Returns("Success"); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.True(result.Success); + Assert.Equal("Success", result.Result); + } + + [Fact] + public void GetApiResponse_SuccessButNullContent_ReturnsInternalError() + { + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(true); + mockApiResponse.SetupGet(r => r.Content).Returns((string?)null); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.False(result.Success); + Assert.True(result.Result.IsT2); + } + + [Fact] + public async Task GetApiResponse_Failure_ReturnsError() + { + var response = new HttpResponseMessage(HttpStatusCode.InternalServerError) + { + Content = new StringContent(Constants.AppwriteError) + }; + var exception = await ApiException.Create(new HttpRequestMessage(), HttpMethod.Get, response, new RefitSettings()); + + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(false); + mockApiResponse.SetupGet(x => x.Error).Returns(exception); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.False(result.Success); + Assert.True(result.IsAppwriteError); + Assert.True(result.Result.IsT1); + } + + [Fact] + public async Task GetApiResponse_FailureButNullErrorContent_ThrowsException() + { + var exception = await ApiException.Create(new HttpRequestMessage(), HttpMethod.Get, new HttpResponseMessage(HttpStatusCode.InternalServerError), new RefitSettings()); + + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(false); + mockApiResponse.SetupGet(x => x.Error).Returns(exception); + + Assert.Throws(() => mockApiResponse.Object.GetApiResponse()); + } + + [Fact] + public void GetExceptionResponse_ReturnsInternalError() + { + var exception = new Exception("Test exception"); + + var result = exception.GetExceptionResponse(); + + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.True(result.Result.IsT2); + Assert.Equal("Test exception", result.Result.AsT2.Message); + } +} From 6677416f60b7dc5f24156a9e580841064f22992b Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 17:44:07 +0100 Subject: [PATCH 06/33] Added Service Collection Extensions tests to server proj --- .../ServiceCollectionExtensionsTests.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Server.Tests/ServiceCollectionExtensionsTests.cs diff --git a/tests/PinguApps.Appwrite.Server.Tests/ServiceCollectionExtensionsTests.cs b/tests/PinguApps.Appwrite.Server.Tests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000..e578c769 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Server.Handlers; +using PinguApps.Appwrite.Server.Internals; +using PinguApps.Appwrite.Server.Servers; +using PinguApps.Appwrite.Shared.Tests; + +namespace PinguApps.Appwrite.Server.Tests; +public class ServiceCollectionExtensionsTests +{ + [Fact] + public void AddAppwriteServer_RegistersExpectedServices() + { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddAppwriteServer(Constants.ProjectId, Constants.ApiKey, Constants.Endpoint); + + // Assert + var provider = services.BuildServiceProvider(); + + // Assert HeaderHandler is registered + var headerHandler = provider.GetService(); + Assert.NotNull(headerHandler); + + // Assert IAccountApi is registered and configured + var accountApi = provider.GetService(); + Assert.NotNull(accountApi); + + // Assert services are registered + Assert.NotNull(provider.GetService()); + Assert.NotNull(provider.GetService()); + } + + // Additional tests can be added to verify different configurations or overloads of AddAppwriteServer +} From c0aae9b8f239916340b7c35c382b3df9d4b80ff4 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 22:55:21 +0100 Subject: [PATCH 07/33] Added AppwriteServer tests --- .../AppwriteServerTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs diff --git a/tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs b/tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs new file mode 100644 index 00000000..8f0f263a --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs @@ -0,0 +1,17 @@ +using Moq; +using PinguApps.Appwrite.Server.Servers; + +namespace PinguApps.Appwrite.Server.Tests; +public class AppwriteServerTests +{ + [Fact] + public void Constructor_AssignsAccountServerCorrectly() + { + // Arrange + var mockAccountServer = new Mock(); + // Act + var appwriteServer = new AppwriteServer(mockAccountServer.Object); + // Assert + Assert.Equal(mockAccountServer.Object, appwriteServer.Account); + } +} From fa19b43b15bd108c4b9bcb13ea0305a4fa6d3c45 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sat, 6 Jul 2024 22:55:30 +0100 Subject: [PATCH 08/33] Moved account tests into an API folder --- tests/PinguApps.Appwrite.Server.Tests/{ => Api}/AccountTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/PinguApps.Appwrite.Server.Tests/{ => Api}/AccountTests.cs (98%) diff --git a/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs similarity index 98% rename from tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs index 241436d0..a1964c56 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs @@ -6,7 +6,7 @@ using Refit; using RichardSzalay.MockHttp; -namespace PinguApps.Appwrite.Server.Tests; +namespace PinguApps.Appwrite.Server.Tests.Api; public class AccountTests { private readonly MockHttpMessageHandler _mockHttp; From 033cec846d1a47137213c8b669b539ac79a6f9e0 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:18 +0100 Subject: [PATCH 09/33] Create IdUtilsTests.cs --- .../Utils/IdUtilsTests.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/Utils/IdUtilsTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/Utils/IdUtilsTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/Utils/IdUtilsTests.cs new file mode 100644 index 00000000..687e3be4 --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/Utils/IdUtilsTests.cs @@ -0,0 +1,64 @@ +using PinguApps.Appwrite.Shared.Utils; + +namespace PinguApps.Appwrite.Shared.Tests.Utils; +public class IdUtilsTests +{ + [Fact] + public void GetHexTimestamp_Returns_ValidHexFormat() + { + // Act + var hexTimestamp = IdUtils.GetHexTimestamp(); + + // Assert + Assert.Matches("^[a-fA-F0-9]+$", hexTimestamp); + } + + [Fact] + public void GetHexTimestamp_Returns_ExpectedLength() + { + // Act + var hexTimestamp = IdUtils.GetHexTimestamp(); + + // Assert + // Assuming the length is the hex representation of seconds (at least 5 chars) plus 5 chars of milliseconds + Assert.True(hexTimestamp.Length >= 10); + } + + [Theory] + [InlineData(5)] + [InlineData(7)] + [InlineData(10)] + public void GenerateUniqueId_WithPadding_Returns_CorrectLength(int padding) + { + // Act + var uniqueId = IdUtils.GenerateUniqueId(padding); + + // Assert + // Length of the base ID plus the padding + var expectedLength = IdUtils.GetHexTimestamp().Length + padding; + Assert.Equal(expectedLength, uniqueId.Length); + } + + [Fact] + public void GenerateUniqueId_WithoutPadding_Returns_DefaultLength() + { + // Act + var uniqueId = IdUtils.GenerateUniqueId(); + + // Assert + // Default padding is 7 + var expectedLength = IdUtils.GetHexTimestamp().Length + 7; + Assert.Equal(expectedLength, uniqueId.Length); + } + + [Fact] + public void GenerateUniqueId_Returns_UniqueValues() + { + // Act + var id1 = IdUtils.GenerateUniqueId(); + var id2 = IdUtils.GenerateUniqueId(); + + // Assert + Assert.NotEqual(id1, id2); + } +} From 45d76bff9819aad0dbbda33583098a7a5c5a41c6 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:29 +0100 Subject: [PATCH 10/33] Create InternalErrorTests.cs --- .../InternalErrorTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/InternalErrorTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/InternalErrorTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/InternalErrorTests.cs new file mode 100644 index 00000000..0fe7d0fa --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/InternalErrorTests.cs @@ -0,0 +1,16 @@ +namespace PinguApps.Appwrite.Shared.Tests; +public class InternalErrorTests +{ + [Fact] + public void Constructor_AssignsMessage() + { + // Arrange + var expectedMessage = "An error occurred"; + + // Act + var internalError = new InternalError(expectedMessage); + + // Assert + Assert.Equal(expectedMessage, internalError.Message); + } +} From 42057353bd966abafdf17eb0a347a5ac44d04bca Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:33 +0100 Subject: [PATCH 11/33] Delete IdUtilsTests.cs --- .../IdUtilsTests.cs | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs deleted file mode 100644 index cf6c3f89..00000000 --- a/tests/PinguApps.Appwrite.Shared.Tests/IdUtilsTests.cs +++ /dev/null @@ -1,64 +0,0 @@ -using PinguApps.Appwrite.Shared.Utils; - -namespace PinguApps.Appwrite.Shared.Tests; -public class IdUtilsTests -{ - [Fact] - public void GetHexTimestamp_Returns_ValidHexFormat() - { - // Act - var hexTimestamp = IdUtils.GetHexTimestamp(); - - // Assert - Assert.Matches("^[a-fA-F0-9]+$", hexTimestamp); - } - - [Fact] - public void GetHexTimestamp_Returns_ExpectedLength() - { - // Act - var hexTimestamp = IdUtils.GetHexTimestamp(); - - // Assert - // Assuming the length is the hex representation of seconds (at least 5 chars) plus 5 chars of milliseconds - Assert.True(hexTimestamp.Length >= 10); - } - - [Theory] - [InlineData(5)] - [InlineData(7)] - [InlineData(10)] - public void GenerateUniqueId_WithPadding_Returns_CorrectLength(int padding) - { - // Act - var uniqueId = IdUtils.GenerateUniqueId(padding); - - // Assert - // Length of the base ID plus the padding - var expectedLength = IdUtils.GetHexTimestamp().Length + padding; - Assert.Equal(expectedLength, uniqueId.Length); - } - - [Fact] - public void GenerateUniqueId_WithoutPadding_Returns_DefaultLength() - { - // Act - var uniqueId = IdUtils.GenerateUniqueId(); - - // Assert - // Default padding is 7 - var expectedLength = IdUtils.GetHexTimestamp().Length + 7; - Assert.Equal(expectedLength, uniqueId.Length); - } - - [Fact] - public void GenerateUniqueId_Returns_UniqueValues() - { - // Act - var id1 = IdUtils.GenerateUniqueId(); - var id2 = IdUtils.GenerateUniqueId(); - - // Assert - Assert.NotEqual(id1, id2); - } -} From bb94e5317cc90f43ac755822bf51906db0f05a24 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:48 +0100 Subject: [PATCH 12/33] Added prefs to user constant --- tests/PinguApps.Appwrite.Shared.Tests/Constants.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs b/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs index 80ae2e24..1fc5715f 100644 --- a/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs +++ b/tests/PinguApps.Appwrite.Shared.Tests/Constants.cs @@ -54,7 +54,9 @@ public static class Constants "emailVerification": true, "phoneVerification": true, "mfa": true, - "prefs": {}, + "prefs": { + "pref1": "val1" + }, "targets": [ { "$id": "259125845563242502", From 70b6447ed1a037cea3b4cd71f156e1a987a280c7 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:52 +0100 Subject: [PATCH 13/33] Create AppwriteErrorTests.cs --- .../AppwriteErrorTests.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/AppwriteErrorTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/AppwriteErrorTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/AppwriteErrorTests.cs new file mode 100644 index 00000000..0747dd81 --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/AppwriteErrorTests.cs @@ -0,0 +1,22 @@ +namespace PinguApps.Appwrite.Shared.Tests; +public class AppwriteErrorTests +{ + [Fact] + public void AppwriteError_Constructor_ShouldSetPropertiesCorrectly() + { + // Arrange + var expectedMessage = "An error occurred"; + var expectedCode = 400; + var expectedType = "BadRequest"; + var expectedVersion = "v1"; + + // Act + var error = new AppwriteError(expectedMessage, expectedCode, expectedType, expectedVersion); + + // Assert + Assert.Equal(expectedMessage, error.Message); + Assert.Equal(expectedCode, error.Code); + Assert.Equal(expectedType, error.Type); + Assert.Equal(expectedVersion, error.Version); + } +} From 6863cc21a09eacec67f6bcf08de7b288da2a31e9 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:09:59 +0100 Subject: [PATCH 14/33] Create HashOptions.cs --- src/PinguApps.Appwrite.Common/Responses/HashOptions.cs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/PinguApps.Appwrite.Common/Responses/HashOptions.cs diff --git a/src/PinguApps.Appwrite.Common/Responses/HashOptions.cs b/src/PinguApps.Appwrite.Common/Responses/HashOptions.cs new file mode 100644 index 00000000..9b68903f --- /dev/null +++ b/src/PinguApps.Appwrite.Common/Responses/HashOptions.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace PinguApps.Appwrite.Shared.Responses; +public record HashOptions( + [property: JsonPropertyName("type")] string Type, + [property: JsonPropertyName("memoryCost")] long MemoryCost, + [property: JsonPropertyName("timeCost")] int TimeCost, + [property: JsonPropertyName("threads")] int Threads +); From 9a7b3a2aa6093c1371543ca19c87ad677a92511d Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:10:11 +0100 Subject: [PATCH 15/33] added admin stuff to user obj --- src/PinguApps.Appwrite.Common/Responses/User.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PinguApps.Appwrite.Common/Responses/User.cs b/src/PinguApps.Appwrite.Common/Responses/User.cs index 882cbe44..1d1affee 100644 --- a/src/PinguApps.Appwrite.Common/Responses/User.cs +++ b/src/PinguApps.Appwrite.Common/Responses/User.cs @@ -8,6 +8,9 @@ public record User( [property: JsonPropertyName("$createdAt")] DateTime CreatedAt, [property: JsonPropertyName("$updatedAt")] DateTime UpdatedAt, [property: JsonPropertyName("name")] string Name, + [property: JsonPropertyName("password")] string? Password, + [property: JsonPropertyName("hash")] string? Hash, + [property: JsonPropertyName("hashOptions")] HashOptions? HashOptions, [property: JsonPropertyName("registration")] DateTime Registration, [property: JsonPropertyName("status")] bool Status, [property: JsonPropertyName("labels")] IReadOnlyList Labels, From 506c2699383007fc845ab6129be8469df67bd2ec Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:10:15 +0100 Subject: [PATCH 16/33] Create UserTests.cs --- .../Responses/UserTests.cs | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/Responses/UserTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/Responses/UserTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/Responses/UserTests.cs new file mode 100644 index 00000000..f5f9845c --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/Responses/UserTests.cs @@ -0,0 +1,98 @@ +using System.Text.Json; +using PinguApps.Appwrite.Shared.Enums; +using PinguApps.Appwrite.Shared.Responses; + +namespace PinguApps.Appwrite.Shared.Tests.Responses; +public class UserTests +{ + [Fact] + public void User_Constructor_AssignsPropertiesCorrectly() + { + // Arrange + var id = "testId"; + var createdAt = DateTime.UtcNow; + var updatedAt = DateTime.UtcNow; + var name = "Test User"; + var password = ""; + var hash = ""; + var hashOptions = new HashOptions("type", 6, 5, 4); + var registration = DateTime.UtcNow; + var status = true; + var labels = new List { "label1", "label2" }; + var passwordUpdate = DateTime.UtcNow; + var email = "test@example.com"; + var phone = "1234567890"; + var emailVerification = true; + var phoneVerification = false; + var mfa = true; + var prefs = new Dictionary { { "theme", "dark" } }; + var targets = new List { new Target("259125845563242502", DateTime.UtcNow, DateTime.UtcNow, "Aegon apple token", "259125845563242502", "259125845563242502", TargetProviderType.Email, "token") }; + var accessedAt = DateTime.UtcNow; + + // Act + var user = new User(id, createdAt, updatedAt, name, password, hash, hashOptions, registration, status, labels, passwordUpdate, + email, phone, emailVerification, phoneVerification, mfa, prefs, targets, accessedAt); + + // Assert + Assert.Equal(id, user.Id); + Assert.Equal(createdAt, user.CreatedAt); + Assert.Equal(updatedAt, user.UpdatedAt); + Assert.Equal(name, user.Name); + Assert.Equal(registration, user.Registration); + Assert.Equal(status, user.Status); + Assert.Equal(labels, user.Labels); + Assert.Equal(passwordUpdate, user.PasswordUpdate); + Assert.Equal(email, user.Email); + Assert.Equal(phone, user.Phone); + Assert.Equal(emailVerification, user.EmailVerification); + Assert.Equal(phoneVerification, user.PhoneVerification); + Assert.Equal(mfa, user.Mfa); + Assert.Equal(prefs, user.Prefs); + Assert.Equal(targets, user.Targets); + Assert.Equal(accessedAt, user.AccessedAt); + } + + [Fact] + public void User_CanBeDeserialized_FromJson() + { + // Act + var user = JsonSerializer.Deserialize(Constants.UserResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + // Assert + Assert.NotNull(user); + Assert.Equal("5e5ea5c16897e", user.Id); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.CreatedAt.ToUniversalTime()); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.UpdatedAt.ToUniversalTime()); + Assert.Equal("John Doe", user.Name); + Assert.NotNull(user.Password); + Assert.Equal("$argon2id$v=19$m=2048,t=4,p=3$aUZjLnliVWRINmFNTWMudg$5S+x+7uA31xFnrHFT47yFwcJeaP0w92L/4LdgrVRXxE", user.Password); + Assert.NotNull(user.Hash); + Assert.Equal("argon2", user.Hash); + Assert.NotNull(user.HashOptions); + Assert.Equal("argon2", user.HashOptions.Type); + Assert.Equal(65536, user.HashOptions.MemoryCost); + Assert.Equal(4, user.HashOptions.TimeCost); + Assert.Equal(3, user.HashOptions.Threads); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.Registration.ToUniversalTime()); + Assert.True(user.Status); + Assert.Contains("vip", user.Labels); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.PasswordUpdate.ToUniversalTime()); + Assert.Equal("john@appwrite.io", user.Email); + Assert.Equal("+4930901820", user.Phone); + Assert.True(user.EmailVerification); + Assert.True(user.PhoneVerification); + Assert.True(user.Mfa); + Assert.Contains("pref1", user.Prefs); + Assert.Equal("val1", user.Prefs["pref1"]); + Assert.Single(user.Targets); + Assert.Equal("259125845563242502", user.Targets[0].Id); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.Targets[0].CreatedAt.ToUniversalTime()); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.Targets[0].UpdatedAt.ToUniversalTime()); + Assert.Equal("Aegon apple token", user.Targets[0].Name); + Assert.Equal("259125845563242502", user.Targets[0].UserId); + Assert.Equal("259125845563242502", user.Targets[0].ProviderId); + Assert.Equal(TargetProviderType.Email, user.Targets[0].ProviderType); + Assert.Equal("token", user.Targets[0].Identifier); + Assert.Equal(DateTime.Parse("2020-10-15T06:38:00.000+00:00").ToUniversalTime(), user.AccessedAt.ToUniversalTime()); + } +} From c54614193c1520f6966af34d305685ff2026f045 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:36:22 +0100 Subject: [PATCH 17/33] Added coverage reports to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 144ef7ca..d934889f 100644 --- a/.gitignore +++ b/.gitignore @@ -398,3 +398,4 @@ FodyWeavers.xsd *.sln.iml **/*appsettings*.json +**/coverage-report/** From 1a939fc3c8799702460b234df462a377c1d418ee Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:38:00 +0100 Subject: [PATCH 18/33] added coverlet to shared tests --- .../PinguApps.Appwrite.Shared.Tests.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj b/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj index 91503aea..d2fa0703 100644 --- a/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj +++ b/tests/PinguApps.Appwrite.Shared.Tests/PinguApps.Appwrite.Shared.Tests.csproj @@ -11,6 +11,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From e090bb6410c64c3d4aacae85d247aef024ffb075 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:44:16 +0100 Subject: [PATCH 19/33] Added powershell script to help run tests with ease --- tests/PinguApps.Appwrite.Shared.Tests/test.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/test.ps1 diff --git a/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 new file mode 100644 index 00000000..278d0e06 --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 @@ -0,0 +1,13 @@ +# Check if the dotnet-reportgenerator-globaltool is installed +$toolInstalled = dotnet tool list -g | Select-String -Pattern "dotnet-reportgenerator-globaltool" + +if (-not $toolInstalled) { + # Install the dotnet-reportgenerator-globaltool globally + dotnet tool install -g dotnet-reportgenerator-globaltool +} + +# Generate the report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report + +# Open the generated report in the default browser +Start-Process "coverage-report/index.html" From cd5a45872a28fc38c10dc741f4524a9d4392c888 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:52:10 +0100 Subject: [PATCH 20/33] Fixed test ps --- tests/PinguApps.Appwrite.Shared.Tests/test.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 index 278d0e06..11e4d51d 100644 --- a/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 +++ b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 @@ -1,3 +1,5 @@ +dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover + # Check if the dotnet-reportgenerator-globaltool is installed $toolInstalled = dotnet tool list -g | Select-String -Pattern "dotnet-reportgenerator-globaltool" From 8a9c2288e2ab841a3c8bb164f07c97e537df800d Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:52:14 +0100 Subject: [PATCH 21/33] Create CreateAccountRequestTests.cs --- .../Requests/CreateAccountRequestTests.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Shared.Tests/Requests/CreateAccountRequestTests.cs diff --git a/tests/PinguApps.Appwrite.Shared.Tests/Requests/CreateAccountRequestTests.cs b/tests/PinguApps.Appwrite.Shared.Tests/Requests/CreateAccountRequestTests.cs new file mode 100644 index 00000000..9f92b18f --- /dev/null +++ b/tests/PinguApps.Appwrite.Shared.Tests/Requests/CreateAccountRequestTests.cs @@ -0,0 +1,38 @@ +using PinguApps.Appwrite.Shared.Requests; + +namespace PinguApps.Appwrite.Shared.Tests.Requests; +public class CreateAccountRequestTests +{ + [Fact] + public void Constructor_InitializesWithExpectedValues() + { + // Arrange & Act + var request = new CreateAccountRequest(); + + // Assert + Assert.NotNull(request.UserId); + Assert.NotEmpty(request.UserId); + Assert.Equal(string.Empty, request.Email); + Assert.Equal(string.Empty, request.Password); + Assert.Null(request.Name); + } + + [Theory] + [InlineData("test@example.com", "password123", "Test User")] + [InlineData("another@example.com", "diffPassword", null)] + public void Properties_CanBeSet(string email, string password, string? name) + { + // Arrange + var request = new CreateAccountRequest(); + + // Act + request.Email = email; + request.Password = password; + request.Name = name; + + // Assert + Assert.Equal(email, request.Email); + Assert.Equal(password, request.Password); + Assert.Equal(name, request.Name); + } +} From 8e64165cc004e88401850853eb93d2e699661024 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:53:45 +0100 Subject: [PATCH 22/33] added coverlet and test script to other test projects --- .../PinguApps.Appwrite.Client.Tests.csproj | 4 ++++ tests/PinguApps.Appwrite.Client.Tests/test.ps1 | 15 +++++++++++++++ .../PinguApps.Appwrite.Server.Tests.csproj | 4 ++++ tests/PinguApps.Appwrite.Server.Tests/test.ps1 | 15 +++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/test.ps1 create mode 100644 tests/PinguApps.Appwrite.Server.Tests/test.ps1 diff --git a/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj b/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj index 67240f04..e23ead07 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj +++ b/tests/PinguApps.Appwrite.Client.Tests/PinguApps.Appwrite.Client.Tests.csproj @@ -11,6 +11,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/PinguApps.Appwrite.Client.Tests/test.ps1 b/tests/PinguApps.Appwrite.Client.Tests/test.ps1 new file mode 100644 index 00000000..11e4d51d --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/test.ps1 @@ -0,0 +1,15 @@ +dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover + +# Check if the dotnet-reportgenerator-globaltool is installed +$toolInstalled = dotnet tool list -g | Select-String -Pattern "dotnet-reportgenerator-globaltool" + +if (-not $toolInstalled) { + # Install the dotnet-reportgenerator-globaltool globally + dotnet tool install -g dotnet-reportgenerator-globaltool +} + +# Generate the report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report + +# Open the generated report in the default browser +Start-Process "coverage-report/index.html" diff --git a/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj b/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj index 79aceb35..21e09583 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj +++ b/tests/PinguApps.Appwrite.Server.Tests/PinguApps.Appwrite.Server.Tests.csproj @@ -11,6 +11,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/PinguApps.Appwrite.Server.Tests/test.ps1 b/tests/PinguApps.Appwrite.Server.Tests/test.ps1 new file mode 100644 index 00000000..11e4d51d --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/test.ps1 @@ -0,0 +1,15 @@ +dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover + +# Check if the dotnet-reportgenerator-globaltool is installed +$toolInstalled = dotnet tool list -g | Select-String -Pattern "dotnet-reportgenerator-globaltool" + +if (-not $toolInstalled) { + # Install the dotnet-reportgenerator-globaltool globally + dotnet tool install -g dotnet-reportgenerator-globaltool +} + +# Generate the report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report + +# Open the generated report in the default browser +Start-Process "coverage-report/index.html" From 3e6c32fc36b351495cf59eef80f4be4ef6efbf21 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 00:59:52 +0100 Subject: [PATCH 23/33] Moved some stuff about in server test proj --- .../{ => Handlers}/HeaderHandlerTests.cs | 2 +- .../{Api => Servers}/AccountTests.cs | 2 +- .../{ => Servers}/AppwriteServerTests.cs | 2 +- .../{ => Utils}/ResponseUtilsTests.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename tests/PinguApps.Appwrite.Server.Tests/{ => Handlers}/HeaderHandlerTests.cs (96%) rename tests/PinguApps.Appwrite.Server.Tests/{Api => Servers}/AccountTests.cs (98%) rename tests/PinguApps.Appwrite.Server.Tests/{ => Servers}/AppwriteServerTests.cs (89%) rename tests/PinguApps.Appwrite.Server.Tests/{ => Utils}/ResponseUtilsTests.cs (98%) diff --git a/tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Handlers/HeaderHandlerTests.cs similarity index 96% rename from tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Handlers/HeaderHandlerTests.cs index dba8dd63..9be219e4 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/HeaderHandlerTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Handlers/HeaderHandlerTests.cs @@ -3,7 +3,7 @@ using PinguApps.Appwrite.Server.Handlers; using PinguApps.Appwrite.Shared.Tests; -namespace PinguApps.Appwrite.Server.Tests; +namespace PinguApps.Appwrite.Server.Tests.Handlers; public class HeaderHandlerTests { [Fact] diff --git a/tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs similarity index 98% rename from tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs index a1964c56..c06ac961 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/Api/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs @@ -6,7 +6,7 @@ using Refit; using RichardSzalay.MockHttp; -namespace PinguApps.Appwrite.Server.Tests.Api; +namespace PinguApps.Appwrite.Server.Tests.Servers; public class AccountTests { private readonly MockHttpMessageHandler _mockHttp; diff --git a/tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/AppwriteServerTests.cs similarity index 89% rename from tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Servers/AppwriteServerTests.cs index 8f0f263a..05bbba79 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/AppwriteServerTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/AppwriteServerTests.cs @@ -1,7 +1,7 @@ using Moq; using PinguApps.Appwrite.Server.Servers; -namespace PinguApps.Appwrite.Server.Tests; +namespace PinguApps.Appwrite.Server.Tests.Servers; public class AppwriteServerTests { [Fact] diff --git a/tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Utils/ResponseUtilsTests.cs similarity index 98% rename from tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Utils/ResponseUtilsTests.cs index 57165c31..5ddd5ad2 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/ResponseUtilsTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Utils/ResponseUtilsTests.cs @@ -4,7 +4,7 @@ using PinguApps.Appwrite.Shared.Tests; using Refit; -namespace PinguApps.Appwrite.Server.Tests; +namespace PinguApps.Appwrite.Server.Tests.Utils; public class ResponseUtilsTests { [Fact] From 9d98901d1e37dff01ca52d7caebb1f2c68034a0d Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:11:36 +0100 Subject: [PATCH 24/33] added account tests exception handling --- .../Servers/AccountTests.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs index c06ac961..7bee7532 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs @@ -73,6 +73,31 @@ public async Task Create_ShouldHandleException_WhenApiCallFails() Assert.True(result.IsError); Assert.True(result.IsAppwriteError); } + + [Fact] + public async Task Create_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new CreateAccountRequest() + { + Email = "email@example.com", + Password = "password", + Name = "name" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") + .ExpectedHeaders() + .WithJsonContent(request) + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteServer.Account.Create(request); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } } public static class AccountTestsExtensions From 18696880083bf894b9ee0fc3a66e3dfa9042e237 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:33:57 +0100 Subject: [PATCH 25/33] Modified test scripts to only care about the assembly that they are meant to test --- tests/PinguApps.Appwrite.Client.Tests/test.ps1 | 2 +- tests/PinguApps.Appwrite.Server.Tests/test.ps1 | 2 +- tests/PinguApps.Appwrite.Shared.Tests/test.ps1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PinguApps.Appwrite.Client.Tests/test.ps1 b/tests/PinguApps.Appwrite.Client.Tests/test.ps1 index 11e4d51d..1e7a9698 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/test.ps1 +++ b/tests/PinguApps.Appwrite.Client.Tests/test.ps1 @@ -9,7 +9,7 @@ if (-not $toolInstalled) { } # Generate the report -reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report -assemblyfilters:+PinguApps.Appwrite.Client # Open the generated report in the default browser Start-Process "coverage-report/index.html" diff --git a/tests/PinguApps.Appwrite.Server.Tests/test.ps1 b/tests/PinguApps.Appwrite.Server.Tests/test.ps1 index 11e4d51d..12457080 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/test.ps1 +++ b/tests/PinguApps.Appwrite.Server.Tests/test.ps1 @@ -9,7 +9,7 @@ if (-not $toolInstalled) { } # Generate the report -reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report -assemblyfilters:+PinguApps.Appwrite.Server # Open the generated report in the default browser Start-Process "coverage-report/index.html" diff --git a/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 index 11e4d51d..57b4af39 100644 --- a/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 +++ b/tests/PinguApps.Appwrite.Shared.Tests/test.ps1 @@ -9,7 +9,7 @@ if (-not $toolInstalled) { } # Generate the report -reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report +reportgenerator -reports:coverage.opencover.xml -targetdir:coverage-report -assemblyfilters:+PinguApps.Appwrite.Shared # Open the generated report in the default browser Start-Process "coverage-report/index.html" From 467be678d4e07a8b299f63304123e9105de99a3f Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:37:02 +0100 Subject: [PATCH 26/33] Moved client account tests into folder --- .../{ => Clients}/AccountTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/PinguApps.Appwrite.Client.Tests/{ => Clients}/AccountTests.cs (98%) diff --git a/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs similarity index 98% rename from tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs rename to tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs index c314f8ed..ffeb2775 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs @@ -5,7 +5,7 @@ using Refit; using RichardSzalay.MockHttp; -namespace PinguApps.Appwrite.Client.Tests; +namespace PinguApps.Appwrite.Client.Tests.Clients; public class AccountTests { private readonly MockHttpMessageHandler _mockHttp; From 22ec938595d99e34773c72374a26ce3adade443f Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:48:18 +0100 Subject: [PATCH 27/33] Split AccountClient into partials --- .../Account/AccountClientTests.Create.cs | 80 +++++++++++ .../Clients/Account/AccountClientTests.Get.cs | 61 ++++++++ .../Clients/Account/AccountClientTests.cs | 51 +++++++ .../Clients/AccountTests.cs | 135 ------------------ 4 files changed, 192 insertions(+), 135 deletions(-) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Create.cs create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Get.cs create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs delete mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Create.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Create.cs new file mode 100644 index 00000000..c8e57e36 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Create.cs @@ -0,0 +1,80 @@ +using System.Net; +using PinguApps.Appwrite.Shared.Requests; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Account; +public partial class AccountClientTests +{ + [Fact] + public async Task Create_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new CreateAccountRequest() + { + Email = "email@example.com", + Password = "password", + Name = "name" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") + .ExpectedHeaders() + .WithJsonContent(request) + .Respond(Constants.AppJson, Constants.UserResponse); + + // Act + var result = await _appwriteClient.Account.Create(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task Create_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new CreateAccountRequest() + { + Email = "email@example.com", + Password = "password", + Name = "name" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") + .ExpectedHeaders() + .WithJsonContent(request) + .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); + + // Act + var result = await _appwriteClient.Account.Create(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task Create_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new CreateAccountRequest() + { + Email = "email@example.com", + Password = "password", + Name = "name" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") + .ExpectedHeaders() + .WithJsonContent(request) + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteClient.Account.Create(request); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +} diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Get.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Get.cs new file mode 100644 index 00000000..ff31f349 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Get.cs @@ -0,0 +1,61 @@ +using System.Net; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Account; +public partial class AccountClientTests +{ + [Fact] + public async Task Get_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + _mockHttp.Expect(HttpMethod.Get, $"{Constants.Endpoint}/account") + .ExpectedHeaders(true) + .Respond(Constants.AppJson, Constants.UserResponse); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.Get(); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task Get_ShouldHandleException_WhenApiCallFails() + { + // Arrange + _mockHttp.Expect(HttpMethod.Get, $"{Constants.Endpoint}/account") + .ExpectedHeaders(true) + .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.Get(); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task Get_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + _mockHttp.Expect(HttpMethod.Get, $"{Constants.Endpoint}/account") + .ExpectedHeaders(true) + .Throw(new HttpRequestException("An error occurred")); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.Get(); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +} diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs new file mode 100644 index 00000000..5b13235b --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs @@ -0,0 +1,51 @@ +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Shared.Tests; +using Refit; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Account; +public partial class AccountClientTests +{ + private readonly MockHttpMessageHandler _mockHttp; + private readonly IAppwriteClient _appwriteClient; + + public AccountClientTests() + { + _mockHttp = new MockHttpMessageHandler(); + var services = new ServiceCollection(); + + services.AddAppwriteClientForServer("PROJECT_ID", Constants.Endpoint, new RefitSettings + { + HttpMessageHandlerFactory = () => _mockHttp + }); + + var serviceProvider = services.BuildServiceProvider(); + + _appwriteClient = serviceProvider.GetRequiredService(); + } +} + +public static class AccountTestsExtensions +{ + public static MockedRequest ExpectedHeaders(this MockedRequest request, bool addSessionHeaders = false) + { + var req = request + .WithHeaders("x-appwrite-project", Constants.ProjectId) + .WithHeaders("x-sdk-name", Constants.SdkName) + .WithHeaders("x-sdk-platform", "client") + .WithHeaders("x-sdk-language", Constants.SdkLanguage) + .WithHeaders("x-sdk-version", Constants.SdkVersion) + .WithHeaders("x-appwrite-response-format", Constants.AppwriteResponseFormat); + + if (addSessionHeaders) + return req.ExpectSessionHeaders(); + + return req; + } + + public static MockedRequest ExpectSessionHeaders(this MockedRequest request) + { + return request + .WithHeaders("x-appwrite-session", Constants.Session); + } +} diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs deleted file mode 100644 index ffeb2775..00000000 --- a/tests/PinguApps.Appwrite.Client.Tests/Clients/AccountTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System.Net; -using Microsoft.Extensions.DependencyInjection; -using PinguApps.Appwrite.Shared.Requests; -using PinguApps.Appwrite.Shared.Tests; -using Refit; -using RichardSzalay.MockHttp; - -namespace PinguApps.Appwrite.Client.Tests.Clients; -public class AccountTests -{ - private readonly MockHttpMessageHandler _mockHttp; - private readonly IAppwriteClient _appwriteClient; - - public AccountTests() - { - _mockHttp = new MockHttpMessageHandler(); - var services = new ServiceCollection(); - - services.AddAppwriteClientForServer("PROJECT_ID", Constants.Endpoint, new RefitSettings - { - HttpMessageHandlerFactory = () => _mockHttp - }); - - var serviceProvider = services.BuildServiceProvider(); - - _appwriteClient = serviceProvider.GetRequiredService(); - } - - [Fact] - public async Task Get_ShouldReturnSuccess_WhenApiCallSucceeds() - { - // Arrange - _mockHttp.Expect(HttpMethod.Get, $"{Constants.Endpoint}/account") - .ExpectedHeaders(true) - .Respond(Constants.AppJson, Constants.UserResponse); - - _appwriteClient.SetSession(Constants.Session); - - // Act - var result = await _appwriteClient.Account.Get(); - - // Assert - Assert.True(result.Success); - } - - [Fact] - public async Task Get_ShouldHandleException_WhenApiCallFails() - { - // Arrange - _mockHttp.Expect(HttpMethod.Get, $"{Constants.Endpoint}/account") - .ExpectedHeaders(true) - .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); - - _appwriteClient.SetSession(Constants.Session); - - // Act - var result = await _appwriteClient.Account.Get(); - - // Assert - Assert.True(result.IsError); - Assert.True(result.IsAppwriteError); - } - - [Fact] - public async Task Create_ShouldReturnSuccess_WhenApiCallSucceeds() - { - // Arrange - var request = new CreateAccountRequest() - { - Email = "email@example.com", - Password = "password", - Name = "name" - }; - - _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") - .ExpectedHeaders() - .WithJsonContent(request) - .Respond(Constants.AppJson, Constants.UserResponse); - - // Act - var result = await _appwriteClient.Account.Create(request); - - // Assert - Assert.True(result.Success); - } - - [Fact] - public async Task Create_ShouldHandleException_WhenApiCallFails() - { - // Arrange - var request = new CreateAccountRequest() - { - Email = "email@example.com", - Password = "password", - Name = "name" - }; - - _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account") - .ExpectedHeaders() - .WithJsonContent(request) - .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); - - // Act - var result = await _appwriteClient.Account.Create(request); - - // Assert - Assert.True(result.IsError); - Assert.True(result.IsAppwriteError); - } -} - -public static class AccountTestsExtensions -{ - public static MockedRequest ExpectedHeaders(this MockedRequest request, bool addSessionHeaders = false) - { - var req = request - .WithHeaders("x-appwrite-project", Constants.ProjectId) - .WithHeaders("x-sdk-name", Constants.SdkName) - .WithHeaders("x-sdk-platform", "client") - .WithHeaders("x-sdk-language", Constants.SdkLanguage) - .WithHeaders("x-sdk-version", Constants.SdkVersion) - .WithHeaders("x-appwrite-response-format", Constants.AppwriteResponseFormat); - - if (addSessionHeaders) - return req.ExpectSessionHeaders(); - - return req; - } - - public static MockedRequest ExpectSessionHeaders(this MockedRequest request) - { - return request - .WithHeaders("x-appwrite-session", Constants.Session); - } -} From 36f8bbcc5a64f7e88a94c0cad09544a584990c32 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:50:40 +0100 Subject: [PATCH 28/33] Split account server into partials --- .../AccountServerTests.Create.cs} | 40 +----------------- .../Servers/Account/AccountServerTests.cs | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+), 38 deletions(-) rename tests/PinguApps.Appwrite.Server.Tests/Servers/{AccountTests.cs => Account/AccountServerTests.Create.cs} (61%) create mode 100644 tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.cs diff --git a/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.Create.cs similarity index 61% rename from tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs rename to tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.Create.cs index 7bee7532..cd78a877 100644 --- a/tests/PinguApps.Appwrite.Server.Tests/Servers/AccountTests.cs +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.Create.cs @@ -1,32 +1,11 @@ using System.Net; -using Microsoft.Extensions.DependencyInjection; -using PinguApps.Appwrite.Server.Servers; using PinguApps.Appwrite.Shared.Requests; using PinguApps.Appwrite.Shared.Tests; -using Refit; using RichardSzalay.MockHttp; -namespace PinguApps.Appwrite.Server.Tests.Servers; -public class AccountTests +namespace PinguApps.Appwrite.Server.Tests.Servers.Account; +public partial class AccountServerTests { - private readonly MockHttpMessageHandler _mockHttp; - private readonly IAppwriteServer _appwriteServer; - - public AccountTests() - { - _mockHttp = new MockHttpMessageHandler(); - var services = new ServiceCollection(); - - services.AddAppwriteServer(Constants.ProjectId, Constants.ApiKey, Constants.Endpoint, new RefitSettings - { - HttpMessageHandlerFactory = () => _mockHttp - }); - - var serviceProvider = services.BuildServiceProvider(); - - _appwriteServer = serviceProvider.GetRequiredService(); - } - [Fact] public async Task Create_ShouldReturnSuccess_WhenApiCallSucceeds() { @@ -99,18 +78,3 @@ public async Task Create_ShouldReturnErrorResponse_WhenExceptionOccurs() Assert.Equal("An error occurred", result.Result.AsT2.Message); } } - -public static class AccountTestsExtensions -{ - public static MockedRequest ExpectedHeaders(this MockedRequest request) - { - return request - .WithHeaders("x-appwrite-project", Constants.ProjectId) - .WithHeaders("x-appwrite-key", Constants.ApiKey) - .WithHeaders("x-sdk-name", Constants.SdkName) - .WithHeaders("x-sdk-platform", "server") - .WithHeaders("x-sdk-language", Constants.SdkLanguage) - .WithHeaders("x-sdk-version", Constants.SdkVersion) - .WithHeaders("x-appwrite-response-format", Constants.AppwriteResponseFormat); - } -} diff --git a/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.cs new file mode 100644 index 00000000..48df8da0 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.cs @@ -0,0 +1,42 @@ +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Server.Servers; +using PinguApps.Appwrite.Shared.Tests; +using Refit; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Server.Tests.Servers.Account; +public partial class AccountServerTests +{ + private readonly MockHttpMessageHandler _mockHttp; + private readonly IAppwriteServer _appwriteServer; + + public AccountServerTests() + { + _mockHttp = new MockHttpMessageHandler(); + var services = new ServiceCollection(); + + services.AddAppwriteServer(Constants.ProjectId, Constants.ApiKey, Constants.Endpoint, new RefitSettings + { + HttpMessageHandlerFactory = () => _mockHttp + }); + + var serviceProvider = services.BuildServiceProvider(); + + _appwriteServer = serviceProvider.GetRequiredService(); + } +} + +public static class AccountTestsExtensions +{ + public static MockedRequest ExpectedHeaders(this MockedRequest request) + { + return request + .WithHeaders("x-appwrite-project", Constants.ProjectId) + .WithHeaders("x-appwrite-key", Constants.ApiKey) + .WithHeaders("x-sdk-name", Constants.SdkName) + .WithHeaders("x-sdk-platform", "server") + .WithHeaders("x-sdk-language", Constants.SdkLanguage) + .WithHeaders("x-sdk-version", Constants.SdkVersion) + .WithHeaders("x-appwrite-response-format", Constants.AppwriteResponseFormat); + } +} From 6ab332e3106f994b22e3f42c3d389a20ebffe59d Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 01:56:19 +0100 Subject: [PATCH 29/33] Create AppwriteClientTests.cs --- .../Clients/AppwriteClientTests.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs new file mode 100644 index 00000000..a9b0f41e --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs @@ -0,0 +1,64 @@ +using Moq; +using PinguApps.Appwrite.Client.Clients; +using PinguApps.Appwrite.Shared.Tests; + +namespace PinguApps.Appwrite.Client.Tests.Clients; +public class AppwriteClientTests +{ + [Fact] + public void Constructor_SetsAccountClient() + { + // Arrange + var mockAccountClient = new Mock(); + + // Act + var appwriteClient = new AppwriteClient(mockAccountClient.Object); + + // Assert + Assert.Equal(mockAccountClient.Object, appwriteClient.Account); + } + + [Fact] + public void Session_InitiallyNull_ReturnsNull() + { + // Arrange + var mockAccountClient = new Mock(); + var appwriteClient = new AppwriteClient(mockAccountClient.Object); + + // Act + var session = appwriteClient.Session; + + // Assert + Assert.Null(session); + } + + [Fact] + public void SetSession_UpdatesSession() + { + // Arrange + var mockAccountClient = new Mock(); + mockAccountClient.As(); + var appwriteClient = new AppwriteClient(mockAccountClient.Object); + + // Act + appwriteClient.SetSession(Constants.Session); + + // Assert + Assert.Equal(Constants.Session, appwriteClient.Session); + } + + [Fact] + public void SetSession_UpdatesSessionInAccountClient() + { + // Arrange + var mockAccountClient = new Mock(); + mockAccountClient.As(); + var appwriteClient = new AppwriteClient(mockAccountClient.Object); + + // Act + appwriteClient.SetSession(Constants.Session); + + // Assert + mockAccountClient.As().Verify(a => a.UpdateSession(Constants.Session), Times.Once); + } +} From 554ffd765953f29d0c0973894ec0791ced3dca3a Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 02:08:55 +0100 Subject: [PATCH 30/33] Added header handler tests --- .../Handlers/HeaderHandlerTests.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Handlers/HeaderHandlerTests.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/Handlers/HeaderHandlerTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Handlers/HeaderHandlerTests.cs new file mode 100644 index 00000000..89259ef9 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Handlers/HeaderHandlerTests.cs @@ -0,0 +1,42 @@ +using Moq; +using Moq.Protected; +using PinguApps.Appwrite.Client.Handlers; +using PinguApps.Appwrite.Shared.Tests; + +namespace PinguApps.Appwrite.Client.Tests.Handlers; +public class HeaderHandlerTests +{ + [Fact] + public async Task SendAsync_AddsRequiredHeaders() + { + // Arrange + var mockInnerHandler = new Mock(); + mockInnerHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny() + ) + .ReturnsAsync(new HttpResponseMessage()) + .Verifiable(); + + var headerHandler = new HeaderHandler(Constants.ProjectId) + { + InnerHandler = mockInnerHandler.Object + }; + var httpClient = new HttpClient(headerHandler); + + // Act + await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://test.com")); + + // Assert + mockInnerHandler.Protected().Verify( + "SendAsync", + Times.Once(), + ItExpr.Is(req => + req.Headers.Contains("x-appwrite-project") && + req.Headers.GetValues("x-appwrite-project").Contains(Constants.ProjectId)), + ItExpr.IsAny() + ); + } +} From ae40c194d56d017b19865a9cef0e276df7cf1555 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 02:09:04 +0100 Subject: [PATCH 31/33] Create ServiceCollectionExtensionsTests.cs --- .../ServiceCollectionExtensionsTests.cs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/ServiceCollectionExtensionsTests.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/ServiceCollectionExtensionsTests.cs b/tests/PinguApps.Appwrite.Client.Tests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000..1f93b2cb --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Client.Handlers; +using PinguApps.Appwrite.Client.Internals; +using PinguApps.Appwrite.Shared.Tests; + +namespace PinguApps.Appwrite.Client.Tests; +public class ServiceCollectionExtensionsTests +{ + [Fact] + public void AddAppwriteClient_RegistersExpectedServices() + { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddAppwriteClient(Constants.ProjectId, Constants.Endpoint); + + // Assert + var provider = services.BuildServiceProvider(); + + // Assert HeaderHandler is registered + var headerHandler = provider.GetService(); + Assert.NotNull(headerHandler); + + // Assert IAccountApi is registered and configured + var accountApi = provider.GetService(); + Assert.NotNull(accountApi); + + // Assert services are registered + Assert.NotNull(provider.GetService()); + Assert.NotNull(provider.GetService()); + } + + [Fact] + public void AddAppwriteClientForServer_RegistersExpectedServicesWithTransientLifetime() + { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddAppwriteClientForServer(Constants.ProjectId, Constants.Endpoint); + + // Assert + var provider = services.BuildServiceProvider(); + + // Assert HeaderHandler is registered + var headerHandler = provider.GetService(); + Assert.NotNull(headerHandler); + + // Assert IAccountApi is registered and configured + var accountApi = provider.GetService(); + Assert.NotNull(accountApi); + + // Assert services are registered with Transient lifetime + var accountClientServiceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(IAccountClient)); + Assert.NotNull(accountClientServiceDescriptor); + Assert.Equal(ServiceLifetime.Transient, accountClientServiceDescriptor.Lifetime); + + var appwriteClientServiceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(IAppwriteClient)); + Assert.NotNull(appwriteClientServiceDescriptor); + Assert.Equal(ServiceLifetime.Transient, appwriteClientServiceDescriptor.Lifetime); + } +} From 31c1eb577bd8ca11b289740f8e42718f022c28bb Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 02:09:15 +0100 Subject: [PATCH 32/33] Added response utils tests --- .../Utils/ResponseUtils.cs | 2 +- .../Utils/ResponseUtilsTests.cs | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Utils/ResponseUtilsTests.cs diff --git a/src/PinguApps.Appwrite.Client/Utils/ResponseUtils.cs b/src/PinguApps.Appwrite.Client/Utils/ResponseUtils.cs index 01fbc0d1..ecfeacc4 100644 --- a/src/PinguApps.Appwrite.Client/Utils/ResponseUtils.cs +++ b/src/PinguApps.Appwrite.Client/Utils/ResponseUtils.cs @@ -18,7 +18,7 @@ internal static AppwriteResult GetApiResponse(this IApiResponse result) return new AppwriteResult(result.Content); } - if (result.Error?.Content is null) + if (result.Error?.Content is null || string.IsNullOrEmpty(result.Error.Content)) { throw new Exception("Unknown error encountered."); } diff --git a/tests/PinguApps.Appwrite.Client.Tests/Utils/ResponseUtilsTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Utils/ResponseUtilsTests.cs new file mode 100644 index 00000000..a7663bc4 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Utils/ResponseUtilsTests.cs @@ -0,0 +1,80 @@ +using System.Net; +using Moq; +using PinguApps.Appwrite.Client.Utils; +using PinguApps.Appwrite.Shared.Tests; +using Refit; + +namespace PinguApps.Appwrite.Client.Tests.Utils; +public class ResponseUtilsTests +{ + [Fact] + public void GetApiResponse_Success_ReturnsContent() + { + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(true); + mockApiResponse.SetupGet(r => r.Content).Returns("Success"); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.True(result.Success); + Assert.Equal("Success", result.Result); + } + + [Fact] + public void GetApiResponse_SuccessButNullContent_ReturnsInternalError() + { + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(true); + mockApiResponse.SetupGet(r => r.Content).Returns((string?)null); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.False(result.Success); + Assert.True(result.Result.IsT2); + } + + [Fact] + public async Task GetApiResponse_Failure_ReturnsError() + { + var response = new HttpResponseMessage(HttpStatusCode.InternalServerError) + { + Content = new StringContent(Constants.AppwriteError) + }; + var exception = await ApiException.Create(new HttpRequestMessage(), HttpMethod.Get, response, new RefitSettings()); + + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(false); + mockApiResponse.SetupGet(x => x.Error).Returns(exception); + + var result = mockApiResponse.Object.GetApiResponse(); + + Assert.False(result.Success); + Assert.True(result.IsAppwriteError); + Assert.True(result.Result.IsT1); + } + + [Fact] + public async Task GetApiResponse_FailureButNullErrorContent_ThrowsException() + { + var exception = await ApiException.Create(new HttpRequestMessage(), HttpMethod.Get, new HttpResponseMessage(HttpStatusCode.InternalServerError), new RefitSettings()); + + var mockApiResponse = new Mock>(); + mockApiResponse.SetupGet(r => r.IsSuccessStatusCode).Returns(false); + mockApiResponse.SetupGet(x => x.Error).Returns(exception); + + Assert.Throws(() => mockApiResponse.Object.GetApiResponse()); + } + + [Fact] + public void GetExceptionResponse_ReturnsInternalError() + { + var exception = new Exception("Test exception"); + + var result = exception.GetExceptionResponse(); + + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.True(result.Result.IsT2); + Assert.Equal("Test exception", result.Result.AsT2.Message); + } +} From a4bb320b4b869b05828e8f1703740045b2a610ef Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 7 Jul 2024 02:16:12 +0100 Subject: [PATCH 33/33] Adjusted test workflow, so that we ignore testing test projects --- .github/workflows/_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml index 4188aa9e..bd15bba9 100644 --- a/.github/workflows/_test.yml +++ b/.github/workflows/_test.yml @@ -52,6 +52,7 @@ jobs: tag: "${{ github.run_number }}_${{ github.run_id }}" customSettings: "" toolpath: "reportgeneratortool" + assemblyfilters: "-PinguApps.Appwrite.Shared.Tests" - name: Upload Combined Coverage XML uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4