diff --git a/README.md b/README.md index 1de1514c..198cf76d 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,11 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( ## βŒ› Progress -![Server & Client - 118 / 318](https://img.shields.io/badge/Server_&_Client-118%20%2F%20318-gold?style=for-the-badge) +![Server & Client - 120 / 318](https://img.shields.io/badge/Server_&_Client-120%20%2F%20318-gold?style=for-the-badge) -![Server - 62 / 225](https://img.shields.io/badge/Server-62%20%2F%20225-red?style=for-the-badge) +![Server - 63 / 225](https://img.shields.io/badge/Server-63%20%2F%20225-red?style=for-the-badge) -![Client - 56 / 93](https://img.shields.io/badge/Client-56%20%2F%2093-gold?style=for-the-badge) +![Client - 57 / 93](https://img.shields.io/badge/Client-57%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 - 18 / 26](https://img.shields.io/badge/Teams-18%20%2F%2026-gold?style=for-the-badge) +![Teams - 20 / 26](https://img.shields.io/badge/Teams-18%20%2F%2026-gold?style=for-the-badge) | Endpoint | Client | Server | |:-:|:-:|:-:| @@ -268,7 +268,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [List Team Memberships](https://appwrite.io/docs/references/1.6.x/client-rest/teams#listMemberships) | βœ… | βœ… | | [Create Team Membership](https://appwrite.io/docs/references/1.6.x/client-rest/teams#createMembership) | βœ… | βœ… | | [Get Team Membership](https://appwrite.io/docs/references/1.6.x/client-rest/teams#getMembership) | βœ… | βœ… | -| [Update Membership](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updateMembership) | ⬛ | ⬛ | +| [Update Membership](https://appwrite.io/docs/references/1.6.x/client-rest/teams#updateMembership) | βœ… | βœ… | | [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) | ⬛ | ⬛ | diff --git a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs index c6d1ccb7..d41777ca 100644 --- a/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/ITeamsClient.cs @@ -87,7 +87,13 @@ public interface ITeamsClient /// The request content /// The membership Task> GetTeamMembership(GetTeamMembershipRequest request); - [Obsolete("This method hasn't yet been implemented!")] + + /// + /// Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about roles and permissions. + /// Appwrite Docs + /// + /// The request content + /// The membership Task> UpdateMembership(UpdateMembershipRequest request); [Obsolete("This method hasn't yet been implemented!")] Task> UpdateTeamMembershipStatus(UpdateTeamMembershipStatusRequest request); diff --git a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs index 7e580097..98853132 100644 --- a/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/TeamsClient.cs @@ -178,9 +178,22 @@ public async Task> GetTeamMembership(GetTeamMembershi } } - [ExcludeFromCodeCoverage] /// - public Task> UpdateMembership(UpdateMembershipRequest request) => throw new NotImplementedException(); + public async Task> UpdateMembership(UpdateMembershipRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.UpdateMembership(GetCurrentSessionOrThrow(), request.TeamId, request.MembershipId, request); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } [ExcludeFromCodeCoverage] /// diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs index 444aa331..ee75df12 100644 --- a/src/PinguApps.Appwrite.Playground/App.cs +++ b/src/PinguApps.Appwrite.Playground/App.cs @@ -19,23 +19,23 @@ public async Task Run(string[] args) { _client.SetSession(_session); - var request = new CreateTeamMembershipRequest() + var request = new UpdateMembershipRequest() { TeamId = "67142b78001c379958cb", - Email = "pingu@example.com", - Name = "Pingu" + MembershipId = "671515e5bf4d9b8849c8", + Roles = ["server"] }; - var clientResponse = await _client.Teams.CreateTeamMembership(request); + //var clientResponse = await _client.Teams.UpdateMembership(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.CreateTeamMembership(request); + var serverResponse = await _server.Teams.UpdateMembership(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 04a8c655..be217d7f 100644 --- a/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/ITeamsClient.cs @@ -87,7 +87,13 @@ public interface ITeamsClient /// The request content /// The membership Task> GetTeamMembership(GetTeamMembershipRequest request); - [Obsolete("This method hasn't yet been implemented!")] + + /// + /// Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about roles and permissions. + /// Appwrite Docs + /// + /// The request content + /// The membership Task> UpdateMembership(UpdateMembershipRequest request); [Obsolete("This method hasn't yet been implemented!")] Task> UpdateTeamMembershipStatus(UpdateTeamMembershipStatusRequest request); diff --git a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs index 3245a507..69bf115c 100644 --- a/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs +++ b/src/PinguApps.Appwrite.Server/Clients/TeamsClient.cs @@ -178,9 +178,22 @@ public async Task> GetTeamMembership(GetTeamMembershi } } - [ExcludeFromCodeCoverage] /// - public Task> UpdateMembership(UpdateMembershipRequest request) => throw new NotImplementedException(); + public async Task> UpdateMembership(UpdateMembershipRequest request) + { + try + { + request.Validate(true); + + var result = await _teamsApi.UpdateMembership(request.TeamId, request.MembershipId, request); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } [ExcludeFromCodeCoverage] /// diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdateMembership.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdateMembership.cs new file mode 100644 index 00000000..b43cbde5 --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Teams/TeamsClientTests.UpdateMembership.cs @@ -0,0 +1,105 @@ +ο»Ώ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 UpdateMembership_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders(true) + .Respond(TestConstants.AppJson, TestConstants.MembershipResponse); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task UpdateMembership_ShouldReturnError_WhenSessionIsNull() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsInternalError); + Assert.Equal(ISessionAware.SessionExceptionMessage, result.Result.AsT2.Message); + } + + [Fact] + public async Task UpdateMembership_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders(true) + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task UpdateMembership_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders(true) + .Throw(new HttpRequestException("An error occurred")); + + _appwriteClient.SetSession(TestConstants.Session); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(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.UpdateMembership.cs b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.UpdateMembership.cs new file mode 100644 index 00000000..33abfdab --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Clients/Teams/TeamsClientTests.UpdateMembership.cs @@ -0,0 +1,78 @@ +ο»Ώ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 UpdateMembership_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders() + .Respond(TestConstants.AppJson, TestConstants.MembershipResponse); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task UpdateMembership_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders() + .Respond(HttpStatusCode.BadRequest, TestConstants.AppJson, TestConstants.AppwriteError); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task UpdateMembership_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new UpdateMembershipRequest + { + TeamId = IdUtils.GenerateUniqueId(), + MembershipId = IdUtils.GenerateUniqueId(), + // Add other necessary fields for the request + }; + + _mockHttp.Expect(HttpMethod.Patch, $"{TestConstants.Endpoint}/teams/{request.TeamId}/memberships/{request.MembershipId}") + .ExpectedHeaders() + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteClient.Teams.UpdateMembership(request); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +}