feat: align legacy operator and playout behavior
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using MMoneyCoderSharp.Data;
|
||||
using MBN_STOCK_WEBVIEW.Core.Playout;
|
||||
using MBN_STOCK_WEBVIEW.Core.Playout.Scenes;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.LegacyApplication.Tests;
|
||||
|
||||
@@ -36,6 +38,229 @@ public sealed class LegacyOperatorPlayoutRequestTests
|
||||
Assert.Equal("005930", entry.Selection?.DataCode));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, false, "")]
|
||||
[InlineData(true, false, "MA5")]
|
||||
[InlineData(false, true, "MA20")]
|
||||
[InlineData(true, true, "MA5,MA20")]
|
||||
public async Task CandleAddedBeforeToggleSamplesCurrentMovingAveragesAtF8Request(
|
||||
bool ma5,
|
||||
bool ma20,
|
||||
string expectedGraphicType)
|
||||
{
|
||||
var controller = new LegacyOperatorController(new StaticLookup());
|
||||
await controller.SearchStocksAsync("stock", LegacySearchTrigger.Button);
|
||||
controller.SelectStock(0);
|
||||
var candle = LegacyStockCutCatalog.Rows.First(row =>
|
||||
!row.IsSeparator &&
|
||||
LegacyStockCutCatalog.ResolveCutAlias(row.RawLabel, isNxt: false) == "8051");
|
||||
AddCut(controller, candle.PhysicalIndex, 1_000);
|
||||
var rawBeforeToggle = Assert.Single(controller.Current.Playlist);
|
||||
var rawGraphicType = rawBeforeToggle.ToPlayoutEntry().Selection!.GraphicType;
|
||||
|
||||
controller.SetMovingAverages(ma5, ma20);
|
||||
var entry = Assert.Single(controller.CreatePlayoutRequest().Playlist);
|
||||
|
||||
Assert.Equal(expectedGraphicType, entry.Selection!.GraphicType);
|
||||
Assert.Equal(rawGraphicType,
|
||||
Assert.Single(controller.Current.Playlist).ToPlayoutEntry().Selection!.GraphicType);
|
||||
Assert.Equal(
|
||||
new LegacySceneMovingAverageSelection(ma5, ma20),
|
||||
entry.MovingAverageSelectionSource!.Current);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MovingAverageOverlayDoesNotAlterNonCandleRequest()
|
||||
{
|
||||
var controller = new LegacyOperatorController(new StaticLookup());
|
||||
await controller.SearchStocksAsync("stock", LegacySearchTrigger.Button);
|
||||
controller.SelectStock(0);
|
||||
var current = LegacyStockCutCatalog.Rows.First(row =>
|
||||
!row.IsSeparator &&
|
||||
LegacyStockCutCatalog.ResolveCutAlias(row.RawLabel, isNxt: false) == "5001");
|
||||
AddCut(controller, current.PhysicalIndex, 1_000);
|
||||
var raw = Assert.Single(controller.Current.Playlist).ToPlayoutEntry();
|
||||
|
||||
controller.SetMovingAverages(ma5: false, ma20: false);
|
||||
var requested = Assert.Single(controller.CreatePlayoutRequest().Playlist);
|
||||
|
||||
Assert.Equal(raw.Selection, requested.Selection);
|
||||
Assert.Null(requested.MovingAverageSelectionSource);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(6)]
|
||||
[InlineData(19)]
|
||||
public async Task RequestAppliesCurrentGlobalDissolveIndexToEveryExistingRow(
|
||||
int globalFadeDuration)
|
||||
{
|
||||
var controller = await CreateControllerWithCutsAsync(3);
|
||||
Assert.All(controller.Current.Playlist, row => Assert.Equal(6, row.FadeDuration));
|
||||
|
||||
var request = controller.CreatePlayoutRequest(globalFadeDuration);
|
||||
|
||||
Assert.All(request.Playlist, entry =>
|
||||
Assert.Equal(globalFadeDuration, entry.FadeDuration));
|
||||
Assert.All(controller.Current.Playlist, row => Assert.Equal(6, row.FadeDuration));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(-1)]
|
||||
[InlineData(20)]
|
||||
[InlineData(60)]
|
||||
public async Task RequestRejectsGlobalDissolveIndexOutsideOriginalComboRange(
|
||||
int globalFadeDuration)
|
||||
{
|
||||
var controller = await CreateControllerWithCutsAsync(1);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() =>
|
||||
controller.CreatePlayoutRequest(globalFadeDuration));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("5단 표그래프", ScenePageSize.Five)]
|
||||
[InlineData("6종목 현재가", ScenePageSize.Six)]
|
||||
[InlineData("12종목 현재가", ScenePageSize.Twelve)]
|
||||
public void ExactLegacyGraphicTypeFreezesTheOperatorPageSuffix(
|
||||
string graphicType,
|
||||
ScenePageSize expectedPageSize)
|
||||
{
|
||||
var entry = OperatorRow(graphicType, "2/3").ToPlayoutEntry();
|
||||
|
||||
Assert.Equal(expectedPageSize, entry.PageNavigation?.PageSize);
|
||||
Assert.Equal(3, entry.PageNavigation?.FrozenPageCount);
|
||||
Assert.True(entry.PageNavigation?.IsEnabled);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("5단 표그래프 ")]
|
||||
[InlineData("5단표그래프")]
|
||||
[InlineData("five-row")]
|
||||
public void NonCanonicalGraphicTypeExplicitlyDisablesPageNext(string graphicType)
|
||||
{
|
||||
var entry = OperatorRow(graphicType, "1/9").ToPlayoutEntry();
|
||||
|
||||
Assert.NotNull(entry.PageNavigation);
|
||||
Assert.False(entry.PageNavigation.IsEnabled);
|
||||
Assert.Null(entry.PageNavigation.PageSize);
|
||||
Assert.Null(entry.PageNavigation.FrozenPageCount);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1/0")]
|
||||
[InlineData("1/21")]
|
||||
[InlineData("2/1")]
|
||||
[InlineData("1 /2")]
|
||||
public void CanonicalPagedGraphicRejectsInvalidOperatorPageText(string pageText)
|
||||
{
|
||||
var row = OperatorRow("5단 표그래프", pageText);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(row.ToPlayoutEntry);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NextProgressUpdatesProgramPageWithoutReplacingOperatorSelection()
|
||||
{
|
||||
var controller = await CreateControllerWithCutsAsync(3);
|
||||
var rows = controller.Current.Playlist;
|
||||
controller.SelectPlaylistRow(rows[2].RowId, control: false, shift: false);
|
||||
|
||||
var state = controller.ReflectSuccessfulPlayout(
|
||||
rows[0].RowId,
|
||||
pageIndexZeroBased: 1,
|
||||
pageCount: 3,
|
||||
synchronizeOperatorSelection: false);
|
||||
|
||||
Assert.Equal("2/3", state.Playlist[0].PageText);
|
||||
Assert.True(state.Playlist[2].IsSelected);
|
||||
Assert.False(state.Playlist[0].IsSelected);
|
||||
Assert.Equal(2, controller.CreatePlayoutRequest().SelectedIndexZeroBased);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TakeSkipMovesOnlyTheF8CandidateAndPreservesDeleteSelection()
|
||||
{
|
||||
var controller = await CreateControllerWithCutsAsync(2);
|
||||
var rows = controller.Current.Playlist;
|
||||
controller.SelectPlaylistRow(rows[0].RowId, control: false, shift: false);
|
||||
controller.ReflectSuccessfulPlayout(
|
||||
rows[0].RowId,
|
||||
pageIndexZeroBased: 2,
|
||||
pageCount: 3,
|
||||
synchronizeOperatorSelection: false);
|
||||
|
||||
var state = controller.ReflectSuccessfulPlayout(
|
||||
rows[1].RowId,
|
||||
pageIndexZeroBased: 0,
|
||||
pageCount: 2,
|
||||
synchronizeOperatorSelection: true);
|
||||
|
||||
Assert.Equal("1/2", state.Playlist[1].PageText);
|
||||
Assert.True(state.Playlist[0].IsSelected);
|
||||
Assert.False(state.Playlist[1].IsSelected);
|
||||
Assert.True(state.Playlist[1].IsActive);
|
||||
Assert.Equal(1, controller.CreatePlayoutRequest().SelectedIndexZeroBased);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SuccessfulF8DoesNotReplaceTheRowsAccumulatedForDelete()
|
||||
{
|
||||
var controller = await CreateControllerWithCutsAsync(3);
|
||||
var rows = controller.Current.Playlist;
|
||||
controller.SelectPlaylistRow(rows[0].RowId, control: false, shift: false);
|
||||
controller.SelectPlaylistRow(rows[2].RowId, control: true, shift: false);
|
||||
|
||||
var reflected = controller.ReflectSuccessfulPlayout(
|
||||
rows[2].RowId,
|
||||
pageIndexZeroBased: 0,
|
||||
pageCount: 1,
|
||||
synchronizeOperatorSelection: true);
|
||||
|
||||
Assert.Equal(
|
||||
[rows[0].RowId, rows[2].RowId],
|
||||
reflected.Playlist.Where(row => row.IsSelected).Select(row => row.RowId));
|
||||
Assert.True(reflected.Playlist[2].IsActive);
|
||||
|
||||
var deleted = controller.DeleteSelectedPlaylistRows();
|
||||
Assert.Equal(rows[1].RowId, Assert.Single(deleted.Playlist).RowId);
|
||||
}
|
||||
|
||||
private static async Task<LegacyOperatorController> CreateControllerWithCutsAsync(int count)
|
||||
{
|
||||
var controller = new LegacyOperatorController(new StaticLookup());
|
||||
await controller.SearchStocksAsync("?쇱꽦", LegacySearchTrigger.Button);
|
||||
controller.SelectStock(0);
|
||||
for (var index = 0; index < count; index++)
|
||||
{
|
||||
AddCut(controller, index, 1_000 + (index * 1_000));
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
private static LegacyOperatorPlaylistRow OperatorRow(
|
||||
string graphicType,
|
||||
string pageText) =>
|
||||
new(
|
||||
"row-1",
|
||||
true,
|
||||
"테마",
|
||||
"반도체",
|
||||
graphicType,
|
||||
"현재가",
|
||||
pageText,
|
||||
"00123",
|
||||
"paged-cut",
|
||||
6,
|
||||
SceneAlias: "5074",
|
||||
PlayoutSelection: new(
|
||||
"테마",
|
||||
"반도체",
|
||||
graphicType,
|
||||
"현재가",
|
||||
"00123"));
|
||||
|
||||
private static void AddCut(
|
||||
LegacyOperatorController controller,
|
||||
int physicalIndex,
|
||||
|
||||
Reference in New Issue
Block a user