// Copyright (c) 2020 Tudor Stanciu using MediatR; using Microsoft.Extensions.DependencyInjection; using System; using System.Threading.Tasks; using Tuitio.Application.CommandHandlers; using Tuitio.Application.Tests.Fixtures; using Tuitio.PublishedLanguage.Constants; using Tuitio.PublishedLanguage.Dto; using Xunit; namespace Tuitio.Application.Tests { public class CommandHandlerTests : IClassFixture, IDisposable { private readonly IServiceScope _tuitioScope; private readonly IMediator _mediator; public CommandHandlerTests(DependencyInjectionFixture fixture) { _tuitioScope = fixture.ServiceProvider.GetRequiredService().CreateScope(); _mediator = _tuitioScope.ServiceProvider.GetRequiredService(); } public void Dispose() { _tuitioScope.Dispose(); } [Fact] public async Task AccountLoginHandler_Handle_Success() { // Arrange var userName = "tuitio.user"; var password = "pass123"; var command = new AccountLoginHandler.Command(userName, password); // Act var result = await _mediator.Send(command); // Assert Assert.NotNull(result); Assert.NotNull(result.Result); Assert.Null(result.Error); Assert.NotEmpty(result.Result.Token); Assert.True(result.Result.ExpiresIn > 0, "Token expiration must be a positive number."); } [Fact] public async Task AccountLoginHandler_Handle_Failed() { // Arrange var userName = "tuitio.user"; var password = "wrong_password"; var command = new AccountLoginHandler.Command(userName, password); // Act var result = await _mediator.Send(command); // Assert Assert.NotNull(result); Assert.Null(result.Result); Assert.NotNull(result.Error); Assert.NotEmpty(result.Error); Assert.Equal(EnvelopeError.BAD_CREDENTIALS, result.Error); } [Fact] public async Task AccountLogoutHandler_Handle_Success() { // Arrange var userName = "tuitio.user"; var password = "pass123"; var loginCommand = new AccountLoginHandler.Command(userName, password); var loginResult = await _mediator.Send(loginCommand); var logoutCommand = new AccountLogoutHandler.Command(loginResult.Result.Token); // Act Envelope logoutResult; using (var scope = _tuitioScope.ServiceProvider.CreateScope()) { var newMediator = scope.ServiceProvider.GetRequiredService(); logoutResult = await newMediator.Send(logoutCommand); } // Assert Assert.NotNull(logoutResult); Assert.NotNull(logoutResult.Result); Assert.Null(logoutResult.Error); Assert.Equal(userName, logoutResult.Result.UserName); Assert.True((DateTime.UtcNow - logoutResult.Result.LogoutDate).TotalMinutes <= 1, "Logout date must be within the last minute."); } [Fact] public async Task AccountLogoutHandler_Handle_Failed() { // Arrange var unauthenticatedToken = "unauthenticated-token"; var command = new AccountLogoutHandler.Command(unauthenticatedToken); // Act var result = await _mediator.Send(command); // Assert Assert.NotNull(result); Assert.Null(result.Result); Assert.NotNull(result.Error); Assert.NotEmpty(result.Error); Assert.Equal(EnvelopeError.UNAUTHENTICATED, result.Error); } [Fact] public async Task AuthorizationHandler_Handle_Success() { // Arrange var userName = "tuitio.user"; var password = "pass123"; var loginCommand = new AccountLoginHandler.Command(userName, password); var loginResult = await _mediator.Send(loginCommand); var authorizationCommand = new AuthorizationHandler.Command(loginResult.Result.Token); // Act var authorizationResult = await _mediator.Send(authorizationCommand); // Assert Assert.NotNull(authorizationResult); Assert.NotNull(authorizationResult.Result); Assert.Null(authorizationResult.Error); Assert.Equal(userName, authorizationResult.Result.UserName); Assert.NotNull(authorizationResult.Result.SecurityStamp); Assert.NotNull(authorizationResult.Result.LockStamp); Assert.True(authorizationResult.Result.TokenId != Guid.Empty, "Token id cannot be an empty guid."); Assert.True(authorizationResult.Result.ExpiresIn > 0, "Token expiration must be a positive number."); } [Fact] public async Task AuthorizationHandler_Handle_Failed() { // Arrange var unauthorizedToken = "unauthorized-token"; var command = new AuthorizationHandler.Command(unauthorizedToken); // Act var result = await _mediator.Send(command); // Assert Assert.NotNull(result); Assert.Null(result.Result); Assert.NotNull(result.Error); Assert.NotEmpty(result.Error); Assert.Equal(EnvelopeError.UNAUTHORIZED, result.Error); } } }