fix: persist first-run folder paths only
This commit is contained in:
@@ -138,39 +138,26 @@ public sealed class LegacyOperatorSettingsTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResourceValidation_ParsesEveryClosedUiIniAndOnlyFlagsDatabaseIni()
|
||||
public void ResourceValidation_AcceptsAnEmptyResDirectoryAsADirectRuntimePath()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var resourceDirectory = directory.CreateDirectory("Res");
|
||||
WriteValidResourceFiles(resourceDirectory);
|
||||
File.WriteAllText(
|
||||
Path.Combine(resourceDirectory, "MmoneyCoder.ini"),
|
||||
"secret-content-that-must-not-be-returned");
|
||||
|
||||
var stockMenu = LegacyRuntimeStockCutMenuLoader
|
||||
.ResolveFromResourceDirectory(resourceDirectory);
|
||||
Assert.False(stockMenu.UsesBuiltInCatalog);
|
||||
var uiCatalogs = LegacyRuntimeUiCatalogLoader
|
||||
.ResolveFromResourceDirectory(resourceDirectory);
|
||||
Assert.Empty(uiCatalogs.Warnings);
|
||||
|
||||
var result = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Resource,
|
||||
resourceDirectory);
|
||||
|
||||
Assert.True(result.IsValid, $"{result.Failure}: {result.WarningMessage}");
|
||||
Assert.True(result.Folder!.DatabaseIniDetected);
|
||||
Assert.DoesNotContain("secret", result.Folder.AbbreviatedPath,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Equal(Path.GetFullPath(resourceDirectory), result.Folder!.CanonicalPath);
|
||||
Assert.False(result.Folder.DatabaseIniDetected);
|
||||
Assert.Null(result.WarningMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResourceValidation_InvalidClosedIniFailsWithoutPartialAcceptance()
|
||||
public void ResourceValidation_DoesNotParseIniContents()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var resourceDirectory = directory.CreateDirectory("private-runtime-resources");
|
||||
WriteValidResourceFiles(resourceDirectory);
|
||||
WriteCp949(
|
||||
Path.Combine(resourceDirectory, "종목.ini"),
|
||||
["[종목]", "등록되지_않은_컷"]);
|
||||
@@ -179,32 +166,26 @@ public sealed class LegacyOperatorSettingsTests
|
||||
LegacyOperatorSettingsFolderKind.Resource,
|
||||
resourceDirectory);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Equal(
|
||||
LegacyOperatorFolderValidationFailure.InvalidRuntimeCatalog,
|
||||
result.Failure);
|
||||
Assert.Null(result.Folder);
|
||||
AssertPathFree(result.WarningMessage, resourceDirectory);
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Equal(Path.GetFullPath(resourceDirectory), result.Folder!.CanonicalPath);
|
||||
Assert.Null(result.WarningMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResourceValidation_RejectsAnUnsafeDatabaseIniWithoutReadingIt()
|
||||
public void ResourceValidation_DoesNotInspectDatabaseIni()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var resourceDirectory = directory.CreateDirectory("Res");
|
||||
WriteValidResourceFiles(resourceDirectory);
|
||||
Directory.CreateDirectory(Path.Combine(resourceDirectory, "MmoneyCoder.ini"));
|
||||
|
||||
var result = LegacyOperatorFolderValidator.Validate(
|
||||
LegacyOperatorSettingsFolderKind.Resource,
|
||||
resourceDirectory);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Equal(
|
||||
LegacyOperatorFolderValidationFailure.RequiredFileUnsafe,
|
||||
result.Failure);
|
||||
Assert.Null(result.Folder);
|
||||
AssertPathFree(result.WarningMessage, resourceDirectory);
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Equal(Path.GetFullPath(resourceDirectory), result.Folder!.CanonicalPath);
|
||||
Assert.False(result.Folder.DatabaseIniDetected);
|
||||
Assert.Null(result.WarningMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -59,16 +59,11 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BothFoldersAndAllActiveIniContractsAreValidatedBeforeSetup()
|
||||
public void BothFolderSelectionsValidateOnlyCanonicalPaths()
|
||||
{
|
||||
var setup = File.ReadAllText(Path.Combine(
|
||||
AppRoot,
|
||||
"FirstRunSetupWindow.xaml.cs"));
|
||||
var settings = File.ReadAllText(Path.Combine(
|
||||
RepositoryRoot,
|
||||
"src",
|
||||
"MBN_STOCK_WEBVIEW.LegacyApplication",
|
||||
"LegacyOperatorSettings.cs"));
|
||||
|
||||
Assert.Contains(
|
||||
"LegacyOperatorSettingsFolderKind.Scene",
|
||||
@@ -78,13 +73,8 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
"LegacyOperatorSettingsFolderKind.Resource",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"validation.Folder.DatabaseIniDetected",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"new LegacyIniDatabaseOptionsLoader",
|
||||
setup,
|
||||
Assert.DoesNotContain("MmoneyCoder.ini", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("LegacyIniDatabaseOptionsLoader", setup,
|
||||
StringComparison.Ordinal);
|
||||
var clearCuts = setup.IndexOf(
|
||||
"_cutsDirectory = null;",
|
||||
@@ -112,62 +102,55 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
" \"Res\"",
|
||||
setup.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
|
||||
foreach (var ini in new[]
|
||||
{
|
||||
"종목.ini",
|
||||
"업종_코스피.ini",
|
||||
"업종_코스닥.ini",
|
||||
"해외.ini",
|
||||
"환율.ini",
|
||||
"지수.ini",
|
||||
"종목비교.ini"
|
||||
})
|
||||
{
|
||||
Assert.Contains($"\"{ini}\"", settings, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetupUsesArgumentListAndPinsTheVerifiedLocalK3dAtTheDefaultEndpoint()
|
||||
public void SetupPersistsOnlyTheSelectedPathsWithoutStartingAChildProcess()
|
||||
{
|
||||
var setup = File.ReadAllText(Path.Combine(
|
||||
AppRoot,
|
||||
"FirstRunSetupWindow.xaml.cs"));
|
||||
|
||||
Assert.Contains(
|
||||
"startInfo.ArgumentList.Add(argument);",
|
||||
var saveSettings = RequiredIndex(
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("\"-NoFolderPicker\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains("\"-DatabaseIniPath\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains("\"-ConfigureDevelopmentLive\"", setup, StringComparison.Ordinal);
|
||||
"var saved = store.Save(current with");
|
||||
var saveBinding = RequiredIndex(
|
||||
setup,
|
||||
"SaveRuntimeBinding(repositoryRoot, runtimeRoot);");
|
||||
Assert.True(saveSettings < saveBinding);
|
||||
Assert.Contains(
|
||||
"private const string DefaultPlayoutHost = \"127.0.0.1\";",
|
||||
"var store = new LegacyOperatorSettingsStore();",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"private const int DefaultPlayoutPort = 30001;",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("\"-PinRegisteredK3D\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains("\"-ReplaceRuntimeBinding\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains("\"-ReplaceDatabaseProfile\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains("\"-ReplaceLiveConfig\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"result.LocalConfigurationReplacementRequired",
|
||||
"SceneDirectory = cutsDirectory",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"await ConfirmLocalConfigurationReplacementAsync()",
|
||||
"ResourceDirectory = resourceDirectory",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("\"-ReplaceK3DPin\"", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("\"-SkipBuild\"", setup, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Directory.Build.local.props",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"File.Move(temporary, destination, overwrite: true);",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("ProcessStartInfo", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("Process.Start", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("RunSetupAsync", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("powershell.exe", setup, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.DoesNotContain("dotnet", setup, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.DoesNotContain("ConfigureDevelopmentLive", setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("PinRegisteredK3D", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("DatabaseIniPath", setup, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SourceOnlyBuildEmbedsOnlyItsOwnClonePathForTheReviewedSetupScript()
|
||||
public void SourceOnlyBuildEmbedsOnlyItsOwnClonePathForTheLocalBinding()
|
||||
{
|
||||
var project = XDocument.Load(Path.Combine(
|
||||
AppRoot,
|
||||
@@ -283,4 +266,11 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
|
||||
throw new DirectoryNotFoundException("Repository root was not found.");
|
||||
}
|
||||
|
||||
private static int RequiredIndex(string value, string marker)
|
||||
{
|
||||
var index = value.IndexOf(marker, StringComparison.Ordinal);
|
||||
Assert.True(index >= 0, $"Required marker was not found: {marker}");
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,9 @@ public sealed class LegacyOperatorSettingsWebContractTests
|
||||
Assert.Contains("databasePollingSeconds", App, StringComparison.Ordinal);
|
||||
Assert.Contains("LegacyOperatorFolderValidator.TryValidate", SettingsHost,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("CanReadSelectedDatabaseProfile", SettingsHost,
|
||||
Assert.DoesNotContain("CanReadSelectedDatabaseProfile", SettingsHost,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("LegacyIniDatabaseOptionsLoader", SettingsHost,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("ResolveDatabaseHealthLabel", SettingsHost,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Reference in New Issue
Block a user