193 lines
8.8 KiB
C#
193 lines
8.8 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
|
|
|
|
public sealed class LegacyIndustryListWebContractTests
|
|
{
|
|
private static readonly string RepositoryRoot = FindRepositoryRoot();
|
|
private static readonly string App = File.ReadAllText(Path.Combine(
|
|
RepositoryRoot,
|
|
"src",
|
|
"MBN_STOCK_WEBVIEW.LegacyParityApp",
|
|
"Web",
|
|
"app.js"));
|
|
|
|
[Fact]
|
|
public void Industry_list_is_one_tab_stop_and_rows_are_programmatic_descendants()
|
|
{
|
|
var renderIndustry = Extract(
|
|
App,
|
|
" function renderIndustry(state) {",
|
|
" function renderOverseas(state) {");
|
|
var listFactory = Extract(
|
|
renderIndustry,
|
|
" const list = document.createElement(\"div\");",
|
|
" const comparisonTitle = document.createElement(\"strong\");");
|
|
|
|
Assert.Contains("list.setAttribute(\"role\", \"listbox\");", listFactory,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("list.tabIndex = 0;", listFactory, StringComparison.Ordinal);
|
|
Assert.Contains("industry.industries.forEach(function (row) {", listFactory,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("button.dataset.industryIndex = String(row.index);", listFactory,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("button.tabIndex = -1;", listFactory, StringComparison.Ordinal);
|
|
Assert.Contains("button.setAttribute(\"role\", \"option\");", listFactory,
|
|
StringComparison.Ordinal);
|
|
Assert.Single(Regex.Matches(listFactory, @"\.tabIndex\s*=\s*0;").Cast<Match>());
|
|
Assert.DoesNotContain("button.tabIndex = 0;", listFactory, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Industry_list_handles_arrow_home_and_end_navigation()
|
|
{
|
|
var keyHandler = Extract(
|
|
App,
|
|
" categoryTree.addEventListener(\"keydown\", function (event) {",
|
|
" window.addEventListener(\"pointerup\", function () {");
|
|
|
|
Assert.Contains("const industryList = event.target.closest(\".industry-list\");",
|
|
keyHandler, StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"[\"ArrowUp\", \"ArrowDown\", \"Home\", \"End\"].includes(event.key)",
|
|
keyHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("event.preventDefault();", keyHandler, StringComparison.Ordinal);
|
|
Assert.Contains("if (event.key === \"Home\") nextIndex = 0;", keyHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("else if (event.key === \"End\") nextIndex = rows.length - 1;",
|
|
keyHandler, StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"else if (event.key === \"ArrowUp\") nextIndex = Math.max(0, selectedIndex - 1);",
|
|
keyHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"else nextIndex = Math.min(rows.length - 1, selectedIndex + 1);",
|
|
keyHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("selectIndustryRow(nextRow);", keyHandler, StringComparison.Ordinal);
|
|
Assert.Contains("nextRow.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });",
|
|
keyHandler, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Selection_only_state_receipt_updates_rows_without_replacing_the_workspace()
|
|
{
|
|
var renderIndustry = Extract(
|
|
App,
|
|
" function renderIndustry(state) {",
|
|
" function renderOverseas(state) {");
|
|
var structureIdentity = Extract(
|
|
renderIndustry,
|
|
" const structureKey = JSON.stringify({",
|
|
" const existingWorkspace = categoryTree.querySelector(\".industry-workspace\");");
|
|
var selectionOnlyReceipt = Extract(
|
|
renderIndustry,
|
|
" if (existingWorkspace && structureKey === industryRenderStructureKey) {",
|
|
" const previousList = categoryTree.querySelector(\".industry-list\");");
|
|
|
|
Assert.Contains("market: industry.market", structureIdentity, StringComparison.Ordinal);
|
|
Assert.Contains("rows: industry.industries.map", structureIdentity,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("actions: industry.actions.map", structureIdentity,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("selectedIndex", structureIdentity, StringComparison.Ordinal);
|
|
|
|
Assert.Contains("existingWorkspace.querySelectorAll(\"button[data-industry-index]\")",
|
|
selectionOnlyReceipt, StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"const selected = Number(row.dataset.industryIndex) === industry.selectedIndex;",
|
|
selectionOnlyReceipt,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("row.classList.toggle(\"selected\", selected);", selectionOnlyReceipt,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains(
|
|
"row.setAttribute(\"aria-selected\", selected ? \"true\" : \"false\");",
|
|
selectionOnlyReceipt,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("return;", selectionOnlyReceipt, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("replaceChildren", selectionOnlyReceipt, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("document.createElement", selectionOnlyReceipt,
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Industry_list_is_appended_before_comparison_label_and_slots()
|
|
{
|
|
var renderIndustry = Extract(
|
|
App,
|
|
" function renderIndustry(state) {",
|
|
" function renderOverseas(state) {");
|
|
|
|
Assert.Contains("comparisonTitle.textContent = \"업종비교\";", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("selector.append(list, comparisonTitle, slots);", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("selector.append(comparisonTitle, slots, list);", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Comparison_text_boxes_commit_closed_text_intents_without_replacing_focused_dom()
|
|
{
|
|
var renderIndustry = Extract(
|
|
App,
|
|
" function renderIndustry(state) {",
|
|
" function renderOverseas(state) {");
|
|
var changeHandler = Extract(
|
|
App,
|
|
" categoryTree.addEventListener(\"change\", function (event) {",
|
|
" categoryTree.addEventListener(\"keydown\", function (event) {");
|
|
|
|
Assert.Contains("first.dataset.industrySlot = \"first\";", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("second.dataset.industrySlot = \"second\";", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("first.maxLength = 128;", renderIndustry, StringComparison.Ordinal);
|
|
Assert.Contains("second.maxLength = 128;", renderIndustry, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("first.readOnly = true;", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("second.readOnly = true;", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("firstName: industry.firstName", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.DoesNotContain("secondName: industry.secondName", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("document.activeElement !== firstInput", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("document.activeElement !== secondInput", renderIndustry,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("send(\"set-industry-comparison-text\"", changeHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("slot: event.target.dataset.industrySlot", changeHandler,
|
|
StringComparison.Ordinal);
|
|
Assert.Contains("value: event.target.value", changeHandler,
|
|
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.");
|
|
}
|
|
}
|