From 2092848064c04564904caacd9c53f1bad51d7fc4 Mon Sep 17 00:00:00 2001 From: zysim Date: Thu, 26 Oct 2023 17:47:51 +0800 Subject: [PATCH] Send email on register --- .../Features/Users/RegistrationTests.cs | 24 +++++++++++ .../Controllers/AccountController.cs | 43 ++++++++++++------- LeaderboardBackend/openapi.json | 3 ++ 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/LeaderboardBackend.Test/Features/Users/RegistrationTests.cs b/LeaderboardBackend.Test/Features/Users/RegistrationTests.cs index 0c319192..ed8e5577 100644 --- a/LeaderboardBackend.Test/Features/Users/RegistrationTests.cs +++ b/LeaderboardBackend.Test/Features/Users/RegistrationTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -7,9 +8,12 @@ using LeaderboardBackend.Models.Entities; using LeaderboardBackend.Models.Requests; using LeaderboardBackend.Models.ViewModels; +using LeaderboardBackend.Services; using LeaderboardBackend.Test.Fixtures; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; +using Moq; using NUnit.Framework; namespace LeaderboardBackend.Test.Features.Users; @@ -65,6 +69,26 @@ public async Task Register_InvalidEmailFormat_ReturnsErrorCode() }); } + [Test] + public async Task Register_EmailFailedToSend_ReturnsErrorCode() + { + Mock emailSenderMock = new(); + emailSenderMock.Setup(x => + x.EnqueueEmailAsync(It.IsAny(), It.IsAny(), It.IsAny()) + ).Throws(new Exception()); + + HttpClient client = _factory.WithWebHostBuilder(builder => + builder.ConfigureTestServices(services => + services.AddScoped(_ => emailSenderMock.Object) + ) + ).CreateClient(); + RegisterRequest request = _registerReqFaker.Generate(); + + HttpResponseMessage res = await client.PostAsJsonAsync(Routes.REGISTER, request); + + res.Should().HaveStatusCode(HttpStatusCode.InternalServerError); + } + [Test] public async Task Register_InvalidUsername_ReturnsUsernameFormatErrorCode() { diff --git a/LeaderboardBackend/Controllers/AccountController.cs b/LeaderboardBackend/Controllers/AccountController.cs index def0e517..f579e9c8 100644 --- a/LeaderboardBackend/Controllers/AccountController.cs +++ b/LeaderboardBackend/Controllers/AccountController.cs @@ -27,6 +27,7 @@ public AccountController(IUserService userService) /// /// The `RegisterRequest` instance from which register the `User`. /// + /// The IConfirmationService dependency. /// The `User` was registered and returned successfully. /// /// The request was malformed. @@ -54,27 +55,37 @@ public AccountController(IUserService userService) [ApiConventionMethod(typeof(Conventions), nameof(Conventions.PostAnon))] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status409Conflict, Type = typeof(ValidationProblemDetails))] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] [FeatureGate(Features.ACCOUNT_REGISTRATION)] - public async Task> Register([FromBody] RegisterRequest request) + public async Task> Register( + [FromBody] RegisterRequest request, + [FromServices] IAccountConfirmationService confirmationService + ) { CreateUserResult result = await _userService.CreateUser(request); - return result.Match>( - user => CreatedAtAction(nameof(UsersController.GetUserById), "Users", - new { id = user.Id }, UserViewModel.MapFrom(user)), - conflicts => - { - if (conflicts.Username) - { - ModelState.AddModelError(nameof(request.Username), "UsernameTaken"); - } - if (conflicts.Email) - { - ModelState.AddModelError(nameof(request.Email), "EmailAlreadyUsed"); - } + if (result.TryPickT0(out User user, out CreateUserConflicts conflicts)) + { + CreateConfirmationResult r = await confirmationService.CreateConfirmationAndSendEmail(user); + + return r.Match( + confirmation => Ok(), + badRole => StatusCode(StatusCodes.Status500InternalServerError), + emailFailed => StatusCode(StatusCodes.Status500InternalServerError) + ); + } + + if (conflicts.Username) + { + ModelState.AddModelError(nameof(request.Username), "UsernameTaken"); + } + + if (conflicts.Email) + { + ModelState.AddModelError(nameof(request.Email), "EmailAlreadyUsed"); + } - return Conflict(new ValidationProblemDetails(ModelState)); - }); + return Conflict(new ValidationProblemDetails(ModelState)); } /// diff --git a/LeaderboardBackend/openapi.json b/LeaderboardBackend/openapi.json index fa279b85..a3bd966c 100644 --- a/LeaderboardBackend/openapi.json +++ b/LeaderboardBackend/openapi.json @@ -42,6 +42,9 @@ } } }, + "500": { + "description": "Server Error" + }, "400": { "description": "The request was malformed." },