fix: apply direct runtime paths and respect taskbar
This commit is contained in:
@@ -22,11 +22,10 @@ public sealed class LegacyOperatorSettingsTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SceneValidation_RequiresEveryActiveSceneAndBuiltInAssetAndAllowsMissingExternalVideo()
|
||||
public void SceneValidation_AcceptsAnEmptyCutsDirectoryAsADirectRuntimePath()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var sceneDirectory = directory.CreateDirectory("Cuts");
|
||||
WriteValidSceneFiles(sceneDirectory);
|
||||
|
||||
var result = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
@@ -34,91 +33,33 @@ public sealed class LegacyOperatorSettingsTests
|
||||
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Equal(Path.GetFullPath(sceneDirectory), result.Folder!.CanonicalPath);
|
||||
Assert.Equal("fixture-scene", File.ReadAllText(
|
||||
Path.Combine(result.Folder.CanonicalPath, "5001.t2s")));
|
||||
Assert.Contains("Cuts", result.Folder.AbbreviatedPath);
|
||||
Assert.InRange(
|
||||
result.Folder.AbbreviatedPath.Length,
|
||||
1,
|
||||
LegacyOperatorFolderValidator.DefaultDisplayCharacters);
|
||||
Assert.False(result.Folder.DatabaseIniDetected);
|
||||
Assert.Equal(
|
||||
LegacyOperatorFolderValidator.OptionalExternalAssetRelativePaths.Count,
|
||||
result.Folder.MissingOptionalExternalAssetCount);
|
||||
Assert.Equal(0, result.Folder.MissingOptionalExternalAssetCount);
|
||||
Assert.Null(result.WarningMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SceneValidation_BaselineOnlyIsRejectedInsteadOfBreakingOtherScenesAfterRestart()
|
||||
public void SceneValidation_DoesNotInspectPartialScenesOrVideoFiles()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var sceneDirectory = directory.CreateDirectory("partial-Cuts");
|
||||
File.WriteAllText(Path.Combine(sceneDirectory, "5001.t2s"), "baseline");
|
||||
var videoDirectory = Directory.CreateDirectory(
|
||||
Path.Combine(sceneDirectory, "Video")).FullName;
|
||||
File.WriteAllBytes(Path.Combine(videoDirectory, "partial.vrv"), []);
|
||||
|
||||
var result = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
sceneDirectory);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Equal(
|
||||
LegacyOperatorFolderValidationFailure.RequiredFileMissing,
|
||||
result.Failure);
|
||||
Assert.Null(result.Folder);
|
||||
AssertPathFree(result.WarningMessage, sceneDirectory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SceneValidation_MissingOneActiveSceneOrBuiltInAssetIsRejected()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var missingSceneDirectory = directory.CreateDirectory("missing-scene");
|
||||
WriteValidSceneFiles(missingSceneDirectory);
|
||||
File.Delete(Path.Combine(missingSceneDirectory, "5079.t2s"));
|
||||
var missingScene = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
missingSceneDirectory);
|
||||
|
||||
var missingAssetDirectory = directory.CreateDirectory("missing-asset");
|
||||
WriteValidSceneFiles(missingAssetDirectory);
|
||||
File.Delete(Path.Combine(missingAssetDirectory, "Images", "KRX.png"));
|
||||
var missingAsset = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
missingAssetDirectory);
|
||||
|
||||
Assert.False(missingScene.IsValid);
|
||||
Assert.Equal(LegacyOperatorFolderValidationFailure.RequiredFileMissing,
|
||||
missingScene.Failure);
|
||||
Assert.False(missingAsset.IsValid);
|
||||
Assert.Equal(LegacyOperatorFolderValidationFailure.RequiredFileMissing,
|
||||
missingAsset.Failure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SceneValidation_RejectsEmptyRequiredOrPresentOptionalFiles()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var emptyRequiredDirectory = directory.CreateDirectory("empty-required");
|
||||
WriteValidSceneFiles(emptyRequiredDirectory);
|
||||
File.WriteAllBytes(Path.Combine(emptyRequiredDirectory, "5076.t2s"), []);
|
||||
var emptyRequired = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
emptyRequiredDirectory);
|
||||
|
||||
var emptyOptionalDirectory = directory.CreateDirectory("empty-optional");
|
||||
WriteValidSceneFiles(emptyOptionalDirectory);
|
||||
var optionalPath = Path.Combine(emptyOptionalDirectory, "Video", "큐브배경.vrv");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(optionalPath)!);
|
||||
File.WriteAllBytes(optionalPath, []);
|
||||
var emptyOptional = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
emptyOptionalDirectory);
|
||||
|
||||
Assert.False(emptyRequired.IsValid);
|
||||
Assert.Equal(LegacyOperatorFolderValidationFailure.RequiredFileUnsafe,
|
||||
emptyRequired.Failure);
|
||||
Assert.False(emptyOptional.IsValid);
|
||||
Assert.Equal(LegacyOperatorFolderValidationFailure.RequiredFileUnsafe,
|
||||
emptyOptional.Failure);
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Equal(Path.GetFullPath(sceneDirectory), result.Folder!.CanonicalPath);
|
||||
Assert.Null(result.WarningMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -162,10 +103,12 @@ public sealed class LegacyOperatorSettingsTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SceneValidation_MissingBaselineFailsWithoutLeakingThePath()
|
||||
public void SceneValidation_MissingDirectoryFailsWithoutLeakingThePath()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var sceneDirectory = directory.CreateDirectory("sensitive-design-folder");
|
||||
var sceneDirectory = Path.Combine(
|
||||
directory.Path,
|
||||
"sensitive-design-folder");
|
||||
|
||||
var result = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Scene,
|
||||
@@ -173,7 +116,7 @@ public sealed class LegacyOperatorSettingsTests
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Equal(
|
||||
LegacyOperatorFolderValidationFailure.RequiredFileMissing,
|
||||
LegacyOperatorFolderValidationFailure.DirectoryNotFound,
|
||||
result.Failure);
|
||||
Assert.Null(result.Folder);
|
||||
AssertPathFree(result.WarningMessage, sceneDirectory);
|
||||
|
||||
@@ -119,7 +119,7 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliedDevelopmentLiveUsesOnlyProtectedStartupInputs()
|
||||
public void AppliedDevelopmentLiveUsesSelectedRuntimePathsAndProtectedDatabaseInputs()
|
||||
{
|
||||
var window = File.ReadAllText(Path.Combine(ParityRoot, "MainWindow.xaml.cs"));
|
||||
var playout = File.ReadAllText(Path.Combine(
|
||||
@@ -135,11 +135,18 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"? LegacyRuntimeStockCutMenuLoader.ResolveFromBaseDirectory(",
|
||||
"var selectedResourceDirectory =\n" +
|
||||
" _appliedOperatorSettings.ResourceDirectory;",
|
||||
window.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"LegacyRuntimeStockCutMenuLoader.ResolveFromResourceDirectory(",
|
||||
window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"? null\n : _appliedOperatorSettings.ResourceDirectory;",
|
||||
"_isDevelopmentLiveLaunch ||\n" +
|
||||
" selectedResourceDirectory is null\n" +
|
||||
" ? null",
|
||||
window.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
@@ -150,6 +157,11 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
"? PlayoutOptionsLoader.LoadDevelopmentLive(",
|
||||
playout,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"operatorSceneDirectory:\n" +
|
||||
" _appliedOperatorSettings.SceneDirectory",
|
||||
playout.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"IsSourceOnlyBuild ||\n _isDevelopmentLiveLaunchRequested",
|
||||
playout.ReplaceLineEndings("\n"),
|
||||
|
||||
@@ -241,11 +241,13 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
var pinPreflight = initializer.LastIndexOf(
|
||||
"$k3dPinPreflight = Get-K3DPinPreflight",
|
||||
StringComparison.Ordinal);
|
||||
var pinWrite = initializer.LastIndexOf(
|
||||
var pinWrite = initializer.IndexOf(
|
||||
"Write-ProtectedUtf8TextAtomically",
|
||||
pinPreflight,
|
||||
StringComparison.Ordinal);
|
||||
var livePreflight = initializer.LastIndexOf(
|
||||
var livePreflight = initializer.IndexOf(
|
||||
"$livePreflight = Get-DevelopmentLivePreflight",
|
||||
pinWrite,
|
||||
StringComparison.Ordinal);
|
||||
Assert.True(pinPreflight >= 0);
|
||||
Assert.True(pinWrite > pinPreflight);
|
||||
|
||||
@@ -12,13 +12,29 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"MBN_STOCK_WEBVIEW.LegacyParityApp.csproj");
|
||||
|
||||
[Fact]
|
||||
public void LegacyParityProjectLinksCutsAndResIntoOutputPublishAndMsix()
|
||||
public void LegacyParityProjectUsesCutsInPlaceAndLinksOnlyAllowlistedRes()
|
||||
{
|
||||
var project = XDocument.Load(ProjectPath);
|
||||
var contents = project.Descendants("Content").ToArray();
|
||||
|
||||
AssertLinkedRuntimeTree(contents, "$(LegacyCutsSourceRoot)\\**\\*", "Cuts\\");
|
||||
Assert.DoesNotContain(
|
||||
contents,
|
||||
element => string.Equals(
|
||||
element.Attribute("Include")?.Value,
|
||||
"$(LegacyCutsSourceRoot)\\**\\*",
|
||||
StringComparison.Ordinal));
|
||||
AssertLinkedRuntimeTree(contents, "@(LegacyPackagedResAsset)", "Res\\");
|
||||
var cutsScrub = Assert.Single(
|
||||
project.Descendants("Target"),
|
||||
target => string.Equals(
|
||||
target.Attribute("Name")?.Value,
|
||||
"ScrubCopiedCutsFromBuildOutput",
|
||||
StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
"$(TargetDir)Cuts",
|
||||
Assert.Single(cutsScrub.Elements("RemoveDir"))
|
||||
.Attribute("Directories")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var packagedResNames = project.Descendants("LegacyPackagedResAsset")
|
||||
.Select(element => Path.GetFileName(element.Attribute("Include")?.Value))
|
||||
@@ -354,10 +370,10 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
validationTarget.Elements("Message"),
|
||||
message => (message.Attribute("Text")?.Value ?? string.Empty)
|
||||
.Contains(
|
||||
"Verified full legacy runtime assets are enabled",
|
||||
"External legacy runtime paths are enabled",
|
||||
StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
"Verified full legacy runtime assets are enabled",
|
||||
"Cuts files remain in the selected folder",
|
||||
fullRuntimeMessage.Attribute("Text")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
@@ -379,7 +395,6 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
|
||||
string[] externalContentIncludes =
|
||||
[
|
||||
@"$(LegacyCutsSourceRoot)\**\*",
|
||||
"@(LegacyPackagedResAsset)",
|
||||
"@(LegacyFinancialPreviewAsset)",
|
||||
"@(LegacyBrandAsset)"
|
||||
@@ -397,6 +412,12 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
content.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
});
|
||||
Assert.DoesNotContain(
|
||||
project.Descendants("Content"),
|
||||
element => string.Equals(
|
||||
element.Attribute("Include")?.Value,
|
||||
@"$(LegacyCutsSourceRoot)\**\*",
|
||||
StringComparison.Ordinal));
|
||||
|
||||
Assert.DoesNotContain(
|
||||
project.Descendants("Target"),
|
||||
@@ -454,8 +475,6 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"$(LegacyRuntimeSourceRoot)",
|
||||
"$(LegacyCutsSourceRoot)",
|
||||
"$(LegacyResSourceRoot)",
|
||||
"$(LegacyCutsSourceRoot)\\%(LegacyRequiredScene.Identity).t2s",
|
||||
"$(LegacyCutsSourceRoot)\\%(LegacyRequiredBuiltInAsset.Identity)",
|
||||
"$(LegacyResSourceRoot)\\logo.png",
|
||||
"$(LegacyResSourceRoot)\\종목.ini",
|
||||
"$(LegacyResSourceRoot)\\업종_코스피.ini",
|
||||
@@ -673,42 +692,52 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"must be outside and must not overlap this repository",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("Assert-NoReparsePointInTree", initializer,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("'New-LegacyRuntimeBundle.ps1'", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("'Initialize-LegacyRuntimeBundle.ps1'", initializer,
|
||||
Assert.Contains("Assert-NoReparsePointInExistingAncestry", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"$existingRuntime.ManifestSha256.Equals(",
|
||||
"Legacy runtime source root contains characters reserved by MSBuild.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("$bundleCreatorPath =", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("$bundleInitializerPath =", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("& $bundleCreatorPath", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("& $bundleInitializerPath", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"function New-DirectRuntimeBindingFile",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Assert-InstalledRuntimeMatchesManifest",
|
||||
"function Get-RuntimeFoldersPreflight",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Installed runtime bundle contains an unexpected file",
|
||||
"runtime-folders.local.json",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("[switch] $ReplaceRuntimeBinding", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"The selected Cuts/Res path differs from the existing runtime binding.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("Set-RuntimeBindingAtomically", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"[IO.File]::Replace($temporary, $destination, $backup)",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
var shadowInstall = initializer.IndexOf(
|
||||
"-RepositoryRoot $shadowRepositoryRoot",
|
||||
var directBinding = initializer.LastIndexOf(
|
||||
"New-DirectRuntimeBindingFile",
|
||||
StringComparison.Ordinal);
|
||||
var bindingReplace = initializer.IndexOf(
|
||||
var bindingReplace = initializer.LastIndexOf(
|
||||
"Set-RuntimeBindingAtomically",
|
||||
shadowInstall,
|
||||
StringComparison.Ordinal);
|
||||
Assert.True(shadowInstall >= 0);
|
||||
Assert.True(bindingReplace > shadowInstall);
|
||||
Assert.True(directBinding >= 0);
|
||||
Assert.True(bindingReplace > directBinding);
|
||||
|
||||
Assert.Contains("[string] $DatabaseIniPath", initializer,
|
||||
StringComparison.Ordinal);
|
||||
@@ -790,6 +819,7 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
Assert.Contains("& $DotNetPath build $ProjectPath",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("'--no-restore'", initializer, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"'-p:LegacyRuntimeAssetsMode=Required'",
|
||||
initializer,
|
||||
@@ -810,7 +840,9 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"unexpectedly resolved as SourceOnly",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("Debug x64 payload count mismatch", initializer,
|
||||
Assert.Contains(
|
||||
"Debug x64 copied Cuts instead of using the selected external path.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Credential-bearing MmoneyCoder.ini entered the Debug build output.",
|
||||
@@ -820,12 +852,15 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
var runtimeWrite = initializer.LastIndexOf(
|
||||
"Set-RuntimeBindingAtomically",
|
||||
StringComparison.Ordinal);
|
||||
var pinWrite = initializer.LastIndexOf(
|
||||
"Write-ProtectedUtf8TextAtomically",
|
||||
var pinWrite = initializer.IndexOf(
|
||||
"-Description 'K3D persistent pin'",
|
||||
StringComparison.Ordinal);
|
||||
var databaseWrite = initializer.LastIndexOf(
|
||||
"Copy-DatabaseProfileAtomically",
|
||||
StringComparison.Ordinal);
|
||||
var runtimeFoldersWrite = initializer.LastIndexOf(
|
||||
"-Description 'runtime folder configuration'",
|
||||
StringComparison.Ordinal);
|
||||
var build = initializer.LastIndexOf(
|
||||
"Invoke-DebugBuildAndVerify",
|
||||
StringComparison.Ordinal);
|
||||
@@ -841,7 +876,8 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
Assert.True(pinWrite >= 0);
|
||||
Assert.True(build > pinWrite);
|
||||
Assert.True(databaseWrite > build);
|
||||
Assert.True(finalK3dVerification > databaseWrite);
|
||||
Assert.True(runtimeFoldersWrite > databaseWrite);
|
||||
Assert.True(finalK3dVerification > runtimeFoldersWrite);
|
||||
Assert.True(liveWrite > finalK3dVerification);
|
||||
Assert.True(runtimeWrite > liveWrite);
|
||||
Assert.True(cleanup > runtimeWrite);
|
||||
@@ -910,6 +946,12 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
var databaseRollback = initializer.LastIndexOf(
|
||||
"-Snapshot $databaseSnapshot",
|
||||
StringComparison.Ordinal);
|
||||
var runtimeFoldersMutation = initializer.LastIndexOf(
|
||||
"$runtimeFoldersMutationStarted = $true",
|
||||
StringComparison.Ordinal);
|
||||
var runtimeFoldersRollback = initializer.LastIndexOf(
|
||||
"-Snapshot $runtimeFoldersSnapshot",
|
||||
StringComparison.Ordinal);
|
||||
var runtimeMutation = initializer.LastIndexOf(
|
||||
"$runtimeBindingMutationStarted = $true",
|
||||
StringComparison.Ordinal);
|
||||
@@ -920,8 +962,10 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"-Snapshot $propsSnapshot",
|
||||
StringComparison.Ordinal);
|
||||
Assert.True(databaseMutation >= 0 && databaseMutation < databaseWrite);
|
||||
Assert.True(runtimeFoldersMutation >= 0);
|
||||
Assert.True(runtimeMutation >= 0 && runtimeMutation < runtimeWrite);
|
||||
Assert.True(databaseRollback > databaseWrite);
|
||||
Assert.True(runtimeFoldersRollback > runtimeFoldersMutation);
|
||||
Assert.True(runtimeRollback > runtimeWrite);
|
||||
Assert.Contains("Original failure:", initializer, StringComparison.Ordinal);
|
||||
Assert.Contains("Secondary recovery failure(s):", initializer,
|
||||
@@ -929,51 +973,16 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
|
||||
Assert.Contains("function Assert-ExactObjectProperties", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Description 'Runtime bundle creation result'",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Description 'Runtime bundle initialization result'",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Description 'K3D registration inspection result'",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Runtime bundle creation result paths escaped or changed the exact output contract.",
|
||||
"function New-DirectRuntimeBindingFile",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Runtime bundle initialization result paths or hashes violate containment.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("function Get-VerifiedRuntimeManifest", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"duplicate/extra/case/type/format changes are rejected.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"function Assert-DebugRuntimePayloadMatchesManifest",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Debug x64 runtime payload differs from the manifest:",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Debug x64 runtime output contains an unexpected file:",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Debug x64 runtime output does not match the exact manifest file set.",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Root $targetRoot",
|
||||
"Runtime folder configuration rollback failed:",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
@@ -1008,8 +1017,8 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
var buildVerification = initializer.LastIndexOf(
|
||||
"Invoke-DebugBuildAndVerify",
|
||||
StringComparison.Ordinal);
|
||||
var pinIssue = initializer.LastIndexOf(
|
||||
"Write-ProtectedUtf8TextAtomically",
|
||||
var pinIssue = initializer.IndexOf(
|
||||
"-Description 'K3D persistent pin'",
|
||||
StringComparison.Ordinal);
|
||||
var finalK3dVerification = initializer.LastIndexOf(
|
||||
"$finalNativeHash = (",
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
|
||||
|
||||
public sealed class LegacyWindowSizingNativeContractTests
|
||||
{
|
||||
private static readonly string Window = File.ReadAllText(Path.Combine(
|
||||
FindRepositoryRoot(),
|
||||
"src",
|
||||
"MBN_STOCK_WEBVIEW.LegacyParityApp",
|
||||
"MainWindow.xaml.cs"));
|
||||
|
||||
[Fact]
|
||||
public void MainWindowClampsRestoreBoundsAndUsesWorkAreaAwareSystemMaximize()
|
||||
{
|
||||
var configureWindow = Slice(
|
||||
Window,
|
||||
"private void ConfigureWindow()",
|
||||
"private async Task InitializeWebViewAsync()");
|
||||
|
||||
var displayArea = RequiredIndex(
|
||||
configureWindow,
|
||||
"DisplayArea.GetFromWindowId(windowId, DisplayAreaFallback.Primary)");
|
||||
var workArea = RequiredIndex(
|
||||
configureWindow,
|
||||
"var workArea = displayArea.WorkArea;");
|
||||
var resizeClient = RequiredIndex(
|
||||
configureWindow,
|
||||
"appWindow.ResizeClient(new SizeInt32(1905, 1015));");
|
||||
var readOuterSize = RequiredIndex(
|
||||
configureWindow,
|
||||
"var requestedWindowSize = appWindow.Size;");
|
||||
var moveAndResize = RequiredIndex(
|
||||
configureWindow,
|
||||
"appWindow.MoveAndResize(");
|
||||
var workAreaX = RequiredIndex(configureWindow, "workArea.X,");
|
||||
var workAreaY = RequiredIndex(configureWindow, "workArea.Y,");
|
||||
var allowSystemMaximize = RequiredIndex(
|
||||
configureWindow,
|
||||
"presenter.IsMaximizable = true;");
|
||||
var maximize = RequiredIndex(
|
||||
configureWindow,
|
||||
"presenter.Maximize();");
|
||||
Assert.True(displayArea < workArea);
|
||||
Assert.True(workArea < resizeClient);
|
||||
Assert.True(resizeClient < readOuterSize);
|
||||
Assert.True(readOuterSize < moveAndResize);
|
||||
Assert.True(moveAndResize < workAreaX);
|
||||
Assert.True(workAreaX < workAreaY);
|
||||
Assert.True(moveAndResize < allowSystemMaximize);
|
||||
Assert.True(allowSystemMaximize < maximize);
|
||||
Assert.DoesNotContain(
|
||||
"presenter.IsMaximizable = false;",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"presenter.IsResizable = false;",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"var requestedWindowSize = appWindow.Size;",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Math.Min(requestedWindowSize.Width, workArea.Width)",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Math.Min(requestedWindowSize.Height, workArea.Height)",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"appWindow.Move(new PointInt32(",
|
||||
configureWindow,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static int RequiredIndex(string value, string needle)
|
||||
{
|
||||
var index = value.IndexOf(needle, StringComparison.Ordinal);
|
||||
Assert.True(index >= 0, $"Required marker was not found: {needle}");
|
||||
return index;
|
||||
}
|
||||
|
||||
private static string Slice(string value, string start, string end)
|
||||
{
|
||||
var startIndex = value.IndexOf(start, StringComparison.Ordinal);
|
||||
var endIndex = value.IndexOf(
|
||||
end,
|
||||
startIndex + start.Length,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Assert.True(startIndex >= 0, $"Required marker was not found: {start}");
|
||||
Assert.True(endIndex >= 0, $"Required marker was not found: {end}");
|
||||
return value[startIndex..endIndex];
|
||||
}
|
||||
|
||||
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 find the repository root.");
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,49 @@ public sealed class PlayoutOptionsLoaderTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadDevelopmentLive_UsesTheFirstRunCutsPathWithoutCopyingIt()
|
||||
{
|
||||
using var environment = ClearedEnvironment()
|
||||
.Set("MBN_STOCK_PLAYOUT_SCENE_DIRECTORY", "C:\\stale-scenes");
|
||||
using var file = TemporaryJsonFile.Create(DevelopmentLiveBaseJson());
|
||||
var executableRoot = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
Guid.NewGuid().ToString("N"),
|
||||
"app");
|
||||
var selectedCuts = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
Guid.NewGuid().ToString("N"),
|
||||
"Cuts");
|
||||
Directory.CreateDirectory(executableRoot);
|
||||
Directory.CreateDirectory(selectedCuts);
|
||||
try
|
||||
{
|
||||
var options = PlayoutOptionsLoader.LoadDevelopmentLive(
|
||||
file.Path,
|
||||
executableRoot,
|
||||
selectedCuts);
|
||||
|
||||
Assert.Equal(Path.GetFullPath(selectedCuts), options.SceneDirectory);
|
||||
Assert.Equal(
|
||||
Path.GetFullPath(selectedCuts),
|
||||
options.DevelopmentLiveExecutableSceneDirectory);
|
||||
Assert.False(Directory.Exists(Path.Combine(executableRoot, "Cuts")));
|
||||
|
||||
var validated = ValidatedPlayoutOptions.Create(options);
|
||||
Assert.Equal(Path.GetFullPath(selectedCuts), validated.SceneDirectory);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(
|
||||
Path.GetDirectoryName(executableRoot)!,
|
||||
recursive: true);
|
||||
Directory.Delete(
|
||||
Path.GetDirectoryName(selectedCuts)!,
|
||||
recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadDevelopmentLive_RejectsBaseProfileThatCanReconnect()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user