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

109 lines
4.4 KiB
C#

namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyFixedSectionBatchWebTests
{
private static readonly string RepositoryRoot = FindRepositoryRoot();
private static readonly string App = File.ReadAllText(Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"Web",
"app.js"));
private static readonly string MainWindow = File.ReadAllText(Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"MainWindow.xaml.cs"));
private static readonly string Playout = File.ReadAllText(Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"MainWindow.Playout.cs"));
[Fact]
public void Fixed_section_progress_is_native_state_and_locks_other_catalog_actions()
{
var fixedCatalog = Extract("function renderFixedCatalog", "function renderIndustry");
Assert.Contains("const batch = state.fixedSectionBatch", fixedCatalog,
StringComparison.Ordinal);
Assert.Contains("button.disabled = state.isBusy === true || batch != null",
fixedCatalog,
StringComparison.Ordinal);
Assert.Contains("summary.setAttribute(\"aria-disabled\"", fixedCatalog,
StringComparison.Ordinal);
Assert.Contains("section.getAttribute(\"aria-disabled\") !== \"true\"", App,
StringComparison.Ordinal);
}
[Fact]
public void Manual_modal_explains_atomic_staging_and_exposes_only_confirm_next_or_cancel()
{
var manual = Extract("function renderManualLists", "function openNamedPlaylist");
Assert.Contains("const fixedBatch = state.fixedSectionBatch", manual,
StringComparison.Ordinal);
Assert.Contains("아직 편성표에 추가되지 않았습니다", manual, StringComparison.Ordinal);
Assert.Contains("button.disabled = busy || fixedBatch != null", manual,
StringComparison.Ordinal);
Assert.Contains("확인 후 다음", manual, StringComparison.Ordinal);
Assert.Contains("확인 후 섹션 추가", manual, StringComparison.Ordinal);
Assert.Contains("send(\"confirm-manual-list\", {})", manual, StringComparison.Ordinal);
Assert.DoesNotContain("resume-fixed-section", App, StringComparison.Ordinal);
}
[Fact]
public void Native_dispatch_awaits_the_whole_fixed_section_workflow()
{
Assert.Contains("await _controller.ActivateFixedSection(", MainWindow,
StringComparison.Ordinal);
Assert.Contains("section.SectionIndex", MainWindow, StringComparison.Ordinal);
Assert.Contains("cancellationToken", MainWindow, StringComparison.Ordinal);
}
[Fact]
public void Native_boundary_allows_only_current_manual_edits_until_batch_completion()
{
var allowlist = Extract(
Playout,
"private static bool IsFixedSectionBatchMutationIntent",
"private void ObserveOperatorMutationQuarantine");
Assert.Contains("_controller.Current.FixedSectionBatch is not null", MainWindow,
StringComparison.Ordinal);
Assert.Contains("!IsFixedSectionBatchMutationIntent(intent)", MainWindow,
StringComparison.Ordinal);
Assert.Contains("LegacySetManualNetSellCellIntent", allowlist, StringComparison.Ordinal);
Assert.Contains("LegacyConfirmManualListIntent", allowlist, StringComparison.Ordinal);
Assert.DoesNotContain("LegacyDropSelectedCutsIntent", allowlist, StringComparison.Ordinal);
}
private static string Extract(string startToken, string endToken)
{
return Extract(App, startToken, endToken);
}
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 && end > start);
return source[start..end];
}
private static string FindRepositoryRoot()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
if (File.Exists(Path.Combine(current.FullName, "MBN_STOCK_WEBVIEW.sln")))
{
return current.FullName;
}
current = current.Parent;
}
throw new DirectoryNotFoundException("Repository root was not found.");
}
}