Сборка бэк

This commit is contained in:
Халимов Рустам
2026-03-27 15:45:34 +03:00
parent 16978c423c
commit 11f2b232a3
135 changed files with 2162 additions and 725 deletions
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Shared\IntegrationTests.Shared\Knot.IntegrationTests.Shared.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Admin\Knot.Modules.Admin.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Admin\Knot.Modules.Admin.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Admin\Knot.Modules.Admin.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
</ItemGroup>
</Project>
@@ -1,5 +1,5 @@
using FluentAssertions;
using Host.Application.Admin.Commands;
using Knot.Modules.Admin.Application.Admin.Commands;
using Knot.Modules.Auth.Application.Abstractions;
using Knot.Modules.Auth.Domain;
using Knot.Shared.Kernel;
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -10,13 +10,14 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -23,9 +23,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Identity\Knot.Modules.Auth.csproj" />
<ProjectReference Include="..\..\src\Modules\Auth\Knot.Modules.Auth.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Auth\Knot.Modules.Auth.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -23,9 +23,11 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Chats\Knot.Modules.Conversations.csproj" />
<ProjectReference Include="..\..\src\Modules\Messaging\Knot.Modules.Messaging.csproj" />
<ProjectReference Include="..\..\src\Modules\Conversations\Knot.Modules.Conversations.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Chats\Knot.Modules.Conversations.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Messaging\Knot.Modules.Messaging.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Conversations\Knot.Modules.Conversations.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -12,6 +12,8 @@ using Knot.Modules.Conversations.Domain;
using Knot.Modules.Messaging.Domain;
using Knot.Modules.Conversations.Application.Abstractions;
using Knot.Modules.Conversations.Application.Messages.Send;
using Knot.Modules.Settings.Application.Settings.Abstractions;
using Knot.Modules.Settings.Application.Settings.DTOs;
namespace Knot.Modules.Conversations.UnitTests.Messages;
@@ -21,6 +23,7 @@ public class SendMessageCommandHandlerTests
private readonly IMessageRepository _messageRepository;
private readonly IChatsUnitOfWork _unitOfWork;
private readonly IMediator _mediator;
private readonly IMessagesSettings _messagesSettings;
private readonly SendMessageCommandHandler _handler;
public SendMessageCommandHandlerTests()
@@ -29,8 +32,12 @@ public class SendMessageCommandHandlerTests
_messageRepository = Substitute.For<IMessageRepository>();
_unitOfWork = Substitute.For<IChatsUnitOfWork>();
_mediator = Substitute.For<IMediator>();
_messagesSettings = Substitute.For<IMessagesSettings>();
var config = new Knot.Modules.Settings.Application.Settings.DTOs.MessagesConfig();
_messagesSettings.Current.Returns(config);
_handler = new SendMessageCommandHandler(_chatRepository, _messageRepository, _unitOfWork, _mediator);
_handler = new SendMessageCommandHandler(_chatRepository, _messageRepository, _unitOfWork, _mediator, _messagesSettings);
}
[Fact]
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Federation\Knot.Modules.Federation.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Federation\Knot.Modules.Federation.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Klipy\Knot.Modules.Klipy.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Klipy\Knot.Modules.Klipy.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,42 +0,0 @@
using FluentAssertions;
using Knot.Modules.Conversations.Application.Chats.Commands.CreatePersonalChat;
using Knot.Modules.Conversations.Domain;
using Knot.Modules.Conversations.Application.Abstractions;
using Knot.Shared.Kernel;
using NSubstitute;
using Xunit;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Knot.Modules.Conversations.UnitTests;
public class CreatePersonalChatCommandHandlerTests
{
private readonly IChatRepository _chatRepository;
private readonly IChatsUnitOfWork _unitOfWork;
private readonly CreatePersonalChatCommandHandler _handler;
public CreatePersonalChatCommandHandlerTests()
{
_chatRepository = Substitute.For<IChatRepository>();
_unitOfWork = Substitute.For<IChatsUnitOfWork>();
_handler = new CreatePersonalChatCommandHandler(_chatRepository, _unitOfWork);
}
[Fact]
public async Task Handle_ShouldReturnError_WhenChatAlreadyExists()
{
// Arrange
var command = new CreatePersonalChatCommand(Guid.NewGuid(), Guid.NewGuid());
_chatRepository.GetPersonalChatAsync(command.InitiatorId, command.TargetUserId, Arg.Any<CancellationToken>())
.Returns(PersonalChat.Create(command.InitiatorId, command.TargetUserId));
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Should().Be(ChatErrors.PersonalChatAlreadyExists);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -17,6 +17,8 @@
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Relations\Knot.Modules.Relations.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Relations\Knot.Modules.Relations.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,88 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using Testcontainers.PostgreSql;
using Testcontainers.MongoDb;
using Xunit;
using System.Threading.Tasks;
using System.Collections.Generic;
using Knot.Shared.Kernel;
using NSubstitute;
namespace Knot.IntegrationTests;
public abstract class BaseIntegrationTest : IAsyncLifetime
{
protected readonly PostgreSqlContainer _postgresContainer = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.Build();
protected readonly MongoDbContainer _mongoContainer = new MongoDbBuilder()
.WithImage("mongo:6.0")
.Build();
protected HttpClient _client;
protected WebApplicationFactory<Program> _factory;
protected readonly Guid _userId = Guid.NewGuid();
protected readonly IUserContext _userContextMock = Substitute.For<IUserContext>();
public virtual async Task InitializeAsync()
{
await _postgresContainer.StartAsync();
await _mongoContainer.StartAsync();
_userContextMock.UserId.Returns(_userId);
_userContextMock.IsAuthenticated.Returns(true);
_factory = new IntegrationTestWebApplicationFactory(
_postgresContainer.GetConnectionString(),
_mongoContainer.GetConnectionString(),
_userContextMock);
_client = _factory.CreateClient();
}
public virtual async Task DisposeAsync()
{
await _postgresContainer.StopAsync();
await _mongoContainer.StopAsync();
_factory?.Dispose();
_client?.Dispose();
}
private class IntegrationTestWebApplicationFactory : WebApplicationFactory<Program>
{
private readonly string _pgConnectionString;
private readonly string _mongoConnectionString;
private readonly IUserContext _userContext;
public IntegrationTestWebApplicationFactory(string pg, string mongo, IUserContext userContext)
{
_pgConnectionString = pg;
_mongoConnectionString = mongo;
_userContext = userContext;
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((context, config) =>
{
config.AddInMemoryCollection(new Dictionary<string, string?>
{
["ConnectionStrings:DefaultConnection"] = _pgConnectionString,
["ConnectionStrings:MongoConnection"] = _mongoConnectionString,
["DATABASE_URL"] = _pgConnectionString,
["MONGO_CONNECTION"] = _mongoConnectionString,
["KNOT_MASTER_ENCRYPTION_KEY"] = "TestEncryptionKey_32CharactersLong!"
});
});
builder.ConfigureTestServices(services => {
services.AddScoped(_ => _userContext);
});
}
}
}
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="FluentAssertions" Version="8.9.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.5" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="10.0.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="Respawn" Version="7.0.0" />
<PackageReference Include="Testcontainers.MongoDb" Version="4.11.0" />
<PackageReference Include="Testcontainers.PostgreSql" Version="4.11.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Host\Host.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Infrastructure\Knot.Shared.Infrastructure.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Storage\Knot.Modules.Storage.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Storage\Knot.Modules.Storage.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Shared\IntegrationTests.Shared\Knot.IntegrationTests.Shared.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Stories\Knot.Modules.Stories.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,34 @@
using Knot.IntegrationTests;
using FluentAssertions;
using Knot.Modules.Stories.Application.Stories.Commands.CreateStory;
using Knot.Shared.Kernel;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using System.Net;
using System.Net.Http.Json;
using Xunit;
using System;
using System.Threading.Tasks;
namespace Knot.IntegrationTests.Stories;
public class StoriesTests : BaseIntegrationTest
{
[Fact]
public async Task CreateStory_ShouldReturnOk_WhenValidRequest()
{
// Arrange
var request = new CreateStoryRequest("Text", null, "Hello Integration Test", null);
// Act
var response = await _client.PostAsJsonAsync("api/stories", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadFromJsonAsync<dynamic>();
}
}
public record CreateStoryRequest(string Type, string? MediaUrl, string? Content, string? BgColor);
@@ -0,0 +1,76 @@
using FluentAssertions;
using Knot.Modules.Stories.Application.Stories.Commands.CreateStory;
using Knot.Modules.Stories.Domain;
using Knot.Shared.Kernel;
using Knot.Modules.Settings.Application.Settings.Abstractions;
using Knot.Modules.Settings.Application.Settings.DTOs;
using Knot.Modules.Stories.Application.Abstractions;
using NSubstitute;
using Xunit;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Knot.Modules.Stories.UnitTests;
public class CreateStoryCommandHandlerTests
{
private readonly IStoryRepository _storyRepository;
private readonly ISettingsService _settingsService;
private readonly CreateStoryCommandHandler _handler;
public CreateStoryCommandHandlerTests()
{
_storyRepository = Substitute.For<IStoryRepository>();
_settingsService = Substitute.For<ISettingsService>();
_handler = new CreateStoryCommandHandler(_storyRepository, _settingsService);
}
[Fact]
public async Task Handle_ShouldSucceed_WhenValidRequest()
{
// Arrange
var command = new CreateStoryCommand(Guid.NewGuid(), "Text", null, "Hello Story", null);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsSuccess.Should().BeTrue();
await _storyRepository.Received(1).AddAsync(Arg.Any<Story>(), Arg.Any<CancellationToken>());
}
[Fact]
public async Task Handle_ShouldFail_WhenKlipyDisabledAndKlipyType()
{
// Arrange
var command = new CreateStoryCommand(Guid.NewGuid(), "Klipy", "http://klipy.com/gif", null, null);
var settings = new SystemSettingsDto { Klipy = new KlipyConfig { Enabled = false } };
_settingsService.GetSettingsAsync(Arg.Any<CancellationToken>()).Returns(settings);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Code.Should().Be("Stories.KlipyDisabled");
await _storyRepository.DidNotReceive().AddAsync(Arg.Any<Story>(), Arg.Any<CancellationToken>());
}
[Fact]
public async Task Handle_ShouldSucceed_WhenKlipyEnabledAndKlipyType()
{
// Arrange
var command = new CreateStoryCommand(Guid.NewGuid(), "Klipy", "http://klipy.com/gif", null, null);
var settings = new SystemSettingsDto { Klipy = new KlipyConfig { Enabled = true } };
_settingsService.GetSettingsAsync(Arg.Any<CancellationToken>()).Returns(settings);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsSuccess.Should().BeTrue();
await _storyRepository.Received(1).AddAsync(Arg.Any<Story>(), Arg.Any<CancellationToken>());
}
}
@@ -0,0 +1,76 @@
using FluentAssertions;
using Knot.Modules.Stories.Application.Stories.Commands.DeleteStory;
using Knot.Modules.Stories.Domain;
using Knot.Shared.Kernel;
using Knot.Modules.Stories.Application.Abstractions;
using NSubstitute;
using Xunit;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Knot.Modules.Stories.UnitTests;
public class DeleteStoryCommandHandlerTests
{
private readonly IStoryRepository _storyRepository;
private readonly DeleteStoryCommandHandler _handler;
public DeleteStoryCommandHandlerTests()
{
_storyRepository = Substitute.For<IStoryRepository>();
_handler = new DeleteStoryCommandHandler(_storyRepository);
}
[Fact]
public async Task Handle_ShouldReturnError_WhenStoryNotFound()
{
// Arrange
var command = new DeleteStoryCommand(Guid.NewGuid(), Guid.NewGuid());
_storyRepository.GetByIdAsync(command.StoryId, Arg.Any<CancellationToken>()).Returns((Story?)null);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Should().Be(StoryErrors.StoryNotFound);
}
[Fact]
public async Task Handle_ShouldReturnError_WhenUserIsNotOwner()
{
// Arrange
var ownerId = Guid.NewGuid();
var viewerId = Guid.NewGuid();
var story = Story.Create(ownerId, StoryType.Text, null, "Content", null);
var command = new DeleteStoryCommand(viewerId, story.Id);
_storyRepository.GetByIdAsync(command.StoryId, Arg.Any<CancellationToken>()).Returns(story);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Should().Be(StoryErrors.Unauthorized);
}
[Fact]
public async Task Handle_ShouldSucceed_WhenOwnerDeletes()
{
// Arrange
var ownerId = Guid.NewGuid();
var story = Story.Create(ownerId, StoryType.Text, null, "Content", null);
var command = new DeleteStoryCommand(ownerId, story.Id);
_storyRepository.GetByIdAsync(command.StoryId, Arg.Any<CancellationToken>()).Returns(story);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsSuccess.Should().BeTrue();
await _storyRepository.Received(1).DeleteAsync(story, Arg.Any<CancellationToken>());
}
}
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\Stories\Knot.Modules.Stories.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Stories\Knot.Modules.Stories.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\TelegramImport\Knot.Modules.TelegramImport.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\TelegramImport\Knot.Modules.TelegramImport.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Modules\Profiles\Knot.Modules.Profiles.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>
@@ -1,41 +1,38 @@
using FluentAssertions;
using Knot.Modules.Profiles.Application.Profiles.Commands.UpdateProfile;
using Knot.Modules.Profiles.Application.Profiles.UpdateProfile;
using Knot.Modules.Profiles.Domain;
using Knot.Modules.Profiles.Application.Abstractions;
using Knot.Shared.Kernel;
using NSubstitute;
using Xunit;
using System;
using System.Threading;
using System.Threading.Tasks;
using Knot.Modules.Profiles.Application.Abstractions;
namespace Knot.Modules.Profiles.UnitTests;
public class UpdateProfileCommandHandlerTests
{
private readonly IProfileRepository _profileRepository;
private readonly IProfilesUnitOfWork _unitOfWork;
private readonly UpdateProfileCommandHandler _handler;
public UpdateProfileCommandHandlerTests()
{
_profileRepository = Substitute.For<IProfileRepository>();
_unitOfWork = Substitute.For<IProfilesUnitOfWork>();
_handler = new UpdateProfileCommandHandler(_profileRepository, _unitOfWork);
_handler = new UpdateProfileCommandHandler(_profileRepository);
}
[Fact]
public async Task Handle_ShouldReturnError_WhenProfileNotFound()
{
// Arrange
var command = new UpdateProfileCommand(Guid.NewGuid(), "FirstName", "LastName", "Bio");
_profileRepository.GetByIdAsync(command.UserId, Arg.Any<CancellationToken>()).Returns((UserProfile?)null);
var command = new UpdateProfileCommand(Guid.NewGuid(), "FirstName", "Bio", null);
_profileRepository.GetByIdAsync(command.UserId, Arg.Any<CancellationToken>()).Returns((ProfileDocument?)null);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Should().Be(ProfileErrors.NotFound);
}
}
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
@@ -21,8 +21,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Modules\WebRtc\Knot.Modules.WebRtc.csproj" />
<ProjectReference Include="..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\WebRtc\Knot.Modules.WebRtc.csproj" />
<ProjectReference Include="..\..\..\src\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
<ProjectReference Include="..\..\..\src\Modules\Settings\Knot.Modules.Settings.csproj" />
</ItemGroup>
</Project>