From d65376aece6c6b77ae2ce7900506d8d9234e4ec8 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Fri, 18 Oct 2024 01:13:35 +0100 Subject: [PATCH 1/3] Fixed some holes, and implemented ListTeams --- .../Clients/AccountClient.cs | 25 +----------------- .../Clients/AppwriteClient.cs | 1 + .../Clients/IAppwriteClient.cs | 5 +++- .../Clients/ITeamsClient.cs | 7 ++++- .../Clients/SessionAwareClientBase.cs | 22 ++++++++++++++++ .../Clients/TeamsClient.cs | 21 ++++++++++++--- .../Internals/ITeamsApi.cs | 26 +++++++++---------- src/PinguApps.Appwrite.Playground/App.cs | 18 +++++++++---- .../Clients/IAppwriteClient.cs | 1 + .../Clients/ITeamsClient.cs | 7 ++++- .../Clients/TeamsClient.cs | 19 ++++++++++++-- 11 files changed, 102 insertions(+), 50 deletions(-) create mode 100644 src/PinguApps.Appwrite.Client/Clients/SessionAwareClientBase.cs diff --git a/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs b/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs index f2677d22..581bd728 100644 --- a/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs @@ -12,7 +12,7 @@ namespace PinguApps.Appwrite.Client; /// -public class AccountClient : IAccountClient, ISessionAware +public class AccountClient : SessionAwareClientBase, IAccountClient { private readonly IAccountApi _accountApi; private readonly Config _config; @@ -23,29 +23,6 @@ public AccountClient(IServiceProvider services, Config config) _config = config; } - string? ISessionAware.Session { get; set; } - - ISessionAware? _sessionAware; - /// - /// Get the current session - /// - public string? Session => GetCurrentSession(); - - private string? GetCurrentSession() - { - if (_sessionAware is null) - { - _sessionAware = this; - } - - return _sessionAware.Session; - } - - private string GetCurrentSessionOrThrow() - { - return GetCurrentSession() ?? throw new Exception(ISessionAware.SessionExceptionMessage); - } - /// public async Task> Get() { diff --git a/src/PinguApps.Appwrite.Client/Clients/AppwriteClient.cs b/src/PinguApps.Appwrite.Client/Clients/AppwriteClient.cs index 433300b6..447f6176 100644 --- a/src/PinguApps.Appwrite.Client/Clients/AppwriteClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/AppwriteClient.cs @@ -35,5 +35,6 @@ public void SetSession(string? session) { (this as ISessionAware).UpdateSession(session); (Account as ISessionAware)!.UpdateSession(session); + (Teams as ISessionAware)!.UpdateSession(session); } } diff --git a/src/PinguApps.Appwrite.Client/Clients/IAppwriteClient.cs b/src/PinguApps.Appwrite.Client/Clients/IAppwriteClient.cs index e2d92c8a..c212a5b3 100644 --- a/src/PinguApps.Appwrite.Client/Clients/IAppwriteClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/IAppwriteClient.cs @@ -1,4 +1,6 @@ -namespace PinguApps.Appwrite.Client; +using PinguApps.Appwrite.Client.Clients; + +namespace PinguApps.Appwrite.Client; /// /// The root of the Client SDK. Access all API sections from here @@ -23,4 +25,5 @@ public interface IAppwriteClient /// The sessio of the currently logged in user /// string? Session { get; } + ITeamsClient Teams { get; } } diff --git a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs index e1325283..0191bc8b 100644 --- a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs @@ -13,7 +13,12 @@ namespace PinguApps.Appwrite.Client.Clients; /// public interface ITeamsClient { - [Obsolete("This method hasn't yet been implemented!")] + /// + /// Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results. + /// Appwrite Docs + /// + /// The request content + /// The teams list Task> ListTeams(ListTeamsRequest request); [Obsolete("This method hasn't yet been implemented!")] Task> CreateTeam(CreateTeamRequest request); diff --git a/src/PinguApps.Appwrite.Client/Clients/SessionAwareClientBase.cs b/src/PinguApps.Appwrite.Client/Clients/SessionAwareClientBase.cs new file mode 100644 index 00000000..394b0519 --- /dev/null +++ b/src/PinguApps.Appwrite.Client/Clients/SessionAwareClientBase.cs @@ -0,0 +1,22 @@ +using System; + +namespace PinguApps.Appwrite.Client.Clients; +public abstract class SessionAwareClientBase : ISessionAware +{ + string? ISessionAware.Session { get; set; } + + /// + /// Get the current session + /// + public string? Session => GetCurrentSession(); + + protected string? GetCurrentSession() + { + return ((ISessionAware)this).Session; + } + + public string GetCurrentSessionOrThrow() + { + return GetCurrentSession() ?? throw new Exception(ISessionAware.SessionExceptionMessage); + } +} diff --git a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs index 4e974dee..9a76eeca 100644 --- a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Client.Internals; +using PinguApps.Appwrite.Client.Utils; using PinguApps.Appwrite.Shared; using PinguApps.Appwrite.Shared.Requests.Teams; using PinguApps.Appwrite.Shared.Responses; @@ -11,7 +12,7 @@ namespace PinguApps.Appwrite.Client.Clients; /// -public class TeamsClient : ITeamsClient +public class TeamsClient : SessionAwareClientBase, ITeamsClient { private readonly ITeamsApi _teamsApi; private readonly Config _config; @@ -22,8 +23,22 @@ public TeamsClient(IServiceProvider services, Config config) _config = config; } - [ExcludeFromCodeCoverage] - public Task> ListTeams(ListTeamsRequest request) => throw new NotImplementedException(); + /// + public async Task> ListTeams(ListTeamsRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.ListTeams(GetCurrentSessionOrThrow(), RequestUtils.GetQueryStrings(request.Queries), request.Search); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } [ExcludeFromCodeCoverage] /// diff --git a/src/PinguApps.Appwrite.Client/Internals/ITeamsApi.cs b/src/PinguApps.Appwrite.Client/Internals/ITeamsApi.cs index 1ddf4bc3..0d3e3707 100644 --- a/src/PinguApps.Appwrite.Client/Internals/ITeamsApi.cs +++ b/src/PinguApps.Appwrite.Client/Internals/ITeamsApi.cs @@ -10,42 +10,42 @@ internal interface ITeamsApi : IBaseApi { [Get("/teams")] [QueryUriFormat(UriFormat.Unescaped)] - Task> ListTeams([Query(CollectionFormat.Multi), AliasAs("queries[]")] IEnumerable queries, string? search); + Task> ListTeams([Header("x-appwrite-session")] string session, [Query(CollectionFormat.Multi), AliasAs("queries[]")] IEnumerable queries, string? search); [Post("/teams")] - Task> CreateTeam(CreateTeamRequest request); + Task> CreateTeam([Header("x-appwrite-session")] string session, CreateTeamRequest request); [Delete("/teams/{teamId}")] - Task DeleteTeam(string teamId); + Task DeleteTeam([Header("x-appwrite-session")] string session, string teamId); [Get("/teams/{teamId}")] - Task> GetTeam(string teamId); + Task> GetTeam([Header("x-appwrite-session")] string session, string teamId); [Put("/teams/{teamId}")] - Task> UpdateName(string teamId, UpdateNameRequest request); + Task> UpdateName([Header("x-appwrite-session")] string session, string teamId, UpdateNameRequest request); [Get("/teams/{teamId}/memberships")] [QueryUriFormat(UriFormat.Unescaped)] - Task> ListTeamMemberships(string teamId, [Query(CollectionFormat.Multi), AliasAs("queries[]")] IEnumerable queries, string? search); + Task> ListTeamMemberships([Header("x-appwrite-session")] string session, string teamId, [Query(CollectionFormat.Multi), AliasAs("queries[]")] IEnumerable queries, string? search); [Post("/teams/{teamId}/memberships")] - Task> CreateTeamMembership(string teamId, CreateTeamMembershipRequest request); + Task> CreateTeamMembership([Header("x-appwrite-session")] string session, string teamId, CreateTeamMembershipRequest request); [Delete("/teams/{teamId}/memberships/{membershipId}")] - Task DeleteTeamMembership(string teamId, string membershipId); + Task DeleteTeamMembership([Header("x-appwrite-session")] string session, string teamId, string membershipId); [Get("/teams/{teamId}/memberships/{membershipId}")] - Task> GetTeamMembership(string teamId, string membershipId); + Task> GetTeamMembership([Header("x-appwrite-session")] string session, string teamId, string membershipId); [Patch("/teams/{teamId}/memberships/{membershipId}")] - Task> UpdateMembership(string teamId, string membershipId, UpdateMembershipRequest request); + Task> UpdateMembership([Header("x-appwrite-session")] string session, string teamId, string membershipId, UpdateMembershipRequest request); [Patch("/teams/{teamId}/memberships/{membershipId}/status")] - Task> UpdateTeamMembershipStatus(string teamId, string membershipId, UpdateTeamMembershipStatusRequest request); + Task> UpdateTeamMembershipStatus([Header("x-appwrite-session")] string session, string teamId, string membershipId, UpdateTeamMembershipStatusRequest request); [Get("/teams/{teamId}/prefs")] - Task>> GetTeamPreferences(string teamId); + Task>> GetTeamPreferences([Header("x-appwrite-session")] string session, string teamId); [Put("/teams/{teamId}/prefs")] - Task>> UpdatePreferences(string teamId, UpdatePreferencesRequest request); + Task>> UpdatePreferences([Header("x-appwrite-session")] string session, string teamId, UpdatePreferencesRequest request); } diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs index 09bab76e..12241919 100644 --- a/src/PinguApps.Appwrite.Playground/App.cs +++ b/src/PinguApps.Appwrite.Playground/App.cs @@ -1,5 +1,5 @@ using Microsoft.Extensions.Configuration; -using PinguApps.Appwrite.Shared.Requests.Account; +using PinguApps.Appwrite.Shared.Requests.Teams; namespace PinguApps.Appwrite.Playground; internal class App @@ -19,14 +19,22 @@ public async Task Run(string[] args) { _client.SetSession(_session); - var request = new DeletePushTargetRequest() + var request = new ListTeamsRequest() { - TargetId = "670be3330025c0f23b93" }; - var response = await _client.Account.DeletePushTarget(request); + var clientResponse = await _client.Teams.ListTeams(request); - Console.WriteLine(response.Result.Match( + Console.WriteLine(clientResponse.Result.Match( + result => result.ToString(), + appwriteError => appwriteError.Message, + internalError => internalError.Message)); + + Console.WriteLine("############################################################################"); + + var serverResponse = await _server.Teams.ListTeams(request); + + Console.WriteLine(serverResponse.Result.Match( result => result.ToString(), appwriteError => appwriteError.Message, internalError => internalError.Message)); diff --git a/src/PinguApps.Appwrite.Server/Clients/IAppwriteClient.cs b/src/PinguApps.Appwrite.Server/Clients/IAppwriteClient.cs index c29a371b..3be2226e 100644 --- a/src/PinguApps.Appwrite.Server/Clients/IAppwriteClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/IAppwriteClient.cs @@ -18,4 +18,5 @@ public interface IAppwriteClient /// Appwrite Docs /// IUsersClient Users { get; } + ITeamsClient Teams { get; } } diff --git a/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs b/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs index 4e03b6e8..7d2d431d 100644 --- a/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs @@ -13,7 +13,12 @@ namespace PinguApps.Appwrite.Server.Clients; /// public interface ITeamsClient { - [Obsolete("This method hasn't yet been implemented!")] + /// + /// Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results. + /// Appwrite Docs + /// + /// The request content + /// The teams list Task> ListTeams(ListTeamsRequest request); [Obsolete("This method hasn't yet been implemented!")] Task> CreateTeam(CreateTeamRequest request); diff --git a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs index 8bd58f6f..d97887d1 100644 --- a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Server.Internals; +using PinguApps.Appwrite.Server.Utils; using PinguApps.Appwrite.Shared; using PinguApps.Appwrite.Shared.Requests.Teams; using PinguApps.Appwrite.Shared.Responses; @@ -22,8 +23,22 @@ public TeamsClient(IServiceProvider services, Config config) _config = config; } - [ExcludeFromCodeCoverage] - public Task> ListTeams(ListTeamsRequest request) => throw new NotImplementedException(); + /// + public async Task> ListTeams(ListTeamsRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.ListTeams(RequestUtils.GetQueryStrings(request.Queries), request.Search); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } [ExcludeFromCodeCoverage] /// From fd832c7167f47d56810e2954a76fe4819b98f5f6 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Fri, 18 Oct 2024 01:42:32 +0100 Subject: [PATCH 2/3] Rejigged tests and added tests for create teams --- .../Clients/Account/AccountClientTests.cs | 2 +- .../Clients/AppwriteClientTests.cs | 2 + ...Extensions.cs => ClientTestsExtensions.cs} | 4 +- .../Teams/TeamsClientTests.ListTeams.cs | 84 +++++++++++++++++++ .../Clients/Teams/TeamsClientTests.cs | 38 +++++++++ .../Teams/TeamsClientTests.ListTeams.cs | 62 ++++++++++++++ .../Clients/Teams/TeamsClientTests.cs | 39 +++++++++ 7 files changed, 228 insertions(+), 3 deletions(-) rename tests/PinguApps.Appwrite.Client.Tests/Clients/{Account/AccountTestsExtensions.cs => ClientTestsExtensions.cs} (90%) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.cs create mode 100644 tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs create mode 100644 tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs index 968d22ad..6b41629f 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.cs @@ -22,7 +22,7 @@ public AccountClientTests() _mockHttp = new MockHttpMessageHandler(); var services = new ServiceCollection(); - services.AddAppwriteClientForServer("PROJECT_ID", TestConstants.Endpoint, new RefitSettings + services.AddAppwriteClientForServer(TestConstants.ProjectId, TestConstants.Endpoint, new RefitSettings { HttpMessageHandlerFactory = () => _mockHttp }); diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs index 4f485339..780e65c0 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/AppwriteClientTests.cs @@ -42,6 +42,7 @@ public void SetSession_UpdatesSession() var mockAccountClient = new Mock(); var mockTeamsClient = new Mock(); mockAccountClient.As(); + mockTeamsClient.As(); var appwriteClient = new AppwriteClient(mockAccountClient.Object, mockTeamsClient.Object); // Act @@ -58,6 +59,7 @@ public void SetSession_UpdatesSessionInAccountClient() var mockAccountClient = new Mock(); var mockTeamsClient = new Mock(); mockAccountClient.As(); + mockTeamsClient.As(); var appwriteClient = new AppwriteClient(mockAccountClient.Object, mockTeamsClient.Object); // Act diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountTestsExtensions.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/ClientTestsExtensions.cs similarity index 90% rename from tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountTestsExtensions.cs rename to tests/PinguApps.Appwrite.Client.Tests/Clients/ClientTestsExtensions.cs index 8338d4af..17fccfb6 100644 --- a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountTestsExtensions.cs +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/ClientTestsExtensions.cs @@ -2,9 +2,9 @@ using PinguApps.Appwrite.Shared.Tests; using RichardSzalay.MockHttp; -namespace PinguApps.Appwrite.Client.Tests.Clients.Account; +namespace PinguApps.Appwrite.Client.Tests.Clients; -public static class AccountTestsExtensions +public static class ClientTestsExtensions { public static MockedRequest ExpectedHeaders(this MockedRequest request, bool addSessionHeaders = false) { diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs new file mode 100644 index 00000000..e7c14de2 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs @@ -0,0 +1,84 @@ +using System.Net; +using PinguApps.Appwrite.Client.Clients; +using PinguApps.Appwrite.Shared.Requests.Teams; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + [Fact] + public async Task ListTeams_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders(true) + .Respond(TestConstants.AppJson, TestConstants.TeamsListResponse); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.ListTeams(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task ListTeams_ShouldReturnError_WhenSessionIsNull() + { + // Arrange + var request = new ListTeamsRequest(); + + // Act + var result = await _appwriteClient.Teams.ListTeams(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsInternalError); + Assert.Equal(ISessionAware.SessionExceptionMessage, result.Result.AsT2.Message); + } + + [Fact] + public async Task ListTeams_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders(true) + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.ListTeams(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task ListTeams_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders(true) + .Throw(new HttpRequestException("An error occurred")); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.ListTeams(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/Teams/TeamsClientTests.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.cs new file mode 100644 index 00000000..c991ab08 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.cs @@ -0,0 +1,38 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Shared.Converters; +using PinguApps.Appwrite.Shared.Tests; +using Refit; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + private readonly MockHttpMessageHandler _mockHttp; + private readonly IAppwriteClient _appwriteClient; + private readonly JsonSerializerOptions _jsonSerializerOptions; + + public TeamsClientTests() + { + _mockHttp = new MockHttpMessageHandler(); + var services = new ServiceCollection(); + + services.AddAppwriteClientForServer(TestConstants.ProjectId, TestConstants.Endpoint, new RefitSettings + { + HttpMessageHandlerFactory = () => _mockHttp + }); + + var serviceProvider = services.BuildServiceProvider(); + + _appwriteClient = serviceProvider.GetRequiredService(); + + _jsonSerializerOptions = new JsonSerializerOptions + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + _jsonSerializerOptions.Converters.Add(new IgnoreSdkExcludedPropertiesConverterFactory()); + } +} diff --git a/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs new file mode 100644 index 00000000..c5c9efbb --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.ListTeams.cs @@ -0,0 +1,62 @@ +using System.Net; +using PinguApps.Appwrite.Shared.Requests.Teams; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Server.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + [Fact] + public async Task ListTeams_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders() + .Respond(TestConstants.AppJson, TestConstants.TeamsListResponse); + + // Act + var result = await _appwriteClient.Teams.ListTeams(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task ListTeams_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders() + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + // Act + var result = await _appwriteClient.Teams.ListTeams(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task ListTeams_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new ListTeamsRequest(); + + _mockHttp.Expect(HttpMethod.Get, $"{TestConstants.Endpoint}/teams") + .ExpectedHeaders() + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteClient.Teams.ListTeams(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.Server.Tests/Clients/Teams/TeamsClientTests.cs b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.cs new file mode 100644 index 00000000..9efd8b38 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.cs @@ -0,0 +1,39 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.DependencyInjection; +using PinguApps.Appwrite.Server.Clients; +using PinguApps.Appwrite.Shared.Converters; +using PinguApps.Appwrite.Shared.Tests; +using Refit; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Server.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + private readonly MockHttpMessageHandler _mockHttp; + private readonly IAppwriteClient _appwriteClient; + private readonly JsonSerializerOptions _jsonSerializerOptions; + + public TeamsClientTests() + { + _mockHttp = new MockHttpMessageHandler(); + var services = new ServiceCollection(); + + services.AddAppwriteServer(TestConstants.ProjectId, TestConstants.ApiKey, TestConstants.Endpoint, new RefitSettings + { + HttpMessageHandlerFactory = () => _mockHttp + }); + + var serviceProvider = services.BuildServiceProvider(); + + _appwriteClient = serviceProvider.GetRequiredService(); + + _jsonSerializerOptions = new JsonSerializerOptions + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + _jsonSerializerOptions.Converters.Add(new IgnoreSdkExcludedPropertiesConverterFactory()); + } +} From 7e8215309491bb13616906f54dbb35f4fa5e7d44 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Fri, 18 Oct 2024 01:47:55 +0100 Subject: [PATCH 3/3] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 07c114e8..391ba881 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,11 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( ## ⌛ Progress -![Server & Client - 100 / 295](https://img.shields.io/badge/Server_&_Client-100%20%2F%20295-gold?style=for-the-badge) +![Server & Client - 102 / 295](https://img.shields.io/badge/Server_&_Client-102%20%2F%20295-gold?style=for-the-badge) -![Server - 53 / 202](https://img.shields.io/badge/Server-53%20%2F%20202-red?style=for-the-badge) +![Server - 54 / 202](https://img.shields.io/badge/Server-54%20%2F%20202-red?style=for-the-badge) -![Client - 47 / 93](https://img.shields.io/badge/Client-47%20%2F%2093-gold?style=for-the-badge) +![Client - 48 / 93](https://img.shields.io/badge/Client-48%20%2F%2093-gold?style=for-the-badge) ### 🔑 Key | Icon | Definition | @@ -256,12 +256,11 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [Update Phone Verification](https://appwrite.io/docs/references/1.6.x/server-rest/users#updatePhoneVerification) | ❌ | ✅ | ### Teams - -![Teams - 0 / 26](https://img.shields.io/badge/Teams-0%20%2F%2026-red?style=for-the-badge) +![Teams - 2 / 26](https://img.shields.io/badge/Teams-2%20%2F%2026-red?style=for-the-badge) | Endpoint | Client | Server | |:-:|:-:|:-:| -| [List Teams](https://appwrite.io/docs/references/1.6.x/client-rest/teams#list) | ⬛ | ⬛ | +| [List Teams](https://appwrite.io/docs/references/1.6.x/client-rest/teams#list) | ✅ | ✅ | | [Create Team](https://appwrite.io/docs/references/1.6.x/client-rest/teams#create) | ⬛ | ⬛ | | [Get Team](https://appwrite.io/docs/references/1.6.x/client-rest/teams#get) | ⬛ | ⬛ | | [Update Name](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updateName) | ⬛ | ⬛ |