Files
jdescopingtool/NEW/tests/Utils/JdeScoping.ConfigManager.Cli.Tests/Commands/ConfigCommandsTests.cs
T
Joseph Doherty bad0102af1 feat(configmanager): add CLI feature parity with UI
Expand ConfigManager.Cli with pipeline, config, backup, and connection commands
to match the feature set of ConfigManager.Ui, plus README documentation.
2026-01-28 10:40:25 -05:00

184 lines
6.6 KiB
C#

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;
public class ConfigCommandsTests
{
private readonly IServiceProvider _serviceProvider;
private readonly IConfigFileService _configFileService;
private readonly IAutoDiscoveryService _autoDiscoveryService;
private readonly Option<string?> _configPathOption;
private readonly Option<bool> _verboseOption;
private readonly Option<bool> _quietOption;
public ConfigCommandsTests()
{
_configFileService = Substitute.For<IConfigFileService>();
_autoDiscoveryService = Substitute.For<IAutoDiscoveryService>();
var services = new ServiceCollection();
services.AddSingleton(_configFileService);
services.AddSingleton(_autoDiscoveryService);
_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 CreateShowCommand_ReturnsCommandWithSubcommands()
{
// Act
var command = ConfigCommands.CreateShowCommand(
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
// Assert
command.ShouldNotBeNull();
command.Name.ShouldBe("show");
command.Subcommands.ShouldContain(c => c.Name == "datasync");
command.Subcommands.ShouldContain(c => c.Name == "dataaccess");
command.Subcommands.ShouldContain(c => c.Name == "auth");
command.Subcommands.ShouldContain(c => c.Name == "ldap");
command.Subcommands.ShouldContain(c => c.Name == "search");
command.Subcommands.ShouldContain(c => c.Name == "excelexport");
command.Subcommands.ShouldContain(c => c.Name == "securestore");
command.Subcommands.ShouldContain(c => c.Name == "connections");
command.Subcommands.ShouldContain(c => c.Name == "all");
}
[Fact]
public void CreateShowCommand_HasJsonOption()
{
// Act
var command = ConfigCommands.CreateShowCommand(
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
// Assert
command.Options.ShouldContain(o => o.Name == "json");
}
[Fact]
public async Task ShowDataSyncCommand_WithNoConfigFolder_ReturnsError()
{
// Arrange
_autoDiscoveryService.FindConfigFolderAsync(Arg.Any<CancellationToken>())
.Returns(Task.FromResult<string?>(null));
var command = ConfigCommands.CreateShowCommand(
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
var rootCommand = new RootCommand { command };
rootCommand.AddGlobalOption(_configPathOption);
rootCommand.AddGlobalOption(_verboseOption);
rootCommand.AddGlobalOption(_quietOption);
// Act
var exitCode = await rootCommand.InvokeAsync(["show", "datasync"]);
// Assert - command completes without throwing
command.ShouldNotBeNull();
}
[Fact]
public void DataSyncSubcommand_Exists()
{
// Arrange
var command = ConfigCommands.CreateShowCommand(
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
// Act
var datasyncSubcommand = command.Subcommands.FirstOrDefault(c => c.Name == "datasync");
// Assert
datasyncSubcommand.ShouldNotBeNull();
datasyncSubcommand.Description.ShouldBe("Show DataSync configuration");
}
[Fact]
public async Task ShowConnectionsCommand_MasksNoPasswords()
{
// 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 = "TestConnection",
Provider = ConnectionProvider.SqlServer,
Server = "localhost",
Password = "secret123"
}
]
}
};
_configFileService.LoadAppSettingsAsync(appSettingsPath, Arg.Any<CancellationToken>())
.Returns(Task.FromResult(config));
var command = ConfigCommands.CreateShowCommand(
_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(["show", "connections"]);
// Assert
var output = writer.ToString();
output.ShouldContain("TestConnection");
output.ShouldNotContain("secret123"); // Password should not be visible
}
finally
{
Console.SetOut(originalOut);
}
}
finally
{
Directory.Delete(tempDir, true);
}
}
[Fact]
public void AllSubcommand_HasJsonOption()
{
// Arrange
var command = ConfigCommands.CreateShowCommand(
_serviceProvider, _configPathOption, _verboseOption, _quietOption);
// Act
var allSubcommand = command.Subcommands.FirstOrDefault(c => c.Name == "all");
// Assert
allSubcommand.ShouldNotBeNull();
// The json option is on the parent show command
command.Options.ShouldContain(o => o.Name == "json");
}
}