using AcDream.Core.Chat;
using AcDream.UI.Abstractions.Panels.Chat;
namespace AcDream.UI.Abstractions.Tests.Panels.Chat;
///
/// Phase I.4: when the user submits text via the chat input field, the
/// panel must publish a to the command bus.
/// We exercise the full Render path with the
/// pre-loading a "submitted" string and a recording bus capturing the
/// resulting command.
///
public sealed class ChatPanelInputTests
{
private sealed class RecordingBus : ICommandBus
{
public List Published { get; } = new();
public void Publish(T command) where T : notnull => Published.Add(command);
}
[Fact]
public void Submit_PlainText_PublishesSayCommand()
{
var log = new ChatLog();
var vm = new ChatVM(log);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = "hello world",
InputTextSubmitNextBufferAfter = "",
};
panel.Render(new PanelContext(0.016f, bus), renderer);
var cmd = Assert.Single(bus.Published);
var sendCmd = Assert.IsType(cmd);
Assert.Equal(ChatChannelKind.Say, sendCmd.Channel);
Assert.Null(sendCmd.TargetName);
Assert.Equal("hello world", sendCmd.Text);
}
[Fact]
public void Submit_TellSlashCommand_PublishesTellCommand()
{
var log = new ChatLog();
var vm = new ChatVM(log);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = "/t Bestie ping",
InputTextSubmitNextBufferAfter = "",
};
panel.Render(new PanelContext(0.016f, bus), renderer);
var sendCmd = Assert.IsType(Assert.Single(bus.Published));
Assert.Equal(ChatChannelKind.Tell, sendCmd.Channel);
Assert.Equal("Bestie", sendCmd.TargetName);
Assert.Equal("ping", sendCmd.Text);
}
[Fact]
public void Submit_ReplySlashCommand_UsesLastIncomingTellSender()
{
var log = new ChatLog();
var vm = new ChatVM(log);
log.OnTellReceived("Bestie", "ping", senderGuid: 0x5000_00AAu);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = "/r back at you",
InputTextSubmitNextBufferAfter = "",
};
panel.Render(new PanelContext(0.016f, bus), renderer);
var sendCmd = Assert.IsType(Assert.Single(bus.Published));
Assert.Equal(ChatChannelKind.Tell, sendCmd.Channel);
Assert.Equal("Bestie", sendCmd.TargetName);
Assert.Equal("back at you", sendCmd.Text);
}
[Fact]
public void Submit_EmptyOrWhitespace_PublishesNothing()
{
var log = new ChatLog();
var vm = new ChatVM(log);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = " ",
InputTextSubmitNextBufferAfter = "",
};
panel.Render(new PanelContext(0.016f, bus), renderer);
Assert.Empty(bus.Published);
}
[Fact]
public void NoSubmit_PublishesNothing()
{
// Most frames: user is typing or idle; submitted == null.
var log = new ChatLog();
var vm = new ChatVM(log);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = null,
};
panel.Render(new PanelContext(0.016f, bus), renderer);
Assert.Empty(bus.Published);
}
[Fact]
public void Render_AlwaysCallsInputTextSubmit_ToShowTheField()
{
var log = new ChatLog();
var vm = new ChatVM(log);
var panel = new ChatPanel(vm);
var bus = new RecordingBus();
var renderer = new FakePanelRenderer
{
InputTextSubmitNextSubmitted = null,
};
panel.Render(new PanelContext(0.016f, bus), renderer);
Assert.Contains(renderer.Calls, c => c.Method == "InputTextSubmit");
}
}