using EntKube.Clusters.Domain; using EntKube.Clusters.Features.RegisterCluster; using EntKube.Clusters.Infrastructure; using EntKube.SharedKernel.Domain; using FluentAssertions; namespace EntKube.Clusters.Tests.Features; public class RegisterClusterHandlerTests { private readonly RegisterClusterHandler handler; private readonly InMemoryClusterRepository repository; public RegisterClusterHandlerTests() { repository = new InMemoryClusterRepository(); handler = new RegisterClusterHandler(repository); } [Fact] public async Task HandleAsync_WithValidRequest_ReturnsSuccessWithClusterId() { // Arrange — A valid registration request with all required fields // including the tenant and kubeconfig. Guid tenantId = Guid.NewGuid(); Guid environmentId = Guid.NewGuid(); RegisterClusterRequest request = new("production-eu", "https://k8s.example.com:6443", "apiVersion: v1\nkind: Config", tenantId, "prod-context", environmentId); // Act Result result = await handler.HandleAsync(request); // Assert — The handler should succeed and the cluster should be persisted with tenant link. result.IsSuccess.Should().BeTrue(); result.Value.Should().NotBe(Guid.Empty); KubernetesCluster? persisted = await repository.GetByIdAsync(result.Value!); persisted.Should().NotBeNull(); persisted!.Name.Should().Be("production-eu"); persisted.TenantId.Should().Be(tenantId); persisted.KubeConfig.Should().Contain("apiVersion"); persisted.ContextName.Should().Be("prod-context"); } [Fact] public async Task HandleAsync_WithEmptyName_ReturnsFailure() { // Arrange — Missing cluster name. RegisterClusterRequest request = new("", "https://k8s.example.com:6443", "kubeconfig-data", Guid.NewGuid(), "ctx", Guid.NewGuid()); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("name"); } [Fact] public async Task HandleAsync_WithEmptyApiUrl_ReturnsFailure() { // Arrange — Missing API server URL. RegisterClusterRequest request = new("my-cluster", "", "kubeconfig-data", Guid.NewGuid(), "ctx", Guid.NewGuid()); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("API server URL"); } [Fact] public async Task HandleAsync_WithEmptyKubeConfig_ReturnsFailure() { // Arrange — Missing kubeconfig content. A cluster cannot be registered // without credentials to access it. RegisterClusterRequest request = new("my-cluster", "https://k8s.example.com:6443", "", Guid.NewGuid(), "ctx", Guid.NewGuid()); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("KubeConfig"); } [Fact] public async Task HandleAsync_WithEmptyTenantId_ReturnsFailure() { // Arrange — No tenant specified. Every cluster must belong to a tenant. RegisterClusterRequest request = new("my-cluster", "https://k8s.example.com:6443", "kubeconfig-data", Guid.Empty, "ctx", Guid.NewGuid()); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("tenant"); } [Fact] public async Task HandleAsync_WithEmptyEnvironmentId_ReturnsFailure() { // Arrange — No environment specified. Every cluster must belong to an environment. RegisterClusterRequest request = new("my-cluster", "https://k8s.example.com:6443", "kubeconfig-data", Guid.NewGuid(), "ctx", Guid.Empty); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("environment"); } }