From 1fd6ad42c2d02ac971755f602066d404bc08d2a9 Mon Sep 17 00:00:00 2001 From: Gergely Urbancsik <143094288+gergelyurbancsik@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:01:01 +0200 Subject: [PATCH] fix --- .../Variables/VariableResolver.cs | 4 +- .../Variables/VariableResolverTests.cs | 83 +++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/Confix.Tool/src/Confix.Library/Variables/VariableResolver.cs b/src/Confix.Tool/src/Confix.Library/Variables/VariableResolver.cs index 06bd7c1..e87de6c 100644 --- a/src/Confix.Tool/src/Confix.Library/Variables/VariableResolver.cs +++ b/src/Confix.Tool/src/Confix.Library/Variables/VariableResolver.cs @@ -30,9 +30,9 @@ public async Task SetVariable( await using var provider = _variableProviderFactory.CreateProvider(configuration); - await provider.SetAsync(path.Path, value, context); + var resolvedPath = await provider.SetAsync(path.Path, value, context); - return path; + return new VariablePath(path.ProviderName, resolvedPath); } public async Task> ListVariables(IVariableProviderContext context) diff --git a/src/Confix.Tool/test/Confix.Tool.Tests/Variables/VariableResolverTests.cs b/src/Confix.Tool/test/Confix.Tool.Tests/Variables/VariableResolverTests.cs index 03d68ad..b34d9d6 100644 --- a/src/Confix.Tool/test/Confix.Tool.Tests/Variables/VariableResolverTests.cs +++ b/src/Confix.Tool/test/Confix.Tool.Tests/Variables/VariableResolverTests.cs @@ -171,4 +171,87 @@ public async Task ResolveVariables_ProviderNotFound_ThrowsExitException() await Assert.ThrowsAsync(() => resolver.ResolveVariables(keys, context)); } + + [Fact] + public async Task SetVariable_ProviderReturnsTransformedPath_ReturnsPathWithProviderName() + { + // Arrange – simulates the `secret` provider, whose SetAsync returns the + // Base64-encoded ciphertext rather than the input path. The resolver must + // propagate that transformed path so the CLI can display it to the user. + var factoryMock = new Mock(); + + var configurations = new List + { + new VariableProviderConfiguration + { + Name = "secret", + Type = "secret", + Configuration = JsonNode.Parse("{}")! + } + }; + + const string inputPath = "irrelevant"; + const string cipherTextPath = "K2b8F2zG9HpJxMImaYwlf0ByzArc+abc/def=="; + var value = JsonValue.Create("super-secret")!; + + var providerMock = new Mock(); + providerMock + .Setup(p => p.SetAsync(inputPath, value, It.IsAny())) + .ReturnsAsync(cipherTextPath); + + factoryMock.Setup(f => f.CreateProvider(configurations[0])) + .Returns(providerMock.Object); + + var resolver = new VariableResolver(factoryMock.Object, new VariableListCache(), configurations); + var context = new VariableProviderContext(null!, CancellationToken.None); + + // Act + var result = await resolver.SetVariable( + new VariablePath("secret", inputPath), + value, + context); + + // Assert + result.ProviderName.Should().Be("secret"); + result.Path.Should().Be(cipherTextPath); + result.ToString().Should().Be($"$secret:{cipherTextPath}"); + } + + [Fact] + public async Task SetVariable_ProviderReturnsSamePath_ReturnsPathUnchanged() + { + // Arrange – simulates the `local` provider, whose SetAsync returns the + // original path unchanged. + var factoryMock = new Mock(); + + var configurations = new List + { + new VariableProviderConfiguration + { + Name = "Provider1", + Type = "local", + Configuration = JsonNode.Parse("""{ "path": "/path/to/file.json" }""")! + } + }; + + var providerMock = new Mock(); + providerMock + .Setup(p => p.SetAsync("Key1", It.IsAny(), It.IsAny())) + .ReturnsAsync("Key1"); + + factoryMock.Setup(f => f.CreateProvider(configurations[0])) + .Returns(providerMock.Object); + + var resolver = new VariableResolver(factoryMock.Object, new VariableListCache(), configurations); + var context = new VariableProviderContext(null!, CancellationToken.None); + + // Act + var result = await resolver.SetVariable( + new VariablePath("Provider1", "Key1"), + JsonValue.Create("v")!, + context); + + // Assert + result.Should().Be(new VariablePath("Provider1", "Key1")); + } }