170 lines
5.5 KiB
C#
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")]));
|
|
}
|
|
}
|