using EntKube.Provisioning.Domain; using EntKube.Provisioning.Features.Apps.AddAppSecret; using EntKube.Provisioning.Infrastructure; using EntKube.SharedKernel.Domain; using FluentAssertions; namespace EntKube.Provisioning.Tests.Features; public class AddAppSecretHandlerTests { private readonly AddAppSecretHandler handler; private readonly InMemoryAppRepository repository; public AddAppSecretHandlerTests() { repository = new InMemoryAppRepository(); handler = new AddAppSecretHandler(repository); } [Fact] public async Task HandleAsync_WithValidRequest_AddsSecretToEnvironment() { // Arrange — An app deployed to dev needs a database connection string. // The actual secret value lives in the vault — we just store the reference. App app = App.Create(Guid.NewGuid(), Guid.NewGuid(), "API", "api", AppType.Deployment); Guid environmentId = Guid.NewGuid(); app.AddEnvironment(environmentId, Guid.NewGuid(), "api-dev"); await repository.AddAsync(app); AddAppSecretRequest request = new( AppId: app.Id, EnvironmentId: environmentId, Name: "DATABASE_URL", VaultKey: "database-connection-string"); // Act Result result = await handler.HandleAsync(request); // Assert result.IsSuccess.Should().BeTrue(); App? updated = await repository.GetByIdAsync(app.Id); AppEnvironment env = updated!.Environments[0]; env.Secrets.Should().HaveCount(1); env.Secrets[0].Name.Should().Be("DATABASE_URL"); env.Secrets[0].VaultKey.Should().Be("database-connection-string"); } [Fact] public async Task HandleAsync_NonExistentApp_ReturnsFailure() { // Arrange & Act AddAppSecretRequest request = new(Guid.NewGuid(), Guid.NewGuid(), "KEY", "vault-key"); Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("not found"); } [Fact] public async Task HandleAsync_DuplicateSecretName_ReturnsFailure() { // Arrange — A secret with this name already exists. App app = App.Create(Guid.NewGuid(), Guid.NewGuid(), "API", "api", AppType.Deployment); Guid environmentId = Guid.NewGuid(); AppEnvironment env = app.AddEnvironment(environmentId, Guid.NewGuid(), "api-dev"); env.AddSecret("DATABASE_URL", "db-conn"); await repository.AddAsync(app); AddAppSecretRequest request = new(app.Id, environmentId, "DATABASE_URL", "other-key"); // Act Result result = await handler.HandleAsync(request); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("already exists"); } }