174 lines
8.0 KiB
C#
174 lines
8.0 KiB
C#
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
|
|
|
|
public sealed class LegacyThemeWebParityTests
|
|
{
|
|
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 Styles = File.ReadAllText(Path.Combine(WebRoot, "styles.css"));
|
|
|
|
[Fact]
|
|
public void Theme_workspace_matches_original_vertical_visible_order_and_action_order()
|
|
{
|
|
var renderTheme = Extract(
|
|
App,
|
|
" function renderTheme(state) {",
|
|
" function renderExpert(state) {");
|
|
|
|
Assert.Contains("input.setAttribute(\"aria-label\", \"테마명\");", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("searchButton.textContent = \"테마검색\";", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("search.append(input, searchButton, addTheme, editTheme, deleteTheme);",
|
|
renderTheme, StringComparison.Ordinal);
|
|
Assert.Contains("resultsTitle.textContent = \"테마명\";", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("previewTitle.textContent = \"종목명\";", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("sortControls.className = \"theme-sort-controls\";", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("radio.type = \"radio\";", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"workspace.append(search, resultsPanel, sortControls, actions, previewPanel);",
|
|
renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("theme-body", renderTheme, StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"grid-template-rows: auto minmax(72px, .8fr) auto auto minmax(72px, 1fr)",
|
|
Styles,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("grid-template-columns: repeat(4, minmax(0, 1fr))", Styles,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"[\"six-row-current\", 0],\n" +
|
|
" [\"twelve-row-current\", 1],\n" +
|
|
" [\"five-row-current\", 2],\n" +
|
|
" [\"five-row-expected\", 3]",
|
|
renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("[\"six-row-current\", \"6종목 현재가\"]", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("[\"twelve-row-current\", \"12종목 현재가\"]", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("[\"five-row-current\", \"현재가\"]", renderTheme,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("[\"five-row-expected\", \"예상체결가\"]", renderTheme,
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Main_theme_workspace_does_not_expose_the_non_original_NXT_session_selector()
|
|
{
|
|
var renderTheme = Extract(
|
|
App,
|
|
" function renderTheme(state) {",
|
|
" function renderExpert(state) {");
|
|
var clickDelegate = Extract(
|
|
App,
|
|
" categoryTree.addEventListener(\"click\", function (event) {",
|
|
" categoryTree.addEventListener(\"change\", function (event) {");
|
|
|
|
Assert.DoesNotContain("theme-nxt-session", App, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("themeSearchNxtSession", App, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("nxtSession", clickDelegate, StringComparison.Ordinal);
|
|
Assert.Contains("send(\"search-themes\", { query: input ? input.value : \"\" });",
|
|
clickDelegate, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Selection_receipt_updates_existing_theme_rows_without_replacing_click_target_or_focus()
|
|
{
|
|
var renderTheme = Extract(
|
|
App,
|
|
" function renderTheme(state) {",
|
|
" function renderExpert(state) {");
|
|
var structureIdentity = Extract(
|
|
renderTheme,
|
|
" const structureKey = JSON.stringify({",
|
|
" const existingWorkspace = categoryTree.querySelector(\".theme-workspace\");");
|
|
var selectionReceipt = Extract(
|
|
renderTheme,
|
|
" if (existingWorkspace && structureKey === themeRenderStructureKey) {",
|
|
" const workspace = document.createElement(\"div\");");
|
|
var updater = Extract(
|
|
App,
|
|
" function updateThemeWorkspace(workspace, theme) {",
|
|
" function renderTheme(state) {");
|
|
|
|
Assert.DoesNotContain("selectedResultId", structureIdentity, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("selectedTheme", structureIdentity, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("previewItems", structureIdentity, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("isAvailable", structureIdentity, StringComparison.Ordinal);
|
|
Assert.Contains("updateThemeWorkspace(existingWorkspace, theme);", selectionReceipt,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("return;", selectionReceipt, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("replaceChildren", selectionReceipt, StringComparison.Ordinal);
|
|
Assert.Contains("syncSearchDraft(input, theme.query)", updater,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("button.classList.toggle(\"selected\", selected);", updater,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("button.setAttribute(\"aria-selected\"", updater,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("results.replaceChildren", updater, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("categoryTree.replaceChildren", updater, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void NXT_expected_price_action_stays_clickable_so_native_can_show_the_legacy_warning()
|
|
{
|
|
var clickability = Extract(
|
|
App,
|
|
" function themeActionIsClickable(action) {",
|
|
" function updateThemeWorkspace(workspace, theme) {");
|
|
var updater = Extract(
|
|
App,
|
|
" function updateThemeWorkspace(workspace, theme) {",
|
|
" function renderTheme(state) {");
|
|
var clickDelegate = Extract(
|
|
App,
|
|
" categoryTree.addEventListener(\"click\", function (event) {",
|
|
" categoryTree.addEventListener(\"change\", function (event) {");
|
|
|
|
Assert.Contains("action.actionId === \"five-row-expected\"", clickability,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("action.unavailableReason === \"expected-theme-is-krx-only\"",
|
|
clickability, StringComparison.Ordinal);
|
|
Assert.Contains("button.disabled = !themeActionIsClickable(action);", updater,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("? \"NXT는 데이터가 없습니다.\"", updater,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("send(\"activate-theme-action\"", clickDelegate,
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
private static string Extract(string source, string startToken, string endToken)
|
|
{
|
|
var start = source.IndexOf(startToken, StringComparison.Ordinal);
|
|
var end = source.IndexOf(endToken, start + startToken.Length, StringComparison.Ordinal);
|
|
Assert.True(start >= 0, $"Start token was not found: {startToken}");
|
|
Assert.True(end > start, $"End token was not found after start token: {endToken}");
|
|
return source[start..end];
|
|
}
|
|
|
|
private static string FindRepositoryRoot()
|
|
{
|
|
var directory = new DirectoryInfo(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("Repository root was not found.");
|
|
}
|
|
}
|