From 2a79b9e75382ff8da2f2172d6caa2aeb899b376a Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 20 Oct 2024 20:42:46 +0100 Subject: [PATCH 1/3] Implemented update preferences --- .../Clients/ITeamsClient.cs | 11 +++++++--- .../Clients/TeamsClient.cs | 18 ++++++++++++++--- src/PinguApps.Appwrite.Playground/App.cs | 20 +++++++++++-------- .../Clients/ITeamsClient.cs | 8 +++++++- .../Clients/TeamsClient.cs | 18 ++++++++++++++--- 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs index e25c04d2..03a52a93 100644 --- a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; using PinguApps.Appwrite.Shared; using PinguApps.Appwrite.Shared.Requests.Teams; @@ -112,6 +111,12 @@ public interface ITeamsClient /// The request content /// The preferences Task>> GetTeamPreferences(GetTeamPreferencesRequest request); - [Obsolete("This method hasn't yet been implemented!")] + + /// + /// Update the team's preferences by its unique ID. The object you pass is stored as is and replaces any previous value. The maximum allowed prefs size is 64kB and throws an error if exceeded. + /// Appwrite Docs + /// + /// The request content + /// The preferences Task>> UpdatePreferences(UpdatePreferencesRequest request); } diff --git a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs index da51d0cf..a076aebb 100644 --- a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Client.Internals; @@ -229,7 +228,20 @@ public async Task>> GetTeamPr } } - [ExcludeFromCodeCoverage] /// - public Task>> UpdatePreferences(UpdatePreferencesRequest request) => throw new NotImplementedException(); + public async Task>> UpdatePreferences(UpdatePreferencesRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.UpdatePreferences(GetCurrentSessionOrThrow(), request.TeamId, request); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse>(); + } + } } diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs index 83fa4606..1d229a3d 100644 --- a/src/PinguApps.Appwrite.Playground/App.cs +++ b/src/PinguApps.Appwrite.Playground/App.cs @@ -19,21 +19,25 @@ public async Task Run(string[] args) { _client.SetSession(_session); - var request = new GetTeamPreferencesRequest() + var request = new UpdatePreferencesRequest() { - TeamId = "67142b78001c379958cb" + TeamId = "67142b78001c379958cb", + Preferences = new Dictionary() + { + {"key", "value"} + } }; - var clientResponse = await _client.Teams.GetTeamPreferences(request); + //var clientResponse = await _client.Teams.UpdatePreferences(request); - Console.WriteLine(clientResponse.Result.Match( - result => result.ToString(), - appwriteError => appwriteError.Message, - internalError => internalError.Message)); + //Console.WriteLine(clientResponse.Result.Match( + // result => result.ToString(), + // appwriteError => appwriteError.Message, + // internalError => internalError.Message)); Console.WriteLine("############################################################################"); - var serverResponse = await _server.Teams.GetTeamPreferences(request); + var serverResponse = await _server.Teams.UpdatePreferences(request); Console.WriteLine(serverResponse.Result.Match( result => result.ToString(), diff --git a/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs b/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs index ad2acd52..ad75fde0 100644 --- a/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs @@ -113,6 +113,12 @@ public interface ITeamsClient /// The request content /// The preferences Task>> GetTeamPreferences(GetTeamPreferencesRequest request); - [Obsolete("This method hasn't yet been implemented!")] + + /// + /// Update the team's preferences by its unique ID. The object you pass is stored as is and replaces any previous value. The maximum allowed prefs size is 64kB and throws an error if exceeded. + /// Appwrite Docs + /// + /// The request content + /// The preferences Task>> UpdatePreferences(UpdatePreferencesRequest request); } diff --git a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs index a545a03d..fd671aa4 100644 --- a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using PinguApps.Appwrite.Server.Internals; @@ -229,7 +228,20 @@ public async Task>> GetTeamPr } } - [ExcludeFromCodeCoverage] /// - public Task>> UpdatePreferences(UpdatePreferencesRequest request) => throw new NotImplementedException(); + public async Task>> UpdatePreferences(UpdatePreferencesRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.UpdatePreferences(request.TeamId, request); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse>(); + } + } } From 815a0e67611326714dcef8c2ccdafcef87810be8 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 20 Oct 2024 20:46:55 +0100 Subject: [PATCH 2/3] added tests for update preferences --- .../TeamsClientTests.UpdatePreferences.cs | 120 ++++++++++++++++++ .../TeamsClientTests.UpdatePreferences.cs | 90 +++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs create mode 100644 tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs new file mode 100644 index 00000000..8cefbed0 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs @@ -0,0 +1,120 @@ +using System.Net; +using PinguApps.Appwrite.Client.Clients; +using PinguApps.Appwrite.Shared.Requests.Teams; +using PinguApps.Appwrite.Shared.Tests; +using PinguApps.Appwrite.Shared.Utils; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + [Fact] + public async Task UpdatePreferences_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders(true) + .WithJsonContent(request, _jsonSerializerOptions) + .Respond(TestConstants.AppJson, TestConstants.PreferencesResponse); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task UpdatePreferences_ShouldReturnError_WhenSessionIsNull() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsInternalError); + Assert.Equal(ISessionAware.SessionExceptionMessage, result.Result.AsT2.Message); + } + + [Fact] + public async Task UpdatePreferences_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders(true) + .WithJsonContent(request, _jsonSerializerOptions) + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task UpdatePreferences_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders(true) + .WithJsonContent(request, _jsonSerializerOptions) + .Throw(new HttpRequestException("An error occurred")); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(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.UpdatePreferences.cs b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs new file mode 100644 index 00000000..4d8f6be2 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.UpdatePreferences.cs @@ -0,0 +1,90 @@ +using System.Net; +using PinguApps.Appwrite.Shared.Requests.Teams; +using PinguApps.Appwrite.Shared.Tests; +using PinguApps.Appwrite.Shared.Utils; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Server.Tests.Clients.Teams; +public partial class TeamsClientTests +{ + [Fact] + public async Task UpdatePreferences_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders() + .WithJsonContent(request, _jsonSerializerOptions) + .Respond(TestConstants.AppJson, TestConstants.PreferencesResponse); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task UpdatePreferences_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders() + .WithJsonContent(request, _jsonSerializerOptions) + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task UpdatePreferences_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new UpdatePreferencesRequest + { + TeamId = IdUtils.GenerateUniqueId(), + Preferences = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" } + } + }; + + _mockHttp.Expect(HttpMethod.Put, $"{TestConstants.Endpoint}/teams/{request.TeamId}/prefs") + .ExpectedHeaders() + .WithJsonContent(request, _jsonSerializerOptions) + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteClient.Teams.UpdatePreferences(request); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +} From 3354d4e9ffe4034f4d23d292cbf44b8bad270975 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Sun, 20 Oct 2024 20:50:04 +0100 Subject: [PATCH 3/3] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c7af5a0a..1b1860e5 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,11 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( ## ⌛ Progress -![Server & Client - 124 / 318](https://img.shields.io/badge/Server_&_Client-124%20%2F%20318-gold?style=for-the-badge) +![Server & Client - 126 / 318](https://img.shields.io/badge/Server_&_Client-126%20%2F%20318-gold?style=for-the-badge) -![Server - 65 / 225](https://img.shields.io/badge/Server-65%20%2F%20225-red?style=for-the-badge) +![Server - 66 / 225](https://img.shields.io/badge/Server-66%20%2F%20225-red?style=for-the-badge) -![Client - 59 / 93](https://img.shields.io/badge/Client-59%20%2F%2093-gold?style=for-the-badge) +![Client - 60 / 93](https://img.shields.io/badge/Client-60%20%2F%2093-gold?style=for-the-badge) ### 🔑 Key | Icon | Definition | @@ -256,7 +256,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [Update Phone Verification](https://appwrite.io/docs/references/1.6.x/server-rest/users#updatePhoneVerification) | ❌ | ✅ | ### Teams -![Teams - 24 / 26](https://img.shields.io/badge/Teams-24%20%2F%2026-forestgreen?style=for-the-badge) +![Teams - 26 / 26](https://img.shields.io/badge/Teams-24%20%2F%2026-blue?style=for-the-badge) | Endpoint | Client | Server | |:-:|:-:|:-:| @@ -272,7 +272,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [Delete Team Membership](https://appwrite.io/docs/references/1.6.x/client-rest/teams#deleteMembership) | ✅ | ✅ | | [Update Team Membership Status](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updateMembershipStatus) | ✅ | ✅ | | [Get Team Memberships](https://appwrite.io/docs/references/1.6.x/client-rest/teams#getPrefs) | ✅ | ✅ | -| [Update Preferences](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updatePrefs) | ⬛ | ⬛ | +| [Update Preferences](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updatePrefs) | ✅ | ✅ | ### Databases ![Databases - 0 / 47](https://img.shields.io/badge/Databases-0%20%2F%2047-red?style=for-the-badge)