From 7cca9d9ddf5e47699043898ee709c3b9c9c8eda8 Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Tue, 14 Mar 2023 01:06:09 +0200 Subject: [PATCH] Added Tuitio.Wrapper.Tests --- Tuitio.sln | 9 +- src/Tuitio.Wrapper/Properties/AssemblyInfo.cs | 5 + .../CommandHandlerTests.cs | 12 +-- .../Stubs/HttpMessageHandlerStub.cs | 30 ++++++ .../Tuitio.Wrapper.Tests.csproj | 20 ++++ .../TuitioServiceTests.cs | 95 +++++++++++++++++++ 6 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 src/Tuitio.Wrapper/Properties/AssemblyInfo.cs create mode 100644 test/UnitTests/Tuitio.Wrapper.Tests/Stubs/HttpMessageHandlerStub.cs create mode 100644 test/UnitTests/Tuitio.Wrapper.Tests/Tuitio.Wrapper.Tests.csproj create mode 100644 test/UnitTests/Tuitio.Wrapper.Tests/TuitioServiceTests.cs diff --git a/Tuitio.sln b/Tuitio.sln index ecb6fe1..902811e 100644 --- a/Tuitio.sln +++ b/Tuitio.sln @@ -34,7 +34,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{063D24C5-0 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{ECDF52C7-A2AA-4070-8FCF-A79A58CFA5F6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuitio.Application.Tests", "test\UnitTests\Tuitio.Application.Tests\Tuitio.Application.Tests.csproj", "{11F38E16-13BA-43FB-89FD-CD863FF06BA8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tuitio.Application.Tests", "test\UnitTests\Tuitio.Application.Tests\Tuitio.Application.Tests.csproj", "{11F38E16-13BA-43FB-89FD-CD863FF06BA8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuitio.Wrapper.Tests", "test\UnitTests\Tuitio.Wrapper.Tests\Tuitio.Wrapper.Tests.csproj", "{89D54F51-6ABB-4FE2-B060-A60826B6DE1E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -70,6 +72,10 @@ Global {11F38E16-13BA-43FB-89FD-CD863FF06BA8}.Debug|Any CPU.Build.0 = Debug|Any CPU {11F38E16-13BA-43FB-89FD-CD863FF06BA8}.Release|Any CPU.ActiveCfg = Release|Any CPU {11F38E16-13BA-43FB-89FD-CD863FF06BA8}.Release|Any CPU.Build.0 = Release|Any CPU + {89D54F51-6ABB-4FE2-B060-A60826B6DE1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89D54F51-6ABB-4FE2-B060-A60826B6DE1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89D54F51-6ABB-4FE2-B060-A60826B6DE1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89D54F51-6ABB-4FE2-B060-A60826B6DE1E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,6 +89,7 @@ Global {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95} = {5A8FF505-3E4D-4258-BC3E-CACD74A7B98C} {ECDF52C7-A2AA-4070-8FCF-A79A58CFA5F6} = {063D24C5-0823-48D6-A5DD-974CE38F8E71} {11F38E16-13BA-43FB-89FD-CD863FF06BA8} = {ECDF52C7-A2AA-4070-8FCF-A79A58CFA5F6} + {89D54F51-6ABB-4FE2-B060-A60826B6DE1E} = {ECDF52C7-A2AA-4070-8FCF-A79A58CFA5F6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E93DC46D-9C55-4A05-B299-497CDD90747E} diff --git a/src/Tuitio.Wrapper/Properties/AssemblyInfo.cs b/src/Tuitio.Wrapper/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b631851 --- /dev/null +++ b/src/Tuitio.Wrapper/Properties/AssemblyInfo.cs @@ -0,0 +1,5 @@ +// Copyright (c) 2020 Tudor Stanciu + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Tuitio.Wrapper.Tests")] diff --git a/test/UnitTests/Tuitio.Application.Tests/CommandHandlerTests.cs b/test/UnitTests/Tuitio.Application.Tests/CommandHandlerTests.cs index 167ed04..16d3efd 100644 --- a/test/UnitTests/Tuitio.Application.Tests/CommandHandlerTests.cs +++ b/test/UnitTests/Tuitio.Application.Tests/CommandHandlerTests.cs @@ -37,14 +37,14 @@ namespace Tuitio.Application.Tests var command = new AccountLoginHandler.Command(userName, password); // Act - var result = await _mediator.Send(command); + var loginResult = 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."); + Assert.NotNull(loginResult); + Assert.NotNull(loginResult.Result); + Assert.Null(loginResult.Error); + Assert.NotEmpty(loginResult.Result.Token); + Assert.True(loginResult.Result.ExpiresIn > 0, "Token expiration must be a positive number."); } [Fact] diff --git a/test/UnitTests/Tuitio.Wrapper.Tests/Stubs/HttpMessageHandlerStub.cs b/test/UnitTests/Tuitio.Wrapper.Tests/Stubs/HttpMessageHandlerStub.cs new file mode 100644 index 0000000..e1c2116 --- /dev/null +++ b/test/UnitTests/Tuitio.Wrapper.Tests/Stubs/HttpMessageHandlerStub.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Tuitio.PublishedLanguage.Dto; + +namespace Tuitio.Wrapper.Tests.Stubs +{ + public class HttpMessageHandlerStub : HttpMessageHandler where T : class + { + private readonly Envelope _response; + + public HttpMessageHandlerStub(Envelope response) + { + _response = response ?? throw new ArgumentNullException(nameof(response)); + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var httpResponseMessage = new HttpResponseMessage() + { + StatusCode = System.Net.HttpStatusCode.OK, + Content = new StringContent(JsonConvert.SerializeObject(_response)) + }; + + return Task.FromResult(httpResponseMessage); + } + } +} diff --git a/test/UnitTests/Tuitio.Wrapper.Tests/Tuitio.Wrapper.Tests.csproj b/test/UnitTests/Tuitio.Wrapper.Tests/Tuitio.Wrapper.Tests.csproj new file mode 100644 index 0000000..6964cf2 --- /dev/null +++ b/test/UnitTests/Tuitio.Wrapper.Tests/Tuitio.Wrapper.Tests.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/test/UnitTests/Tuitio.Wrapper.Tests/TuitioServiceTests.cs b/test/UnitTests/Tuitio.Wrapper.Tests/TuitioServiceTests.cs new file mode 100644 index 0000000..399d5c4 --- /dev/null +++ b/test/UnitTests/Tuitio.Wrapper.Tests/TuitioServiceTests.cs @@ -0,0 +1,95 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Tuitio.PublishedLanguage.Dto; +using Tuitio.Wrapper.Services; +using Tuitio.Wrapper.Tests.Stubs; +using Xunit; + +namespace Tuitio.Wrapper.Tests +{ + public class TuitioServiceTests + { + private readonly Models.ServiceConfiguration _serviceConfiguration; + public TuitioServiceTests() + { + _serviceConfiguration = new Models.ServiceConfiguration("http://localhost:5063"); + } + + [Fact] + public async Task Login_ShouldReturnAValidToken() + { + // Arrange + var loginResultMock = new AccountLoginResult("dGVzdA==", 600000); + var envelopeMock = Envelope.Success(loginResultMock); + var httpMessageHandler = new HttpMessageHandlerStub(envelopeMock); + var httpClient = new HttpClient(httpMessageHandler); + var service = new TuitioService(httpClient, _serviceConfiguration); + + // Act + var loginResult = await service.Login("tuitio.user", "pass123"); + + // Assert + Assert.NotNull(loginResult); + Assert.NotNull(loginResult.Result); + Assert.Null(loginResult.Error); + Assert.NotEmpty(loginResult.Result.Token); + Assert.True(loginResult.Result.ExpiresIn > 0, "Token expiration must be a positive number."); + } + + [Fact] + public async Task Authorize_ShouldReturnAValidToken() + { + // Arrange + var authorizationResultMock = new AuthorizationResult() + { + TokenId = Guid.NewGuid(), + UserId = 0, + UserName = "test.tuitio", + CreatedAt = DateTime.Now, + SecurityStamp = Guid.NewGuid().ToString(), + LockStamp = "lock-stamp", + ExpiresIn = 600000 + }; + + var envelopeMock = Envelope.Success(authorizationResultMock); + var httpMessageHandler = new HttpMessageHandlerStub(envelopeMock); + var httpClient = new HttpClient(httpMessageHandler); + var service = new TuitioService(httpClient, _serviceConfiguration); + + // Act + var authorizationResult = await service.Authorize("tuitio-token"); + + // Assert + Assert.NotNull(authorizationResult); + Assert.NotNull(authorizationResult.Result); + Assert.Null(authorizationResult.Error); + Assert.Equal(authorizationResultMock.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 Logout_ShouldSuccessfullyLogoutTheUser() + { + // Arrange + var logoutResultMock = new AccountLogoutResult(1, "test.tuitio", DateTime.Now); + var envelopeMock = Envelope.Success(logoutResultMock); + var httpMessageHandler = new HttpMessageHandlerStub(envelopeMock); + var httpClient = new HttpClient(httpMessageHandler); + var service = new TuitioService(httpClient, _serviceConfiguration); + + // Act + var logoutResult = await service.Logout("tuitio-token"); + + // Assert + Assert.NotNull(logoutResult); + Assert.NotNull(logoutResult.Result); + Assert.Null(logoutResult.Error); + Assert.Equal(logoutResultMock.UserName, logoutResult.Result.UserName); + Assert.True((DateTime.UtcNow - logoutResult.Result.LogoutDate).TotalMinutes <= 1, "Logout date must be within the last minute."); + } + } +} \ No newline at end of file