108 lines
3.1 KiB
C#
108 lines
3.1 KiB
C#
using EntKube.Provisioning.Domain;
|
|
using EntKube.Provisioning.Features.Apps.CreateApp;
|
|
using EntKube.Provisioning.Infrastructure;
|
|
using EntKube.SharedKernel.Domain;
|
|
using FluentAssertions;
|
|
|
|
namespace EntKube.Provisioning.Tests.Features;
|
|
|
|
public class CreateAppHandlerTests
|
|
{
|
|
private readonly CreateAppHandler handler;
|
|
private readonly InMemoryAppRepository repository;
|
|
|
|
public CreateAppHandlerTests()
|
|
{
|
|
repository = new InMemoryAppRepository();
|
|
handler = new CreateAppHandler(repository);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task HandleAsync_WithValidRequest_CreatesAppAndReturnsId()
|
|
{
|
|
// Arrange — A customer admin creates a new Deployment-type app.
|
|
|
|
CreateAppRequest request = new(
|
|
TenantId: Guid.NewGuid(),
|
|
CustomerId: Guid.NewGuid(),
|
|
Name: "Frontend Portal",
|
|
Slug: "frontend-portal",
|
|
Type: AppType.Deployment);
|
|
|
|
// Act
|
|
|
|
Result<Guid> result = await handler.HandleAsync(request);
|
|
|
|
// Assert — The app is created and its ID returned.
|
|
|
|
result.IsSuccess.Should().BeTrue();
|
|
result.Value.Should().NotBe(Guid.Empty);
|
|
|
|
App? stored = await repository.GetByIdAsync(result.Value!);
|
|
stored.Should().NotBeNull();
|
|
stored!.Name.Should().Be("Frontend Portal");
|
|
stored.Type.Should().Be(AppType.Deployment);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task HandleAsync_WithDuplicateSlug_ReturnsFailure()
|
|
{
|
|
// Arrange — An app with the same slug already exists for this customer.
|
|
|
|
Guid customerId = Guid.NewGuid();
|
|
|
|
CreateAppRequest first = new(Guid.NewGuid(), customerId, "App One", "my-app", AppType.Deployment);
|
|
await handler.HandleAsync(first);
|
|
|
|
CreateAppRequest duplicate = new(Guid.NewGuid(), customerId, "App Two", "my-app", AppType.HelmChart);
|
|
|
|
// Act
|
|
|
|
Result<Guid> result = await handler.HandleAsync(duplicate);
|
|
|
|
// Assert
|
|
|
|
result.IsFailure.Should().BeTrue();
|
|
result.Error.Should().Contain("already exists");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task HandleAsync_WithEmptyName_ReturnsFailure()
|
|
{
|
|
// Arrange & Act
|
|
|
|
CreateAppRequest request = new(Guid.NewGuid(), Guid.NewGuid(), "", "slug", AppType.Deployment);
|
|
Result<Guid> result = await handler.HandleAsync(request);
|
|
|
|
// Assert
|
|
|
|
result.IsFailure.Should().BeTrue();
|
|
result.Error.Should().Contain("name");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task HandleAsync_WithHelmChartType_CreatesHelmApp()
|
|
{
|
|
// Arrange — A customer wants to deploy a Helm chart-based app.
|
|
|
|
CreateAppRequest request = new(
|
|
TenantId: Guid.NewGuid(),
|
|
CustomerId: Guid.NewGuid(),
|
|
Name: "Redis Cache",
|
|
Slug: "redis-cache",
|
|
Type: AppType.HelmChart);
|
|
|
|
// Act
|
|
|
|
Result<Guid> result = await handler.HandleAsync(request);
|
|
|
|
// Assert
|
|
|
|
result.IsSuccess.Should().BeTrue();
|
|
|
|
App? stored = await repository.GetByIdAsync(result.Value!);
|
|
stored.Should().NotBeNull();
|
|
stored!.Type.Should().Be(AppType.HelmChart);
|
|
}
|
|
}
|