diff --git a/README.md b/README.md index a003a73e..7e333b1d 100644 --- a/README.md +++ b/README.md @@ -138,14 +138,14 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( ``` ## βŒ› Progress - -![Server & Client - 39 / 293](https://img.shields.io/badge/Server_&_Client-39%20%2F%20293-red?style=for-the-badge) + +![Server & Client - 40 / 293](https://img.shields.io/badge/Server_&_Client-40%20%2F%20293-red?style=for-the-badge) ![Server - 5 / 200](https://img.shields.io/badge/Server-5%20%2F%20200-red?style=for-the-badge) - -![Client - 34 / 93](https://img.shields.io/badge/Client-34%20%2F%2093-gold?style=for-the-badge) + +![Client - 35 / 93](https://img.shields.io/badge/Client-35%20%2F%2093-gold?style=for-the-badge) ### πŸ”‘ Key | Icon | Definition | @@ -155,8 +155,8 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | ❌ | There is currently no intention to implement the endpoint for the given SDK type (client or server) | ### Account - -![Account - 39 / 57](https://img.shields.io/badge/Account-39%20%2F%2057-forestgreen?style=for-the-badge) + +![Account - 40 / 57](https://img.shields.io/badge/Account-40%20%2F%2057-forestgreen?style=for-the-badge) | Endpoint | Client | Server | |:-:|:-:|:-:| @@ -195,7 +195,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [Get Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#getSession) | βœ… | ❌ | | [Update Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#updateSession) | βœ… | ❌ | | [Delete Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#deleteSession) | βœ… | ❌ | -| [Update Status](https://appwrite.io/docs/references/1.6.x/client-rest/account#updateStatus) | ⬛ | ❌ | +| [Update Status](https://appwrite.io/docs/references/1.6.x/client-rest/account#updateStatus) | βœ… | ❌ | | [Create Push Target](https://appwrite.io/docs/references/1.6.x/client-rest/account#createPushTarget) | ⬛ | ❌ | | [Update Push Target](https://appwrite.io/docs/references/1.6.x/client-rest/account#updatePushTarget) | ⬛ | ❌ | | [Delete Push Target](https://appwrite.io/docs/references/1.6.x/client-rest/account#deletePushTarget) | ⬛ | ❌ | diff --git a/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs b/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs index fe36b414..b6187638 100644 --- a/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/AccountClient.cs @@ -597,4 +597,19 @@ public async Task DeleteSession(DeleteSessionRequest request) return e.GetExceptionResponse(); } } + + /// + public async Task> UpdateStatus() + { + try + { + var result = await _accountApi.UpdateStatus(GetCurrentSessionOrThrow()); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } } diff --git a/src/PinguApps.Appwrite.Client/Clients/IAccountClient.cs b/src/PinguApps.Appwrite.Client/Clients/IAccountClient.cs index f1034049..6abc2057 100644 --- a/src/PinguApps.Appwrite.Client/Clients/IAccountClient.cs +++ b/src/PinguApps.Appwrite.Client/Clients/IAccountClient.cs @@ -283,4 +283,10 @@ public interface IAccountClient /// The request content /// code 204 for success Task DeleteSession(DeleteSessionRequest request); + + /// + /// Block the currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. To completely delete a user, use the Users API instead. + /// + /// The User + Task> UpdateStatus(); } diff --git a/src/PinguApps.Appwrite.Client/Internals/IAccountApi.cs b/src/PinguApps.Appwrite.Client/Internals/IAccountApi.cs index 859f56b3..8645263c 100644 --- a/src/PinguApps.Appwrite.Client/Internals/IAccountApi.cs +++ b/src/PinguApps.Appwrite.Client/Internals/IAccountApi.cs @@ -107,4 +107,7 @@ internal interface IAccountApi : IBaseApi [Delete("/account/sessions/{sessionId}")] Task DeleteSession([Header("x-appwrite-session")] string session, string sessionId); + + [Patch("/account/status")] + Task> UpdateStatus([Header("x-appwrite-session")] string session); } diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs index 048fb42e..64040217 100644 --- a/src/PinguApps.Appwrite.Playground/App.cs +++ b/src/PinguApps.Appwrite.Playground/App.cs @@ -1,7 +1,6 @@ ο»Ώusing Microsoft.Extensions.Configuration; using PinguApps.Appwrite.Client; using PinguApps.Appwrite.Server.Servers; -using PinguApps.Appwrite.Shared.Requests; namespace PinguApps.Appwrite.Playground; internal class App @@ -21,25 +20,11 @@ public async Task Run(string[] args) { _client.SetSession(_session); - var response = await _client.Account.Get(); + var response = await _client.Account.UpdateStatus(); Console.WriteLine(response.Result.Match( account => account.ToString(), appwriteError => appwriteError.Message, internalERror => internalERror.Message)); - - var r2 = await _client.Account.DeleteSession(new DeleteSessionRequest()); - - Console.WriteLine(r2.Result.Match( - account => account.ToString(), - appwriteError => appwriteError.Message, - internalERror => internalERror.Message)); - - var r3 = await _client.Account.Get(); - - Console.WriteLine(r3.Result.Match( - account => account.ToString(), - appwriteError => appwriteError.Message, - internalERror => internalERror.Message)); } } diff --git a/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.UpdateStatus.cs b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.UpdateStatus.cs new file mode 100644 index 00000000..e3e300ae --- /dev/null +++ b/tests/PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.UpdateStatus.cs @@ -0,0 +1,74 @@ +ο»Ώusing System.Net; +using PinguApps.Appwrite.Client.Clients; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Client.Tests.Clients.Account; +public partial class AccountClientTests +{ + [Fact] + public async Task UpdateStatus_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + _mockHttp.Expect(HttpMethod.Patch, $"{Constants.Endpoint}/account/status") + .ExpectedHeaders(true) + .Respond(Constants.AppJson, Constants.UserResponse); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.UpdateStatus(); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task UpdateStatus_ShouldReturnError_WhenSessionIsNull() + { + // Act + var result = await _appwriteClient.Account.UpdateStatus(); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsInternalError); + Assert.Equal(ISessionAware.SessionExceptionMessage, result.Result.AsT2.Message); + } + + [Fact] + public async Task UpdateStatus_ShouldHandleException_WhenApiCallFails() + { + // Arrange + _mockHttp.Expect(HttpMethod.Patch, $"{Constants.Endpoint}/account/status") + .ExpectedHeaders(true) + .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.UpdateStatus(); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task UpdateStatus_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + _mockHttp.Expect(HttpMethod.Patch, $"{Constants.Endpoint}/account/status") + .ExpectedHeaders(true) + .Throw(new HttpRequestException("An error occurred")); + + _appwriteClient.SetSession(Constants.Session); + + // Act + var result = await _appwriteClient.Account.UpdateStatus(); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +}