feat(configmanager): add config set and connection update CLI commands
Add missing CLI commands to match UI capabilities: config set commands for all configuration sections (datasync, dataaccess, auth, ldap, search, excelexport) and connection update command. Also adds unit tests for SecretCommands, ValidateCommand, and TestConnectionCommand.
This commit is contained in:
+294
@@ -0,0 +1,294 @@
|
||||
using System.CommandLine;
|
||||
using JdeScoping.ConfigManager.Cli.Commands;
|
||||
using JdeScoping.ConfigManager.Core.Models;
|
||||
using JdeScoping.ConfigManager.Core.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Cli.Tests.Commands;
|
||||
|
||||
[Collection("Console Tests")]
|
||||
public class TestConnectionCommandTests
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IConfigFileService _configFileService;
|
||||
private readonly IAutoDiscoveryService _autoDiscoveryService;
|
||||
private readonly IConnectionTestService _connectionTestService;
|
||||
private readonly Option<string?> _configPathOption;
|
||||
private readonly Option<bool> _verboseOption;
|
||||
private readonly Option<bool> _quietOption;
|
||||
|
||||
public TestConnectionCommandTests()
|
||||
{
|
||||
_configFileService = Substitute.For<IConfigFileService>();
|
||||
_autoDiscoveryService = Substitute.For<IAutoDiscoveryService>();
|
||||
_connectionTestService = Substitute.For<IConnectionTestService>();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(_configFileService);
|
||||
services.AddSingleton(_autoDiscoveryService);
|
||||
services.AddSingleton(_connectionTestService);
|
||||
_serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
_configPathOption = new Option<string?>(["--config-path", "-c"]);
|
||||
_verboseOption = new Option<bool>(["--verbose", "-v"]);
|
||||
_quietOption = new Option<bool>(["--quiet", "-q"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSqlCommand_ReturnsCommand()
|
||||
{
|
||||
// Act
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.ShouldNotBeNull();
|
||||
command.Name.ShouldBe("sql");
|
||||
command.Description.ShouldBe("Test SQL Server connection");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSqlCommand_HasNameOption()
|
||||
{
|
||||
// Act
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.Options.ShouldContain(o => o.Name == "name");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateOracleCommand_ReturnsCommand()
|
||||
{
|
||||
// Act
|
||||
var command = TestConnectionCommand.CreateOracleCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.ShouldNotBeNull();
|
||||
command.Name.ShouldBe("oracle");
|
||||
command.Description.ShouldBe("Test Oracle connection");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateOracleCommand_HasNameOption()
|
||||
{
|
||||
// Act
|
||||
var command = TestConnectionCommand.CreateOracleCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.Options.ShouldContain(o => o.Name == "name");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateAllCommand_ReturnsCommand()
|
||||
{
|
||||
// Act
|
||||
var command = TestConnectionCommand.CreateAllCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.ShouldNotBeNull();
|
||||
command.Name.ShouldBe("all");
|
||||
command.Description.ShouldBe("Test all configured connections");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SqlCommand_WithNoConfigFolder_ReturnsError()
|
||||
{
|
||||
// Arrange
|
||||
_autoDiscoveryService.FindConfigFolderAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<string?>(null));
|
||||
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
var rootCommand = new RootCommand { command };
|
||||
rootCommand.AddGlobalOption(_configPathOption);
|
||||
rootCommand.AddGlobalOption(_verboseOption);
|
||||
rootCommand.AddGlobalOption(_quietOption);
|
||||
|
||||
// Act
|
||||
var exitCode = await rootCommand.InvokeAsync(["sql"]);
|
||||
|
||||
// Assert - command completes without throwing
|
||||
command.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SqlCommand_WithSuccessfulConnection_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var appSettingsPath = Path.Combine(tempDir, "appsettings.json");
|
||||
File.WriteAllText(appSettingsPath, "{}");
|
||||
|
||||
try
|
||||
{
|
||||
_autoDiscoveryService.FindConfigFolderAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<string?>(tempDir));
|
||||
|
||||
var config = new ConfigModel
|
||||
{
|
||||
ConnectionStrings = new ConnectionStringsSection
|
||||
{
|
||||
Entries =
|
||||
[
|
||||
new ConnectionStringEntry
|
||||
{
|
||||
Name = "LocalCache",
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
Database = "TestDb"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
_configFileService.LoadAppSettingsAsync(appSettingsPath, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult(config));
|
||||
|
||||
_connectionTestService.TestConnectionAsync(
|
||||
Arg.Any<string>(),
|
||||
ConnectionProvider.SqlServer,
|
||||
Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult(new ConnectionTestResult
|
||||
{
|
||||
Success = true,
|
||||
Duration = TimeSpan.FromMilliseconds(50)
|
||||
}));
|
||||
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
var rootCommand = new RootCommand { command };
|
||||
rootCommand.AddGlobalOption(_configPathOption);
|
||||
rootCommand.AddGlobalOption(_verboseOption);
|
||||
rootCommand.AddGlobalOption(_quietOption);
|
||||
|
||||
// Capture console output
|
||||
var originalOut = Console.Out;
|
||||
using var writer = new StringWriter();
|
||||
Console.SetOut(writer);
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
await rootCommand.InvokeAsync(["sql"]);
|
||||
|
||||
// Assert
|
||||
var output = writer.ToString();
|
||||
output.ShouldContain("Success");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(tempDir, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SqlCommand_WithFailedConnection_ReturnsError()
|
||||
{
|
||||
// Arrange
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var appSettingsPath = Path.Combine(tempDir, "appsettings.json");
|
||||
File.WriteAllText(appSettingsPath, "{}");
|
||||
|
||||
try
|
||||
{
|
||||
_autoDiscoveryService.FindConfigFolderAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<string?>(tempDir));
|
||||
|
||||
var config = new ConfigModel
|
||||
{
|
||||
ConnectionStrings = new ConnectionStringsSection
|
||||
{
|
||||
Entries =
|
||||
[
|
||||
new ConnectionStringEntry
|
||||
{
|
||||
Name = "LocalCache",
|
||||
Provider = ConnectionProvider.SqlServer,
|
||||
Server = "localhost",
|
||||
Database = "TestDb"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
_configFileService.LoadAppSettingsAsync(appSettingsPath, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult(config));
|
||||
|
||||
_connectionTestService.TestConnectionAsync(
|
||||
Arg.Any<string>(),
|
||||
ConnectionProvider.SqlServer,
|
||||
Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult(new ConnectionTestResult
|
||||
{
|
||||
Success = false,
|
||||
Message = "Connection refused"
|
||||
}));
|
||||
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
var rootCommand = new RootCommand { command };
|
||||
rootCommand.AddGlobalOption(_configPathOption);
|
||||
rootCommand.AddGlobalOption(_verboseOption);
|
||||
rootCommand.AddGlobalOption(_quietOption);
|
||||
|
||||
// Capture console error output
|
||||
var originalErr = Console.Error;
|
||||
using var writer = new StringWriter();
|
||||
Console.SetError(writer);
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
await rootCommand.InvokeAsync(["sql"]);
|
||||
|
||||
// Assert
|
||||
var output = writer.ToString();
|
||||
output.ShouldContain("Failed");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetError(originalErr);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(tempDir, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SqlCommand_NameOptionExists()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = TestConnectionCommand.CreateSqlCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
var nameOption = command.Options.FirstOrDefault(o => o.Name == "name");
|
||||
nameOption.ShouldNotBeNull();
|
||||
nameOption.Description.ShouldBe("Name of the connection string to test");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllCommand_HasCorrectDescription()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = TestConnectionCommand.CreateAllCommand(
|
||||
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
|
||||
|
||||
// Assert
|
||||
command.Description.ShouldBe("Test all configured connections");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user