Reorganize root folder structure: Remove apps layer layer

This commit is contained in:
Халимов Рустам
2026-03-19 22:22:45 +03:00
parent fb252f9d87
commit 11ebbc853b
296 changed files with 139 additions and 139 deletions
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="FluentAssertions" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Identity\Knot.Modules.Identity.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,87 @@
using FluentAssertions;
using NSubstitute;
using Knot.Modules.Identity.Application.Abstractions;
using Knot.Modules.Identity.Application.Users.Login;
using Knot.Modules.Identity.Domain;
using Knot.Shared.Kernel;
using Knot.Modules.Identity.Application.Users.Auth;
using Xunit;
using System.Threading;
using System.Threading.Tasks;
namespace Knot.Modules.Identity.UnitTests;
public class LoginUserCommandHandlerTests
{
private readonly IUserRepository _userRepository;
private readonly IJwtTokenProvider _tokenProvider;
private readonly LoginUserCommandHandler _handler;
public LoginUserCommandHandlerTests()
{
_userRepository = Substitute.For<IUserRepository>();
_tokenProvider = Substitute.For<IJwtTokenProvider>();
_handler = new LoginUserCommandHandler(_userRepository, _tokenProvider);
}
[Fact]
public async Task Handle_ShouldReturnToken_WhenCredentialsAreValid()
{
// Arrange
var password = "password123";
var passwordHash = BCrypt.Net.BCrypt.HashPassword(password);
var user = User.Create("testuser", passwordHash, "Test User", null, null);
var command = new LoginUserCommand("testuser", password);
_userRepository.GetByUsernameAsync(command.Username, Arg.Any<CancellationToken>())
.Returns(user);
_tokenProvider.Generate(user).Returns("valid-jwt-token");
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Token.Should().Be("valid-jwt-token");
result.Value.User.Username.Should().Be("testuser");
}
[Fact]
public async Task Handle_ShouldReturnFailure_WhenUserDoesNotExist()
{
// Arrange
var command = new LoginUserCommand("nonexistent", "password123");
_userRepository.GetByUsernameAsync(command.Username, Arg.Any<CancellationToken>())
.Returns((User)null!);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Code.Should().Be(IdentityErrors.IdentityInvalidCredentials.Code);
}
[Fact]
public async Task Handle_ShouldReturnFailure_WhenPasswordIsInvalid()
{
// Arrange
var correctPassword = "correctPassword";
var passwordHash = BCrypt.Net.BCrypt.HashPassword(correctPassword);
var user = User.Create("testuser", passwordHash, "Test User", null, null);
var command = new LoginUserCommand("testuser", "wrongPassword");
_userRepository.GetByUsernameAsync(command.Username, Arg.Any<CancellationToken>())
.Returns(user);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Code.Should().Be(IdentityErrors.IdentityInvalidCredentials.Code);
}
}
@@ -0,0 +1,95 @@
using FluentAssertions;
using NSubstitute;
using Knot.Modules.Identity.Application.Abstractions;
using Knot.Modules.Identity.Application.Users.Register;
using Knot.Modules.Identity.Domain;
using Knot.Shared.Kernel;
using Knot.Shared.Kernel.Configuration;
using Xunit;
using System.Threading;
using System.Threading.Tasks;
namespace Knot.Modules.Identity.UnitTests;
public class RegisterUserCommandHandlerTests
{
private readonly IUserRepository _userRepository;
private readonly IIdentityUnitOfWork _unitOfWork;
private readonly ISettingsService _settings;
private readonly IJwtTokenProvider _tokenProvider;
private readonly RegisterUserCommandHandler _handler;
public RegisterUserCommandHandlerTests()
{
_userRepository = Substitute.For<IUserRepository>();
_unitOfWork = Substitute.For<IIdentityUnitOfWork>();
_settings = Substitute.For<ISettingsService>();
_tokenProvider = Substitute.For<IJwtTokenProvider>();
var options = new SystemSettingsDto { EnableRegistration = true };
_settings.Current.Returns(options);
_handler = new RegisterUserCommandHandler(_userRepository, _unitOfWork, _settings, _tokenProvider);
}
[Fact]
public async Task Handle_ShouldReturnSuccess_WhenRegistrationIsSuccessful()
{
// Arrange
var command = new RegisterUserCommand("testuser", "password123", "Test User", "test@example.com", "My bio");
_userRepository.IsUsernameUniqueAsync(command.Username, Arg.Any<CancellationToken>())
.Returns(true);
_tokenProvider.Generate(Arg.Any<User>()).Returns("my-token");
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Token.Should().Be("my-token");
_userRepository.Received(1).Add(Arg.Is<User>(u =>
u.Username == command.Username &&
u.DisplayName == command.DisplayName &&
u.Email == command.Email));
await _unitOfWork.Received(1).SaveChangesAsync(Arg.Any<CancellationToken>());
}
[Fact]
public async Task Handle_ShouldReturnFailure_WhenUsernameIsNotUnique()
{
// Arrange
var command = new RegisterUserCommand("duplicate", "password123", "Test User", null, null);
_userRepository.IsUsernameUniqueAsync(command.Username, Arg.Any<CancellationToken>())
.Returns(false);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Code.Should().Be(IdentityErrors.IdentityUsernameNotUnique.Code);
_userRepository.DidNotReceive().Add(Arg.Any<User>());
await _unitOfWork.DidNotReceive().SaveChangesAsync(Arg.Any<CancellationToken>());
}
[Fact]
public async Task Handle_ShouldReturnFailure_WhenRegistrationDisabled()
{
// Arrange
_settings.Current.Returns(new SystemSettingsDto { EnableRegistration = false });
var command = new RegisterUserCommand("testuser", "password123", "Test User", null, null);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Code.Should().Be(IdentityErrors.IdentityRegistrationDisabled.Code);
_userRepository.DidNotReceive().Add(Arg.Any<User>());
await _unitOfWork.DidNotReceive().SaveChangesAsync(Arg.Any<CancellationToken>());
}
}