From 3aabf887c1ac0f8f438ea228ff882cc7cafc4ec1 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Tue, 3 Sep 2024 19:13:55 +0100 Subject: [PATCH 1/3] Implemented create email password session for server and tested it --- src/PinguApps.Appwrite.Playground/App.cs | 12 ++++++++++-- .../Internals/IAccountApi.cs | 3 +++ .../Servers/AccountServer.cs | 17 +++++++++++++++++ .../Servers/IAccountServer.cs | 9 +++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs index 4d6cb744..ac20dec4 100644 --- a/src/PinguApps.Appwrite.Playground/App.cs +++ b/src/PinguApps.Appwrite.Playground/App.cs @@ -1,6 +1,7 @@ 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 @@ -20,7 +21,14 @@ public async Task Run(string[] args) { //_client.SetSession(_session); - var response = await _server.Account.CreateAnonymousSession(); + var request = new CreateEmailPasswordSessionRequest() + { + Email = "pingu@pinguapps.com", + Password = "REDACTED" + }; + + + var response = await _server.Account.CreateEmailPasswordSession(request); Console.WriteLine(response.Result.Match( account => account.ToString(), @@ -29,7 +37,7 @@ public async Task Run(string[] args) await Task.Delay(5000); - var response2 = await _server.Account.CreateAnonymousSession(); + var response2 = await _server.Account.CreateEmailPasswordSession(request); Console.WriteLine(response2.Result.Match( account => account.ToString(), diff --git a/src/PinguApps.Appwrite.Server/Internals/IAccountApi.cs b/src/PinguApps.Appwrite.Server/Internals/IAccountApi.cs index 05c39776..059dd88b 100644 --- a/src/PinguApps.Appwrite.Server/Internals/IAccountApi.cs +++ b/src/PinguApps.Appwrite.Server/Internals/IAccountApi.cs @@ -14,4 +14,7 @@ internal interface IAccountApi : IBaseApi [Post("/account/sessions/anonymous")] Task> CreateAnonymousSession(); + + [Post("/account/sessions/email")] + Task> CreateEmailPasswordSession(CreateEmailPasswordSessionRequest request); } diff --git a/src/PinguApps.Appwrite.Server/Servers/AccountServer.cs b/src/PinguApps.Appwrite.Server/Servers/AccountServer.cs index bddf9dc4..aa7cfba6 100644 --- a/src/PinguApps.Appwrite.Server/Servers/AccountServer.cs +++ b/src/PinguApps.Appwrite.Server/Servers/AccountServer.cs @@ -65,4 +65,21 @@ public async Task> CreateAnonymousSession() return e.GetExceptionResponse(); } } + + /// + public async Task> CreateEmailPasswordSession(CreateEmailPasswordSessionRequest request) + { + try + { + request.Validate(true); + + var result = await _accountApi.CreateEmailPasswordSession(request); + + return result.GetApiResponse(); + } + catch (Exception e) + { + return e.GetExceptionResponse(); + } + } } diff --git a/src/PinguApps.Appwrite.Server/Servers/IAccountServer.cs b/src/PinguApps.Appwrite.Server/Servers/IAccountServer.cs index 0da861b6..5e41bbe5 100644 --- a/src/PinguApps.Appwrite.Server/Servers/IAccountServer.cs +++ b/src/PinguApps.Appwrite.Server/Servers/IAccountServer.cs @@ -36,4 +36,13 @@ public interface IAccountServer /// /// The Session Task> CreateAnonymousSession(); + + /// + /// Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. + /// A user is limited to 10 active sessions at a time by default. Learn more about session limits. + /// Appwrite Docs + /// + /// The request content + /// The Session + Task> CreateEmailPasswordSession(CreateEmailPasswordSessionRequest request); } From dfa92df9bf4b5afcca17cff1391f77fc41750af8 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Tue, 3 Sep 2024 19:15:18 +0100 Subject: [PATCH 2/3] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 37b5a60e..49162716 100644 --- a/README.md +++ b/README.md @@ -138,11 +138,11 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( ``` ## ⌛ Progress - -![Server & Client - 36 / 293](https://img.shields.io/badge/Server_&_Client-36%20%2F%20293-red?style=for-the-badge) + +![Server & Client - 37 / 293](https://img.shields.io/badge/Server_&_Client-37%20%2F%20293-red?style=for-the-badge) - -![Server - 3 / 200](https://img.shields.io/badge/Server-3%20%2F%20200-red?style=for-the-badge) + +![Server - 4 / 200](https://img.shields.io/badge/Server-4%20%2F%20200-red?style=for-the-badge) ![Client - 33 / 93](https://img.shields.io/badge/Client-33%20%2F%2093-red?style=for-the-badge) @@ -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 - 36 / 57](https://img.shields.io/badge/Account-36%20%2F%2057-gold?style=for-the-badge) + +![Account - 37 / 57](https://img.shields.io/badge/Account-37%20%2F%2057-gold?style=for-the-badge) | Endpoint | Client | Server | |:-:|:-:|:-:| @@ -187,7 +187,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match( | [List Sessions](https://appwrite.io/docs/references/1.6.x/client-rest/account#listSessions) | ✅ | ❌ | | [Delete Sessions](https://appwrite.io/docs/references/1.6.x/client-rest/account#deleteSessions) | ✅ | ❌ | | [Create Anonymous Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#createAnonymousSession) | ✅ | ✅ | -| [Create Email Password Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#createEmailPasswordSession) | ✅ | ⬛ | +| [Create Email Password Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#createEmailPasswordSession) | ✅ | ✅ | | [Update Magic URL Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#updateMagicURLSession) | ⬛ | ⬛ | | [Create OAuth2 Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#createOAuth2Session) | ✅ | ❌ | | [Update Phone Session](https://appwrite.io/docs/references/1.6.x/client-rest/account#updatePhoneSession) | ⬛ | ⬛ | From 531d86bce64f3ba69aac72216c406844a0241b34 Mon Sep 17 00:00:00 2001 From: Matthew Parker Date: Tue, 3 Sep 2024 19:17:07 +0100 Subject: [PATCH 3/3] added tests --- ...tServerTests.CreateEmailPasswordSession.cs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.CreateEmailPasswordSession.cs diff --git a/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.CreateEmailPasswordSession.cs b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.CreateEmailPasswordSession.cs new file mode 100644 index 00000000..0ca83383 --- /dev/null +++ b/tests/PinguApps.Appwrite.Server.Tests/Servers/Account/AccountServerTests.CreateEmailPasswordSession.cs @@ -0,0 +1,77 @@ +using System.Net; +using PinguApps.Appwrite.Shared.Requests; +using PinguApps.Appwrite.Shared.Tests; +using RichardSzalay.MockHttp; + +namespace PinguApps.Appwrite.Server.Tests.Servers.Account; +public partial class AccountServerTests +{ + [Fact] + public async Task CreateEmailPasswordSession_ShouldReturnSuccess_WhenApiCallSucceeds() + { + // Arrange + var request = new CreateEmailPasswordSessionRequest() + { + Email = "email@example.com", + Password = "Password" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/sessions/email") + .ExpectedHeaders() + .WithJsonContent(request) + .Respond(Constants.AppJson, Constants.SessionResponse); + + // Act + var result = await _appwriteServer.Account.CreateEmailPasswordSession(request); + + // Assert + Assert.True(result.Success); + } + + [Fact] + public async Task CreateEmailPasswordSession_ShouldHandleException_WhenApiCallFails() + { + // Arrange + var request = new CreateEmailPasswordSessionRequest() + { + Email = "email@example.com", + Password = "Password" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/sessions/email") + .ExpectedHeaders() + .WithJsonContent(request) + .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); + + // Act + var result = await _appwriteServer.Account.CreateEmailPasswordSession(request); + + // Assert + Assert.True(result.IsError); + Assert.True(result.IsAppwriteError); + } + + [Fact] + public async Task CreateEmailPasswordSession_ShouldReturnErrorResponse_WhenExceptionOccurs() + { + // Arrange + var request = new CreateEmailPasswordSessionRequest() + { + Email = "email@example.com", + Password = "Password" + }; + + _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/sessions/email") + .ExpectedHeaders() + .WithJsonContent(request) + .Throw(new HttpRequestException("An error occurred")); + + // Act + var result = await _appwriteServer.Account.CreateEmailPasswordSession(request); + + // Assert + Assert.False(result.Success); + Assert.True(result.IsInternalError); + Assert.Equal("An error occurred", result.Result.AsT2.Message); + } +}