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

222 lines
9.8 KiB
C#

using System.Text.RegularExpressions;
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyManualFinancialParityWebTests
{
private static readonly string RepositoryRoot = FindRepositoryRoot();
private static readonly string WebRoot = Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"Web");
private static readonly string Markup = File.ReadAllText(Path.Combine(WebRoot, "index.html"));
private static readonly string App = File.ReadAllText(Path.Combine(WebRoot, "app.js"));
private static readonly string Styles = File.ReadAllText(Path.Combine(WebRoot, "styles.css"));
private static readonly string MainWindow = File.ReadAllText(Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"MainWindow.xaml.cs"));
[Theory]
[InlineData("revenue-composition", "주요매출 구성")]
[InlineData("growth-metrics", "성장성 지표")]
[InlineData("sales", "매출액")]
[InlineData("operating-profit", "영업이익")]
public void Original_left_GraphE_buttons_are_enabled_closed_screen_intents(
string screen,
string label)
{
Assert.Matches(
$"<button(?![^>]*disabled)[^>]*data-manual-screen=\"{screen}\"[^>]*>{label}</button>",
Markup);
}
[Fact]
public void Modal_exposes_list_stock_editor_CRUD_and_playlist_controls()
{
foreach (var id in new[]
{
"manual-financial-modal",
"manual-financial-title",
"manual-financial-close",
"manual-financial-workspace"
})
{
Assert.Contains($"id=\"{id}\"", Markup, StringComparison.Ordinal);
}
foreach (var intent in new[]
{
"open-manual-financial",
"close-manual-financial",
"search-manual-financial",
"find-manual-financial",
"toggle-manual-financial-name-sort",
"load-manual-financial",
"begin-manual-financial-create",
"search-manual-financial-stocks",
"select-manual-financial-stock",
"save-manual-financial",
"delete-manual-financial",
"delete-all-manual-financial",
"activate-manual-financial-action"
})
{
Assert.Contains($"\"{intent}\"", App, StringComparison.Ordinal);
}
Assert.Contains(".manual-financial-dialog", Styles, StringComparison.Ordinal);
Assert.Contains(".manual-financial-grid", Styles, StringComparison.Ordinal);
}
[Fact]
public void GraphE_find_and_name_header_sort_are_generation_bound_native_intents()
{
Assert.Contains("manual-financial-find-query", App, StringComparison.Ordinal);
Assert.Contains("dataset.manualFindDirection", App, StringComparison.Ordinal);
Assert.Contains("dataset.manualNameSort", App, StringComparison.Ordinal);
Assert.Contains("dataset.manualGeneration", App, StringComparison.Ordinal);
Assert.Contains("send(\"find-manual-financial\"", App, StringComparison.Ordinal);
Assert.Contains(
"send(\"toggle-manual-financial-name-sort\"",
App,
StringComparison.Ordinal);
Assert.Contains("generation: generation", App, StringComparison.Ordinal);
}
[Fact]
public void GraphE_two_row_toolbar_keeps_find_controls_pointer_accessible()
{
Assert.Contains(
".manual-financial-workspace { min-height: 0; display: grid; " +
"grid-template-rows: auto minmax(0, 1fr);",
Styles,
StringComparison.Ordinal);
Assert.DoesNotContain(
".manual-financial-workspace { min-height: 0; display: grid; " +
"grid-template-rows: 38px minmax(0, 1fr);",
Styles,
StringComparison.Ordinal);
}
[Fact]
public void GraphE_uses_only_the_four_same_origin_packaged_reference_images()
{
foreach (var relativePath in new[]
{
"./Previews/pie.bmp",
"./Previews/Grow.bmp",
"./Previews/sell.bmp",
"./Previews/profit.bmp"
})
{
Assert.Contains($"\"{relativePath}\"", App, StringComparison.Ordinal);
}
Assert.Contains("manualFinancialReferenceFigure", App, StringComparison.Ordinal);
Assert.Contains("기존 송출 화면 참고 이미지", App, StringComparison.Ordinal);
Assert.Contains(".manual-financial-reference img", Styles, StringComparison.Ordinal);
Assert.DoesNotContain("../Res/", App, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("legacy-res.mbn.local", App, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void GraphE_list_projects_bounded_read_only_preview_cells_without_native_authority()
{
var start = App.IndexOf("function manualFinancialPreviewColumns", StringComparison.Ordinal);
var end = App.IndexOf("function blankManualRecord", start, StringComparison.Ordinal);
Assert.True(start >= 0 && end > start);
var preview = App[start..end];
Assert.Contains("row.previewValues", preview, StringComparison.Ordinal);
Assert.Contains("slice(0, count)", preview, StringComparison.Ordinal);
Assert.Contains(
"const cell = manualElement(\"span\", \"manual-financial-preview-cell\", value);",
App,
StringComparison.Ordinal);
Assert.DoesNotMatch(
new Regex("(?:ROWID|ROW_HANDLE|rowVersion|stockCode|resultId)"),
preview);
Assert.Contains("manual-financial-preview-columns-", App, StringComparison.Ordinal);
Assert.Contains("manual-financial-preview-cell", App, StringComparison.Ordinal);
Assert.Contains(".manual-financial-preview-cell", Styles, StringComparison.Ordinal);
}
[Fact]
public void Explicit_different_stock_selection_resets_only_a_create_mode_draft()
{
Assert.Contains("function shouldResetManualStockDraft", App, StringComparison.Ordinal);
Assert.Contains("stockIsSelected !== true && stockNameReadOnly !== true", App,
StringComparison.Ordinal);
Assert.Contains("draft.rawMode !== true", App, StringComparison.Ordinal);
var start = App.IndexOf(
"function selectManualFinancialStock",
StringComparison.Ordinal);
var end = App.IndexOf(
"function captureManualDraftForChangedModel",
start,
StringComparison.Ordinal);
Assert.True(start >= 0 && end > start);
var helper = App[start..end];
Assert.Contains("rememberManualDraft();", helper, StringComparison.Ordinal);
Assert.Contains("manualDraft = blankManualRecord(manualDraft.screen);", helper,
StringComparison.Ordinal);
Assert.Contains("manualDraftResetPending = true;", helper, StringComparison.Ordinal);
Assert.Contains("manualDraft = previousDraft;", helper, StringComparison.Ordinal);
}
[Fact]
public void Manual_Web_section_sends_values_and_opaque_ids_without_DB_or_scene_authority()
{
var start = App.IndexOf("function blankManualRecord", StringComparison.Ordinal);
var end = App.IndexOf("function renderDialog", start, StringComparison.Ordinal);
Assert.True(start >= 0 && end > start);
var manualSection = App[start..end];
Assert.DoesNotMatch(
new Regex("(?:INPUT_PIE|INPUT_GROW|INPUT_SELL|INPUT_PROFIT|s5076|s5079|s5080|s5081|rowVersion|builderKey|cutCode|dataCode|confirmationToken)"),
manualSection);
Assert.Contains("dataset.manualResultId", manualSection, StringComparison.Ordinal);
Assert.Contains("dataset.manualStockResultId", manualSection, StringComparison.Ordinal);
Assert.Contains("dataset.manualActionId", manualSection, StringComparison.Ordinal);
}
[Fact]
public void MainWindow_composes_real_read_and_one_shot_write_services_and_busy_dispatch()
{
Assert.Contains("new LegacyManualFinancialScreenService(", MainWindow, StringComparison.Ordinal);
Assert.Contains("new OracleManualFinancialMutationExecutor(", MainWindow, StringComparison.Ordinal);
Assert.Contains("new LegacyStockSearchService(", MainWindow, StringComparison.Ordinal);
Assert.Contains("manualFinancialWorkflow: new LegacyManualFinancialWorkflow(", MainWindow, StringComparison.Ordinal);
Assert.Contains("LegacySaveManualFinancialIntent", MainWindow, StringComparison.Ordinal);
Assert.Contains("LegacyDeleteManualFinancialIntent", MainWindow, StringComparison.Ordinal);
Assert.Contains("LegacyDeleteAllManualFinancialIntent", MainWindow, StringComparison.Ordinal);
Assert.Contains("_intentGate.WaitAsync(", MainWindow, StringComparison.Ordinal);
Assert.Matches(
new Regex(@"_intentGate\.WaitAsync\(\s*0,\s*_lifetimeCancellation\.Token\)"),
MainWindow);
Assert.DoesNotContain("SaveManualFinancialAsync(", MainWindow[..MainWindow.IndexOf(
"HandleIntentAsync",
StringComparison.Ordinal)], StringComparison.Ordinal);
}
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.");
}
}