fix: allow safe fresh-clone DryRun builds
This commit is contained in:
@@ -204,6 +204,12 @@ test("appearance controls and accessibility preferences retain clear feedback",
|
||||
test("workspace header keeps one concise title and the live native connection state", () => {
|
||||
assert.match(markup,
|
||||
/class="brand"[\s\S]*?class="brand-wordmark-plate"[\s\S]*?<img class="brand-wordmark" src="Brand\/logo\.png" width="176" height="43"[\s\S]*?alt="매일경제TV" draggable="false">[\s\S]*?class="brand-divider" aria-hidden="true"[\s\S]*?class="brand-product">V-STOCK<\/span>/);
|
||||
assert.match(markup,
|
||||
/class="brand-wordmark-fallback">매일경제TV<\/span>/);
|
||||
assert.match(styles,
|
||||
/\.brand-wordmark-plate\.wordmark-fallback-active \.brand-wordmark-fallback\s*\{[^}]*visibility:\s*visible/);
|
||||
assert.match(styles,
|
||||
/\.brand-wordmark-plate\.wordmark-fallback-active \.brand-wordmark\s*\{[^}]*display:\s*none/);
|
||||
assert.doesNotMatch(markup, /class="brand-symbol"|class="brand-lockup"|>VRi</);
|
||||
assert.match(markup,
|
||||
/class="workspace-heading"[\s\S]*?class="workspace-heading-icon"[\s\S]*?<div class="workspace-heading-copy">[\s\S]*?<h1 id="workspace-title">[^<]+<\/h1>/);
|
||||
|
||||
@@ -510,6 +510,15 @@ test("workspace navigation stores only the approved local presentation preferenc
|
||||
assert.doesNotMatch(navigation, /postMessage|sessionStorage|send\s*\(/);
|
||||
});
|
||||
|
||||
test("missing external wordmark uses the source-only text fallback", () => {
|
||||
assert.match(navigation,
|
||||
/brandWordmark\.addEventListener\("error", showBrandWordmarkFallback, \{ once: true \}\)/);
|
||||
assert.match(navigation,
|
||||
/brandWordmark\.complete && brandWordmark\.naturalWidth === 0/);
|
||||
assert.match(navigation,
|
||||
/classList\.add\("wordmark-fallback-active"\)/);
|
||||
});
|
||||
|
||||
test("splitter clamps pointer and keyboard resizing and Escape restores the gesture", () => {
|
||||
for (const declaration of [
|
||||
/const scheduleMinimumPercent = 34/,
|
||||
|
||||
@@ -88,6 +88,13 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
Assert.Contains("#if DEBUG", app, StringComparison.Ordinal);
|
||||
Assert.Contains("const bool isDebugBuild = true;", app, StringComparison.Ordinal);
|
||||
Assert.Contains("const bool isDebugBuild = false;", app, StringComparison.Ordinal);
|
||||
Assert.Contains("#if SOURCE_ONLY_RUNTIME", app, StringComparison.Ordinal);
|
||||
Assert.Contains("const bool isSourceOnlyBuild = true;", app,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("const bool isSourceOnlyBuild = false;", app,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("isSourceOnlyBuild", app, StringComparison.Ordinal);
|
||||
Assert.Contains("? null", app, StringComparison.Ordinal);
|
||||
Assert.Contains("args.Arguments", app, StringComparison.Ordinal);
|
||||
Assert.Contains("Environment.GetCommandLineArgs()", app, StringComparison.Ordinal);
|
||||
Assert.Contains("ResolveLaunchArguments(", app, StringComparison.Ordinal);
|
||||
|
||||
@@ -268,6 +268,154 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
Assert.Single(rejectionTarget.Elements("Error"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FreshCloneUsesIsolatedSourceOnlyOutputWithoutWeakeningFullBuilds()
|
||||
{
|
||||
var project = XDocument.Load(ProjectPath);
|
||||
|
||||
var sourceRootWasSpecified = Assert.Single(
|
||||
project.Descendants("LegacyRuntimeSourceRootWasSpecified"));
|
||||
Assert.Equal(
|
||||
"'$(LegacyRuntimeSourceRoot)' != ''",
|
||||
sourceRootWasSpecified.Attribute("Condition")?.Value);
|
||||
|
||||
var modes = project.Descendants("LegacyRuntimeAssetsMode").ToArray();
|
||||
Assert.Equal(2, modes.Length);
|
||||
var requiredMode = Assert.Single(
|
||||
modes,
|
||||
mode => string.Equals(mode.Value, "Required", StringComparison.Ordinal));
|
||||
var requiredCondition = requiredMode.Attribute("Condition")?.Value;
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeSourceRootWasSpecified)",
|
||||
requiredCondition,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"'$(Configuration)' == 'Release'",
|
||||
requiredCondition,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"$(GenerateAppxPackageOnBuild)",
|
||||
requiredCondition,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("$(PublishAppxPackage)", requiredCondition, StringComparison.Ordinal);
|
||||
|
||||
var autoMode = Assert.Single(
|
||||
modes,
|
||||
mode => string.Equals(mode.Value, "Auto", StringComparison.Ordinal));
|
||||
Assert.Equal(
|
||||
"'$(LegacyRuntimeAssetsMode)' == ''",
|
||||
autoMode.Attribute("Condition")?.Value);
|
||||
|
||||
var assetsEnabled = Assert.Single(
|
||||
project.Descendants("LegacyRuntimeAssetsEnabled"),
|
||||
element => (element.Attribute("Condition")?.Value ?? string.Empty)
|
||||
.Contains("Exists('$(LegacyRuntimeSourceRoot)')", StringComparison.Ordinal));
|
||||
Assert.Equal("true", assetsEnabled.Value);
|
||||
|
||||
var sourceOnlyOutput = Assert.Single(project.Descendants("BaseOutputPath"));
|
||||
Assert.Equal(@"bin\SourceOnly\", sourceOnlyOutput.Value);
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsEnabled)",
|
||||
sourceOnlyOutput.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
var sourceOnlyIntermediate = Assert.Single(
|
||||
project.Descendants("IntermediateOutputPath"));
|
||||
Assert.Equal(
|
||||
@"obj\SourceOnly\$(Platform)\$(Configuration)\",
|
||||
sourceOnlyIntermediate.Value);
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsEnabled)",
|
||||
sourceOnlyIntermediate.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
var sourceOnlyConstants = Assert.Single(project.Descendants("DefineConstants"));
|
||||
Assert.Contains(
|
||||
"SOURCE_ONLY_RUNTIME",
|
||||
sourceOnlyConstants.Value,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsEnabled)",
|
||||
sourceOnlyConstants.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var validationTarget = Assert.Single(
|
||||
project.Descendants("Target"),
|
||||
element => string.Equals(
|
||||
element.Attribute("Name")?.Value,
|
||||
"ValidateLegacyRuntimeAssets",
|
||||
StringComparison.Ordinal));
|
||||
var sourceOnlyMessage = Assert.Single(validationTarget.Elements("Message"));
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsMode)",
|
||||
sourceOnlyMessage.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"source-only DryRun",
|
||||
sourceOnlyMessage.Attribute("Text")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var runtimeValidationErrors = validationTarget.Elements("Error")
|
||||
.Where(error => (error.Attribute("Condition")?.Value ?? string.Empty)
|
||||
.Contains("Exists(", StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
Assert.NotEmpty(runtimeValidationErrors);
|
||||
Assert.All(runtimeValidationErrors, error =>
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsValidationEnabled)",
|
||||
error.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal));
|
||||
|
||||
string[] externalContentIncludes =
|
||||
[
|
||||
@"$(LegacyCutsSourceRoot)\**\*",
|
||||
"@(LegacyPackagedResAsset)",
|
||||
"@(LegacyFinancialPreviewAsset)",
|
||||
"@(LegacyBrandAsset)"
|
||||
];
|
||||
Assert.All(externalContentIncludes, include =>
|
||||
{
|
||||
var content = Assert.Single(
|
||||
project.Descendants("Content"),
|
||||
element => string.Equals(
|
||||
element.Attribute("Include")?.Value,
|
||||
include,
|
||||
StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsEnabled)",
|
||||
content.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
var databaseCopy = Assert.Single(
|
||||
project.Descendants("Target"),
|
||||
element => string.Equals(
|
||||
element.Attribute("Name")?.Value,
|
||||
"CopyLegacyDatabaseIniToLocalOutput",
|
||||
StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
"$(LegacyRuntimeAssetsEnabled)",
|
||||
databaseCopy.Attribute("Condition")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var mainWindow = File.ReadAllText(Path.Combine(
|
||||
RepositoryRoot,
|
||||
"src",
|
||||
"MBN_STOCK_WEBVIEW.LegacyParityApp",
|
||||
"MainWindow.xaml.cs"));
|
||||
Assert.Contains("#if SOURCE_ONLY_RUNTIME", mainWindow, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Source-only builds do not initialize a database runtime.",
|
||||
mainWindow,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var playout = File.ReadAllText(Path.Combine(
|
||||
RepositoryRoot,
|
||||
"src",
|
||||
"MBN_STOCK_WEBVIEW.LegacyParityApp",
|
||||
"MainWindow.Playout.cs"));
|
||||
Assert.Contains("forceSafeDryRun: IsSourceOnlyBuild", playout,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LegacyRuntimeSourceRootIsOverrideableAndValidatedBeforeBuild()
|
||||
{
|
||||
|
||||
@@ -62,6 +62,32 @@ public sealed class PlayoutOptionsLoaderTests
|
||||
Assert.Null(options.MaximumAutomaticRefreshesPerTakeIn);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_SourceOnlyIgnoresLocalProfileOperatorRootsAndEnvironment()
|
||||
{
|
||||
using var environment = ClearedEnvironment()
|
||||
.Set("MBN_STOCK_PLAYOUT_MODE", "Live")
|
||||
.Set("MBN_STOCK_PLAYOUT_HOST", "configured-live-host")
|
||||
.Set("MBN_STOCK_PLAYOUT_SCENE_DIRECTORY", "C:\\configured-live-scenes")
|
||||
.Set(
|
||||
PlayoutOptionsLoader.LiveAuthorizationEnvironmentVariable,
|
||||
PlayoutOptionsLoader.RequiredLiveAuthorizationValue);
|
||||
using var file = TemporaryJsonFile.Create("{ intentionally-invalid-json");
|
||||
|
||||
var options = PlayoutOptionsLoader.Load(
|
||||
file.Path,
|
||||
operatorSceneDirectory: "C:\\operator-scenes",
|
||||
operatorBackgroundDirectory: "C:\\operator-backgrounds",
|
||||
forceSafeDryRun: true);
|
||||
|
||||
Assert.Equal(PlayoutMode.DryRun, options.Mode);
|
||||
Assert.Equal("127.0.0.1", options.Host);
|
||||
Assert.Null(options.SceneDirectory);
|
||||
Assert.Null(options.LegacyBackgroundDirectory);
|
||||
Assert.False(options.TrustedLiveOutputEnabled);
|
||||
Assert.Empty(options.TestSceneAllowlist);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyExecutableAssetDefaults_UsesCutsBesideExecutable()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user