feat: restore legacy drag events and Tornado launch integration

This commit is contained in:
2026-07-15 15:35:25 +09:00
parent 6e0c275fdd
commit 06a16e5741
32 changed files with 3096 additions and 101 deletions

View File

@@ -61,6 +61,31 @@ public sealed class LegacyBridgeProtocolTests
out _));
}
[Fact]
public void ParsePlaylistReorder_UsesOnlyOpaqueRowsAndClosedDropPosition()
{
Assert.True(LegacyBridgeProtocol.TryParseIntent(
"{\"type\":\"reorder-playlist-rows\",\"payload\":{\"sourceRowId\":\"legacy-stock-00000001\",\"targetRowId\":\"legacy-stock-00000004\",\"position\":\"before\"}}",
out var parsed,
out _));
var reorder = Assert.IsType<LegacyReorderPlaylistRowsIntent>(parsed);
Assert.Equal("legacy-stock-00000001", reorder.SourceRowId);
Assert.Equal("legacy-stock-00000004", reorder.TargetRowId);
Assert.Equal(LegacyDragDropPosition.Before, reorder.Position);
foreach (var invalid in new[]
{
"{\"type\":\"reorder-playlist-rows\",\"payload\":{\"sourceRowId\":\"../row\",\"targetRowId\":\"legacy-stock-00000004\",\"position\":\"before\"}}",
"{\"type\":\"reorder-playlist-rows\",\"payload\":{\"sourceRowId\":\"legacy-stock-00000001\",\"targetRowId\":\"legacy-stock-00000001\",\"position\":\"before\"}}",
"{\"type\":\"reorder-playlist-rows\",\"payload\":{\"sourceRowId\":\"legacy-stock-00000001\",\"targetRowId\":\"legacy-stock-00000004\",\"position\":\"middle\"}}",
"{\"type\":\"reorder-playlist-rows\",\"payload\":{\"sourceRowId\":\"legacy-stock-00000001\",\"targetRowId\":\"legacy-stock-00000004\",\"position\":\"before\",\"targetIndex\":3}}"
})
{
Assert.False(LegacyBridgeProtocol.TryParseIntent(invalid, out _, out _));
}
}
[Fact]
public void ParseAllPlaylistEnabled_RequiresOnlyBooleanState()
{
@@ -96,6 +121,19 @@ public sealed class LegacyBridgeProtocolTests
Assert.Equal(LegacyOperatorTabId.Theme, parsedSwap.Source);
Assert.Equal(LegacyOperatorTabId.Exchange, parsedSwap.Target);
Assert.True(LegacyBridgeProtocol.TryParseIntent(
"{\"type\":\"hover-swap-tabs\",\"payload\":{\"source\":\"theme\",\"target\":\"exchange\",\"expectedSourceIndex\":6,\"expectedTargetIndex\":1}}",
out var hoverSwap,
out _));
var parsedHover = Assert.IsType<LegacyHoverSwapTabsIntent>(hoverSwap);
Assert.Equal(6, parsedHover.ExpectedSourceIndex);
Assert.Equal(1, parsedHover.ExpectedTargetIndex);
Assert.False(LegacyBridgeProtocol.TryParseIntent(
"{\"type\":\"hover-swap-tabs\",\"payload\":{\"source\":\"theme\",\"target\":\"exchange\",\"expectedSourceIndex\":6,\"expectedTargetIndex\":10}}",
out _,
out _));
Assert.False(LegacyBridgeProtocol.TryParseIntent(
"{\"type\":\"select-tab\",\"payload\":{\"tabId\":\"scene5001\"}}",
out _,

View File

@@ -41,6 +41,10 @@ public sealed class LegacyOperatorCatalogBridgeTests
Assert.IsType<LegacyMoveOperatorCatalogDraftRowIntent>(ParseRequired(
"move-operator-catalog-draft-row",
"""{"rowId":"catalog-draft-0123456789abcdef","direction":"up"}"""));
var reorder = Assert.IsType<LegacyReorderOperatorCatalogDraftRowIntent>(ParseRequired(
"reorder-operator-catalog-draft-row",
"""{"sourceRowId":"catalog-draft-0123456789abcdef","targetRowId":"catalog-draft-fedcba9876543210","position":"after"}"""));
Assert.Equal(LegacyDragDropPosition.After, reorder.Position);
Assert.IsType<LegacyRemoveOperatorCatalogDraftRowIntent>(ParseRequired(
"remove-operator-catalog-draft-row",
"""{"rowId":"catalog-draft-0123456789abcdef"}"""));
@@ -55,6 +59,11 @@ public sealed class LegacyOperatorCatalogBridgeTests
{"type":"select-operator-catalog-stock","payload":{"stockCode":"005930"}}
""",
out _));
Assert.False(Parse(
"""
{"type":"reorder-operator-catalog-draft-row","payload":{"sourceRowId":"catalog-draft-0123456789abcdef","targetRowId":"catalog-draft-fedcba9876543210","position":"after","playIndex":1}}
""",
out _));
}
[Fact]
@@ -72,6 +81,10 @@ public sealed class LegacyOperatorCatalogBridgeTests
Assert.Equal(70_000, Assert.IsType<LegacyAddOperatorCatalogStockIntent>(ParseRequired(
"add-operator-catalog-stock",
"""{"buyAmount":70000}""")).BuyAmount);
Assert.Equal("AI 반도체", Assert.IsType<LegacyCheckOperatorCatalogThemeNameIntent>(
ParseRequired(
"check-operator-catalog-theme-name",
"""{"name":"AI "}""")).Name);
Assert.Equal("김전문", Assert.IsType<LegacySaveOperatorCatalogIntent>(ParseRequired(
"save-operator-catalog",
"""{"name":""}""")).Name);
@@ -84,6 +97,16 @@ public sealed class LegacyOperatorCatalogBridgeTests
{"type":"save-operator-catalog","payload":{"name":"김전문","expertCode":"0001"}}
""",
out _));
Assert.False(Parse(
"""
{"type":"check-operator-catalog-theme-name","payload":{"name":"AI 반도체","market":"krx"}}
""",
out _));
Assert.False(Parse(
"""
{"type":"check-operator-catalog-theme-name","payload":{"name":" AI 반도체"}}
""",
out _));
Assert.False(Parse(
"""
{"type":"add-operator-catalog-stock","payload":{"buyAmount":1.5}}
@@ -114,6 +137,8 @@ public sealed class LegacyOperatorCatalogBridgeTests
"catalog-result-0123456789abcdef",
"00000001",
"AI 반도체",
LegacyThemeNameAvailability.Duplicate,
"AI 반도체",
[
new LegacyOperatorCatalogDraftRowView(
"catalog-draft-0123456789abcdef",
@@ -139,6 +164,7 @@ public sealed class LegacyOperatorCatalogBridgeTests
true,
true,
true,
true,
"편집 중",
LegacyOperatorCatalogStatusKind.Information);
var snapshot = new LegacyOperatorSnapshot(
@@ -157,6 +183,10 @@ public sealed class LegacyOperatorCatalogBridgeTests
Assert.Contains("catalog-result-0123456789abcdef", json, StringComparison.Ordinal);
Assert.Contains("codeLabel", json, StringComparison.Ordinal);
Assert.Contains("themeNameAvailability", json, StringComparison.Ordinal);
Assert.Contains("checkedThemeName", json, StringComparison.Ordinal);
Assert.Contains("canCheckThemeName", json, StringComparison.Ordinal);
Assert.Contains("duplicate", json, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("themeCode", json, StringComparison.Ordinal);
Assert.DoesNotContain("expertCode", json, StringComparison.Ordinal);
Assert.DoesNotContain("stockCode", json, StringComparison.Ordinal);