Files
MBN_STOCK_WEBVIEW/tests/MBN_STOCK_WEBVIEW.LegacyWeb.Tests/LegacyWebContractTests.cs

123 lines
4.5 KiB
C#

using System.Text.RegularExpressions;
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyWebContractTests
{
private static readonly string RepositoryRoot = FindRepositoryRoot();
private static readonly string WebRoot = Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"Web");
private static readonly string App = File.ReadAllText(Path.Combine(WebRoot, "app.js"));
private static readonly string Markup = File.ReadAllText(Path.Combine(WebRoot, "index.html"));
private static readonly string Styles = File.ReadAllText(Path.Combine(WebRoot, "styles.css"));
[Fact]
public void ShellExposesOriginalStockCutPlaylistAndPlayoutControls()
{
foreach (var id in new[]
{
"stock-search",
"stock-search-button",
"stock-results",
"cut-list",
"playlist-drop-zone",
"playlist-rows",
"legacy-dialog"
})
{
Assert.Contains($"id=\"{id}\"", Markup, StringComparison.Ordinal);
}
Assert.Contains("TAKE IN", Markup, StringComparison.Ordinal);
Assert.Contains("TAKE OUT", Markup, StringComparison.Ordinal);
Assert.Contains("NEXT", Markup, StringComparison.Ordinal);
Assert.Matches("class=\"connection-state\"[^>]*>미연결</div>", Markup);
Assert.Contains(
"class=\"active\" type=\"button\" disabled>해외</button>",
Markup,
StringComparison.Ordinal);
Assert.Contains(
"type=\"button\" disabled>정지</button>",
Markup,
StringComparison.Ordinal);
}
[Fact]
public void WebLayerDoesNotOwnSceneDatabaseIdentityOrPlaylistState()
{
Assert.DoesNotMatch(
new Regex("(?:sceneCode|cutCode|stockCode|dataCode|builderKey)"),
App);
Assert.DoesNotMatch(
new Regex("(?:localStorage|sessionStorage|playlist\\.push|fetch\\s*\\()"),
App);
Assert.DoesNotMatch(
new Regex("\\b(?:5001|N5001|5006|5011|5086|8035|8061|8040|8046|8051|8056|8003|5037)\\b"),
App);
}
[Fact]
public void DoubleClickUsesPointerFactsInsteadOfBrowserPolicy()
{
Assert.Contains("cut-pointer-down", App, StringComparison.Ordinal);
Assert.Contains("timestampMilliseconds", App, StringComparison.Ordinal);
Assert.Contains("event.ctrlKey", App, StringComparison.Ordinal);
Assert.Contains("event.shiftKey", App, StringComparison.Ordinal);
Assert.DoesNotContain("dblclick", App, StringComparison.Ordinal);
}
[Fact]
public void CutRowsAreReconciledInPlace()
{
Assert.Contains("dataset.physicalIndex", App, StringComparison.Ordinal);
Assert.Contains("function createCutElement", App, StringComparison.Ordinal);
Assert.DoesNotContain("cutList.replaceChildren", App, StringComparison.Ordinal);
}
[Fact]
public void StockAndPlaylistRowsPreserveNativeControlFocus()
{
Assert.Contains("dataset.resultIndex", App, StringComparison.Ordinal);
Assert.Contains("dataset.rowId", App, StringComparison.Ordinal);
Assert.DoesNotContain("stockResults.replaceChildren", App, StringComparison.Ordinal);
Assert.DoesNotContain("playlistRows.replaceChildren", App, StringComparison.Ordinal);
}
[Fact]
public void SeparatorRowsPreserveOriginalDragGesture()
{
Assert.Contains("element.draggable = true", App, StringComparison.Ordinal);
Assert.DoesNotContain("draggable = !row.isSeparator", App, StringComparison.Ordinal);
}
[Fact]
public void BusySnapshotFreezesControlsWithoutQueueingInput()
{
Assert.Contains("state.isBusy === true", App, StringComparison.Ordinal);
Assert.Contains("classList.toggle(\"busy\"", App, StringComparison.Ordinal);
Assert.Contains(
"body.busy .operator-shell { pointer-events: none; }",
Styles,
StringComparison.Ordinal);
}
private static string FindRepositoryRoot()
{
DirectoryInfo? directory = new(AppContext.BaseDirectory);
while (directory is not null)
{
if (File.Exists(Path.Combine(directory.FullName, "MBN_STOCK_WEBVIEW.sln")))
{
return directory.FullName;
}
directory = directory.Parent;
}
throw new DirectoryNotFoundException("The repository root could not be located.");
}
}