using Xunit; using FluentAssertions; using NSubstitute; using FreeCode.Commands; using FreeCode.Core.Enums; using FreeCode.Core.Interfaces; using FreeCode.Core.Models; using FreeCode.Tests.Unit.Helpers; namespace FreeCode.Tests.Unit.Commands; public sealed class HelpCommandTests { [Fact] public async Task ExecuteAsync_ReturnsFailureWhenCommandRegistryIsUnavailable() { var services = new SimpleServiceProvider(); var command = new HelpCommand(services); var result = await command.ExecuteAsync(new CommandContext(Environment.CurrentDirectory, services)); result.Success.Should().BeFalse(); result.Output.Should().Be("Command registry is unavailable."); } [Fact] public async Task ExecuteAsync_ListsCommandsSortedByCategoryAndName() { var registry = new StubCommandRegistry { EnabledCommandsOverride = [ new TestCommand("exit", "Exit app", CommandCategory.Local, ["quit"]), new TestCommand("help", "Show help", CommandCategory.Prompt) ] }; var services = new SimpleServiceProvider().AddService(typeof(ICommandRegistry), registry); var command = new HelpCommand(services); var result = await command.ExecuteAsync(new CommandContext(Environment.CurrentDirectory, services)); result.Success.Should().BeTrue(); result.Output.Should().Contain("Available commands:"); result.Output.Should().Contain("/help - Show help"); result.Output.Should().Contain("/exit (quit) - Exit app"); } [Fact] public async Task ExecuteAsync_WhenNoCommandsExist_ReturnsHeaderOnly() { var services = new SimpleServiceProvider().AddService(typeof(ICommandRegistry), new StubCommandRegistry()); var command = new HelpCommand(services); var result = await command.ExecuteAsync(new CommandContext(Environment.CurrentDirectory, services)); result.Success.Should().BeTrue(); result.Output.Should().Be("Available commands:"); } private sealed class TestCommand(string name, string description, CommandCategory category, string[]? aliases = null) : ICommand { public string Name => name; public string[]? Aliases => aliases; public string Description => description; public CommandCategory Category => category; public CommandAvailability Availability => CommandAvailability.Always; public bool IsEnabled() => true; public Task ExecuteAsync(CommandContext context, string? args = null, CancellationToken ct = default) => Task.FromResult(new CommandResult(true)); } }