using System.Text.Json; using MBN_STOCK_WEBVIEW.LegacyApplication; using MBN_STOCK_WEBVIEW.LegacyBridge; namespace MBN_STOCK_WEBVIEW.LegacyBridge.Tests; public sealed class LegacyBridgeProtocolTests { [Fact] public void ParseSearch_PreservesBlankEnterAndRejectsExtraAuthority() { Assert.True(LegacyBridgeProtocol.TryParseIntent( "{\"type\":\"search-stocks\",\"payload\":{\"text\":\"\",\"trigger\":\"enter\"}}", out var parsed, out var error)); Assert.Null(error); var search = Assert.IsType(parsed); Assert.Equal(string.Empty, search.Text); Assert.Equal(LegacySearchTrigger.Enter, search.Trigger); Assert.False(LegacyBridgeProtocol.TryParseIntent( "{\"type\":\"search-stocks\",\"payload\":{\"text\":\"삼성\",\"trigger\":\"button\",\"sceneCode\":\"5001\"}}", out _, out _)); } [Fact] public void ParsePointer_RequiresExactBoundedInput() { const string json = "{\"type\":\"cut-pointer-down\",\"payload\":{\"physicalIndex\":1,\"control\":false,\"shift\":true,\"x\":20,\"y\":45,\"timestampMilliseconds\":1400}}"; Assert.True(LegacyBridgeProtocol.TryParseIntent(json, out var parsed, out _)); var pointer = Assert.IsType(parsed); Assert.Equal(1, pointer.PhysicalIndex); Assert.True(pointer.Shift); Assert.Equal(1_400, pointer.TimestampMilliseconds); } [Theory] [InlineData("https://legacy-parity.mbn.local/index.html", true)] [InlineData("https://legacy-parity.mbn.local.evil/index.html", false)] [InlineData("http://legacy-parity.mbn.local/index.html", false)] [InlineData("file:///C:/index.html", false)] public void TrustedSource_IsExactHttpsOrigin(string source, bool expected) { Assert.Equal(expected, LegacyBridgeProtocol.IsTrustedSource(source)); } [Fact] public void SerializedState_DoesNotExposeHiddenDbOrSceneAuthority() { var playlistRow = LegacyStockCutCatalog.CreatePlaylistRow( "legacy-stock-00000001", "삼성전자", new LegacyStockIdentity(LegacyDomesticStockMarket.Kospi, "삼성전자", "005930"), LegacyStockCutCatalog.Rows[1]); var snapshot = new LegacyOperatorSnapshot( 1, "삼성", [new LegacyStockResultRow(0, "삼성전자")], 0, [new LegacyCutViewRow(1, 2, "1열판기본_현재가", false, true)], [playlistRow], null, string.Empty, LegacyOperatorStatusKind.Neutral); var json = LegacyBridgeProtocol.SerializeState(snapshot, isBusy: true); Assert.DoesNotContain("005930", json, StringComparison.Ordinal); Assert.DoesNotContain("5001", json, StringComparison.Ordinal); Assert.DoesNotContain("rawCutLabel", json, StringComparison.Ordinal); using var document = JsonDocument.Parse(json); var payload = document.RootElement.GetProperty("payload"); Assert.Equal( "삼성전자", payload.GetProperty("searchResults")[0].GetProperty("displayName").GetString()); Assert.Equal( "삼성전자", payload.GetProperty("playlist")[0].GetProperty("stockName").GetString()); Assert.Equal( "1열판기본_현재가", payload.GetProperty("cutRows")[0].GetProperty("rawLabel").GetString()); Assert.True(payload.GetProperty("isBusy").GetBoolean()); } }