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

197 lines
7.7 KiB
C#

namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyProgramNamedPlaylistPersistenceContractTests
{
private static readonly string Playout = File.ReadAllText(Path.Combine(
FindRepositoryRoot(),
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"MainWindow.Playout.cs"));
private static readonly string Window = File.ReadAllText(Path.Combine(
FindRepositoryRoot(),
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"MainWindow.xaml.cs"));
private static readonly string Web = File.ReadAllText(Path.Combine(
FindRepositoryRoot(),
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp",
"Web",
"app.js"));
[Fact]
public void ProgramAllowsNamedPlaylistWritesWithoutOpeningDbLoadReplacement()
{
var admission = Slice(
Playout,
"private bool CanAcceptOperatorMutation(",
"private static bool RequiresIdlePlaylistMutation");
var safeWrites = Slice(
admission,
"var isSafeNamedPlaylistPersistenceMutation",
"var refreshAllowsMutation");
Assert.Contains("LegacyCreateNamedPlaylistIntent", safeWrites,
StringComparison.Ordinal);
Assert.Contains("LegacySaveCurrentNamedPlaylistIntent", safeWrites,
StringComparison.Ordinal);
Assert.Contains("LegacySaveCurrentNamedPlaylistToIntent", safeWrites,
StringComparison.Ordinal);
Assert.Contains("LegacyDeleteSelectedNamedPlaylistIntent", safeWrites,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacyRefreshNamedPlaylistsIntent", safeWrites,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacyLoadSelectedNamedPlaylistIntent", safeWrites,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacyLoadNamedPlaylistByIdIntent", safeWrites,
StringComparison.Ordinal);
Assert.Contains("isSafeNamedPlaylistPersistenceMutation ||", admission,
StringComparison.Ordinal);
var idleOnly = Slice(
Playout,
"private static bool RequiresIdlePlaylistMutation",
"private static bool IsPlaylistMutationIdle");
Assert.Contains("LegacyLoadSelectedNamedPlaylistIntent", idleOnly,
StringComparison.Ordinal);
Assert.Contains("LegacyLoadNamedPlaylistByIdIntent", idleOnly,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacyCreateNamedPlaylistIntent", idleOnly,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacySaveCurrentNamedPlaylistIntent", idleOnly,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacySaveCurrentNamedPlaylistToIntent", idleOnly,
StringComparison.Ordinal);
Assert.DoesNotContain("LegacyDeleteSelectedNamedPlaylistIntent", idleOnly,
StringComparison.Ordinal);
}
[Fact]
public void NamedPlaylistModalRequestsUseOnePendingSlotBehindRefresh()
{
Assert.Contains(
"private readonly SemaphoreSlim _orderedNamedPlaylistIntentGate = new(1, 1);",
Window,
StringComparison.Ordinal);
var process = Slice(
Window,
"private async Task ProcessIntentAsync",
"private LegacyOperatorSnapshot SelectCutWithoutAppend");
var queued = Slice(
process,
"else if (IsNamedPlaylistModalIntent(intent))",
"// Keep the zero-timeout admission used by database and edit intents;");
Assert.Contains("_orderedNamedPlaylistIntentGate.WaitAsync(", queued,
StringComparison.Ordinal);
Assert.Contains("0,", queued, StringComparison.Ordinal);
Assert.Contains("await _intentGate.WaitAsync", queued,
StringComparison.Ordinal);
Assert.Contains("_orderedNamedPlaylistIntentGate.Release();", process,
StringComparison.Ordinal);
var classifier = Slice(
Window,
"private static bool IsNamedPlaylistModalIntent",
"private LegacyOperatorSnapshot ReportIntentFailure");
foreach (var intent in new[]
{
"LegacyRefreshNamedPlaylistsIntent",
"LegacySelectNamedPlaylistIntent",
"LegacyLoadSelectedNamedPlaylistIntent",
"LegacyLoadNamedPlaylistByIdIntent",
"LegacyCreateNamedPlaylistIntent",
"LegacySaveCurrentNamedPlaylistIntent",
"LegacySaveCurrentNamedPlaylistToIntent",
"LegacyDeleteSelectedNamedPlaylistIntent",
"LegacyDismissDialogIntent"
})
{
Assert.Contains(intent, classifier, StringComparison.Ordinal);
}
Assert.Contains("else if (intent is LegacyDismissDialogIntent)", process,
StringComparison.Ordinal);
Assert.Contains("PostState(_controller.Current);", process,
StringComparison.Ordinal);
}
[Fact]
public void OneButtonResultDialogCannotLoseItsClickToBackgroundBusyState()
{
Assert.Contains(
"dialogOk.disabled = legacyDialogIsConfirmation && state.isBusy === true;",
Web,
StringComparison.Ordinal);
}
[Fact]
public void NamedPlaylistConfirmationReenablesBothActionsWhenItOpens()
{
var open = Slice(
Web,
"function openNamedPlaylistConfirmation",
"function restoreNamedPlaylistAfterConfirmation");
Assert.Contains("if (!options || isNamedPlaylistActionLocked()) return false;",
open,
StringComparison.Ordinal);
Assert.Contains("namedPlaylistConfirmationYes.disabled = false;",
open,
StringComparison.Ordinal);
Assert.Contains("namedPlaylistConfirmationNo.disabled = false;",
open,
StringComparison.Ordinal);
}
[Fact]
public void OpenNamedPlaylistConfirmationDoesNotLoseClickToProgramRefresh()
{
var render = Slice(
Web,
"function renderNamedPlaylist",
"function clearOperatorCatalogDragVisuals");
var confirmationLock = Slice(
render,
"namedPlaylistConfirmationYes.disabled =",
"if (deferredSelectionAction)");
Assert.Contains("pendingNamedPlaylistCommand !== null", confirmationLock,
StringComparison.Ordinal);
Assert.Contains("namedPlaylistState.isWriteInProgress === true", confirmationLock,
StringComparison.Ordinal);
Assert.DoesNotContain("operatorMutationLocked", confirmationLock,
StringComparison.Ordinal);
Assert.DoesNotContain("uiBusy", confirmationLock,
StringComparison.Ordinal);
}
private static string Slice(string source, string startMarker, string endMarker)
{
var start = source.IndexOf(startMarker, StringComparison.Ordinal);
var end = source.IndexOf(endMarker, start + startMarker.Length,
StringComparison.Ordinal);
Assert.True(start >= 0, $"Missing source marker: {startMarker}");
Assert.True(end > start, $"Missing source 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("Could not locate the repository root.");
}
}