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

148 lines
6.3 KiB
C#

using System.Text.RegularExpressions;
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyOperatorSettingsWebContractTests
{
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 Styles = File.ReadAllText(Path.Combine(WebRoot, "styles.css"));
private static readonly string App = File.ReadAllText(Path.Combine(WebRoot, "app.js"));
[Fact]
public void SettingsScreenOffersThreeNativeFolderPickersAndRestartFeedback()
{
var expectedKinds = new[] { "design", "resource", "background" };
var actualKinds = Regex.Matches(Markup, "data-operator-folder=\"([^\"]+)\"")
.Select(match => match.Groups[1].Value)
.ToArray();
Assert.Equal(expectedKinds, actualKinds);
foreach (var kind in expectedKinds)
{
Assert.Contains($"id=\"operator-{kind}-folder-name\"", Markup,
StringComparison.Ordinal);
Assert.Contains($"id=\"operator-{kind}-folder-status\"", Markup,
StringComparison.Ordinal);
Assert.Contains($"id=\"operator-{kind}-folder-select\"", Markup,
StringComparison.Ordinal);
Assert.Contains($"id=\"operator-{kind}-folder-reset\"", Markup,
StringComparison.Ordinal);
}
Assert.Matches(
"id=\"operator-settings-message\"[^>]*role=\"status\"[^>]*aria-live=\"polite\"",
Markup);
Assert.Matches(
"id=\"operator-settings-restart\"[^>]*role=\"status\"[^>]*aria-live=\"polite\"",
Markup);
Assert.Contains("앱을 다시 시작하면 새 폴더가 적용됩니다.", Markup,
StringComparison.Ordinal);
Assert.Contains("settings-status-badge.valid", Styles, StringComparison.Ordinal);
Assert.Contains("settings-status-badge.invalid", Styles, StringComparison.Ordinal);
}
[Fact]
public void SettingsDispatchesOnlyClosedFolderKindsAndNeverWebSuppliedPaths()
{
var dispatch = Slice(
App,
"Object.keys(operatorFolderControls).forEach(function (kind)",
"searchButton.addEventListener");
Assert.Contains("send(\"choose-operator-folder\", { kind: kind })", dispatch,
StringComparison.Ordinal);
Assert.Contains("send(\"reset-operator-folder\", { kind: kind })", dispatch,
StringComparison.Ordinal);
Assert.Contains(
"send(\"set-operator-navigation-expanded\", { expanded: expanded })",
dispatch,
StringComparison.Ordinal);
Assert.DoesNotContain("path", dispatch, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("displayName", dispatch, StringComparison.Ordinal);
}
[Fact]
public void RepeatedSettingsStateKeepsStaticControlsAndAppliesNavigationByRevision()
{
var folderRender = Slice(App, "function renderOperatorFolder", "function render(state)");
var settingsRender = Slice(
App,
"function renderOperatorSettings",
"function render(state)");
Assert.DoesNotContain("innerHTML", folderRender, StringComparison.Ordinal);
Assert.DoesNotContain("replaceChildren", folderRender, StringComparison.Ordinal);
Assert.Contains("operatorSettingsRevisionInitialized", settingsRender,
StringComparison.Ordinal);
Assert.Contains("revision !== operatorSettingsRenderRevision", settingsRender,
StringComparison.Ordinal);
Assert.Matches(
new Regex(
@"if \(revisionChanged\) \{[\s\S]*?LegacyWorkspaceNavigation\.setExpanded\(expanded\);[\s\S]*?operatorSettingsRenderRevision = revision;",
RegexOptions.CultureInvariant),
settingsRender);
Assert.Single(
Regex.Matches(settingsRender, "LegacyWorkspaceNavigation.setExpanded").Cast<Match>());
Assert.Contains("pendingOperatorSettingsFocusId", settingsRender,
StringComparison.Ordinal);
Assert.Contains("target.focus({ preventScroll: true });", settingsRender,
StringComparison.Ordinal);
}
[Fact]
public void SettingsShowsSafeDiagnosticsAndNamesProtectedValues()
{
foreach (var id in new[]
{
"operator-settings-app-version",
"operator-settings-playout-mode",
"operator-settings-playout-connection",
"operator-settings-oracle-state",
"operator-settings-maria-state",
"operator-settings-db-monitor"
})
{
Assert.Contains($"id=\"{id}\"", Markup, StringComparison.Ordinal);
}
Assert.Contains("id=\"operator-navigation-expanded\"", Markup,
StringComparison.Ordinal);
Assert.Contains("databasePollingSeconds", App, StringComparison.Ordinal);
Assert.Contains("DB 자격 증명", Markup, StringComparison.Ordinal);
Assert.Contains("Tornado2 송출 대상", Markup, StringComparison.Ordinal);
Assert.Contains("Live/DryRun 권한", Markup, StringComparison.Ordinal);
Assert.Contains("장면 허용 목록", Markup, StringComparison.Ordinal);
}
private static string Slice(string source, string startMarker, string endMarker)
{
var start = source.IndexOf(startMarker, StringComparison.Ordinal);
Assert.True(start >= 0, $"Missing start marker: {startMarker}");
var end = source.IndexOf(endMarker, start, StringComparison.Ordinal);
Assert.True(end > start, $"Missing end marker: {endMarker}");
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 could not be located.");
}
}