using e_suite.API.Common.models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; namespace eSuite.API.UnitTests.Controllers.AccountControllerUnitTests; [TestFixture] public class LoginPostUnitTests : AccountControllerTestBase { [SetUp] public override async Task Setup() { await base.Setup(); } [Test] public async Task LoginPost_WhenLoginPasswordEmptyAndNotSingleSignOn_ReturnsLoginViewWithEmptyModel() { //Arrange var login = new Login { Email = "Test@test.test" }; //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var viewResult = response as ViewResult; Assert.That(viewResult?.ViewName, Is.EqualTo("Login")); Assert.That(viewResult?.Model, Is.TypeOf()); var actualLogin = viewResult?.Model as Login; Assert.That(actualLogin, Is.EqualTo(login)); } [Test] public async Task LoginPost_WhenSingleSignOnUserPresentsEmail_ReturnsRedirectsToSingleSignOnUrl() { //Arrange var login = new Login { Email = "Test@test.test" }; var ssoUrl = "http://test.test/login"; _singleSignOnMock.Setup(x => x.StartSingleSignOn(login.Email, It.IsAny())) .ReturnsAsync(() => ssoUrl); //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var redirectResult = response as RedirectResult; Assert.That(redirectResult?.Url, Is.EqualTo(ssoUrl)); } [Test] public async Task LoginPost_WhenForgotPassword_UserManagerForgotPasswordCalled() { //Arrange Login? login = new Login { Email = "TestUser@Test.test", ForgotPassword = true }; //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var viewResult = response as ViewResult; Assert.That(viewResult?.ViewName, Is.EqualTo("Login")); Assert.That(viewResult?.Model, Is.TypeOf()); var actualLogin = viewResult?.Model as Login; Assert.That(actualLogin, Is.EqualTo(login)); _userManagerMock.Verify(x => x.ForgotPassword(login.Email, It.IsAny()), Times.Once); } [Test] public async Task LoginPost_WhenForgotPasswordButPasswordHasRubbish_UserManagerForgotPasswordCalled() { //Arrange Login? login = new Login { Email = "TestUser@Test.test", Password = "A", ForgotPassword = true }; //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var viewResult = response as ViewResult; Assert.That(viewResult?.ViewName, Is.EqualTo("Login")); Assert.That(viewResult?.Model, Is.TypeOf()); var actualLogin = viewResult?.Model as Login; Assert.That(actualLogin, Is.EqualTo(login)); _userManagerMock.Verify(x => x.ForgotPassword(login.Email, It.IsAny()), Times.Once); } [Test] public async Task LoginPost_WhenPasswordPresentAndCorrect_CreatesSessionCookieAndRedirectToRoot() { //Arrange Login? login = new Login { Email = "TestUser@Test.test", Password = "SuperSecret" }; var loginResponse = new LoginResponse { Result = LoginResult.Success, Token = "Valid JSON Web Token" }; _userManagerMock.Setup(x => x.Login(login, It.IsAny())).ReturnsAsync(() => loginResponse); //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var redirectResult = response as RedirectResult; Assert.That(redirectResult?.Url, Is.EqualTo("/")); _cookieManagerMock.Verify( x => x.CreateSessionCookie(It.IsAny(), loginResponse), Times.Once); } [TestCase(LoginResult.EmailNotConfirmed)] [TestCase(LoginResult.TwoFactorAuthenticationRemovalRequested)] [TestCase(LoginResult.TwoFactorAuthenticationCodeRequired)] [TestCase(LoginResult.TwoFactorAuthenticationCodeIncorrect)] public async Task LoginPost_WhenNonSsoLoginNotCompleted_ReturnsUpdatedView( LoginResult loginResult) { //Arrange Login? login = new Login { Email = "TestUser@Test.test", Password = "SuperSecret" }; var loginResponse = new LoginResponse { Result = loginResult }; _userManagerMock.Setup(x => x.Login(login, It.IsAny())).ReturnsAsync(() => loginResponse); //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var viewResult = response as ViewResult; Assert.That(viewResult?.ViewName, Is.EqualTo("Login")); Assert.That(viewResult?.Model, Is.TypeOf()); var actualLogin = viewResult?.Model as Login; Assert.That(actualLogin, Is.EqualTo(login)); } [Test] public async Task LoginPost_WhenLoginFails_LogsBadLoginAttemptAndReturnsUpdatedView() { //Arrange Login? login = new Login { Email = "TestUser@Test.test", Password = "SuperSecret" }; var loginResponse = new LoginResponse { Result = LoginResult.Failed }; _userManagerMock.Setup(x => x.Login(login, It.IsAny())).ReturnsAsync(() => loginResponse); //Act var response = await _accountController.LoginPost(login, CancellationToken.None); //Assert Assert.That(response, Is.TypeOf()); var viewResult = response as ViewResult; Assert.That(viewResult?.ViewName, Is.EqualTo("Login")); Assert.That(viewResult?.Model, Is.TypeOf()); var actualLogin = viewResult?.Model as Login; Assert.That(actualLogin, Is.EqualTo(login)); _sentinelMock.Verify( x => x.LogBadRequest(_accountController, It.IsAny()), Times.Once); } }