Files

170 lines
5.5 KiB
C#

namespace MBN_STOCK_WEBVIEW.LegacyApplication.Tests;
public sealed class LegacyCutKeyboardParityTests
{
[Fact]
public async Task ControlNavigationMovesOnlyFocusAndShiftKeepsTheNativeAnchor()
{
var controller = await CreateReadyControllerAsync();
controller.CutPointerDown(2, false, false, 1, 47, 1_000);
var controlDown = controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowDown,
control: true,
shift: false);
var shiftSpace = controller.CutKeyDown(
LegacyCutKeyboardKey.Space,
control: false,
shift: true);
var plainDown = controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowDown,
control: false,
shift: false);
var shiftUp = controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowUp,
control: false,
shift: true);
AssertCutState(controlDown, [2], focused: 3);
AssertCutState(shiftSpace, [2, 3], focused: 3);
AssertCutState(plainDown, [4], focused: 4);
AssertCutState(shiftUp, [3, 4], focused: 3);
}
[Fact]
public async Task ControlShiftNavigationAddsRangeWithoutDiscardingExistingSelection()
{
var controller = await CreateReadyControllerAsync();
controller.CutPointerDown(1, false, false, 1, 24, 1_000);
controller.CutPointerDown(4, true, false, 1, 93, 2_000);
controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowUp,
control: true,
shift: false);
var state = controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowUp,
control: true,
shift: true);
AssertCutState(state, [1, 2, 3, 4], focused: 2);
}
[Fact]
public async Task HomeAndEndUsePhysicalBoundariesIncludingSeparatorRows()
{
var controller = await CreateReadyControllerAsync();
controller.CutPointerDown(2, false, false, 1, 47, 1_000);
var end = controller.CutKeyDown(
LegacyCutKeyboardKey.End,
control: false,
shift: false);
var controlHome = controller.CutKeyDown(
LegacyCutKeyboardKey.Home,
control: true,
shift: false);
var shiftSpace = controller.CutKeyDown(
LegacyCutKeyboardKey.Space,
control: false,
shift: true);
var last = end.CutRows.Count - 1;
AssertCutState(end, [last], focused: last);
AssertCutState(controlHome, [last], focused: 0);
AssertCutState(shiftSpace, Enumerable.Range(0, last + 1), focused: 0);
}
[Fact]
public async Task ControlSpaceTogglesFocusedRowAndMovesTheAnchor()
{
var controller = await CreateReadyControllerAsync();
controller.CutPointerDown(1, false, false, 1, 24, 1_000);
var toggledOff = controller.CutKeyDown(
LegacyCutKeyboardKey.Space,
control: true,
shift: false);
controller.CutKeyDown(
LegacyCutKeyboardKey.ArrowDown,
control: true,
shift: false);
var extended = controller.CutKeyDown(
LegacyCutKeyboardKey.Space,
control: false,
shift: true);
AssertCutState(toggledOff, [], focused: 1);
AssertCutState(extended, [1, 2], focused: 2);
}
[Fact]
public async Task KeyboardSelectionFeedsTheSameNativeDropAuthority()
{
var controller = await CreateReadyControllerAsync();
var selected = controller.CutKeyDown(
LegacyCutKeyboardKey.Space,
control: false,
shift: false);
var dropped = controller.DropSelectedCutsOnPlaylist();
AssertCutState(selected, [0], focused: 0);
Assert.Equal(
LegacyStockCutCatalog.Rows[0].RawLabel,
Assert.Single(dropped.Playlist).RawCutLabel);
}
[Fact]
public void KeyboardSelectionIsIgnoredUntilAStockIsSelected()
{
var controller = new LegacyOperatorController(new OneStockLookup());
var before = controller.Current;
var after = controller.CutKeyDown(
LegacyCutKeyboardKey.End,
control: false,
shift: false);
Assert.Equal(before.Revision, after.Revision);
Assert.DoesNotContain(after.CutRows, row => row.IsFocused || row.IsSelected);
}
private static async Task<LegacyOperatorController> CreateReadyControllerAsync()
{
var controller = new LegacyOperatorController(new OneStockLookup());
await controller.SearchStocksAsync("stock", LegacySearchTrigger.Button);
controller.SelectStock(0);
return controller;
}
private static void AssertCutState(
LegacyOperatorSnapshot snapshot,
IEnumerable<int> selected,
int focused)
{
Assert.Equal(
selected,
snapshot.CutRows
.Where(row => row.IsSelected)
.Select(row => row.PhysicalIndex));
Assert.Equal(
focused,
Assert.Single(snapshot.CutRows, row => row.IsFocused).PhysicalIndex);
}
private sealed class OneStockLookup : ILegacyStockLookup
{
public Task<LegacyStockSearchData> SearchAsync(
string query,
CancellationToken cancellationToken = default) =>
Task.FromResult(new LegacyStockSearchData(
query,
["Stock"],
[new LegacyStockIdentity(
LegacyDomesticStockMarket.Kospi,
"Stock",
"000001")]));
}
}