feat: add configurable operator appearance and layout
This commit is contained in:
@@ -358,7 +358,10 @@ public sealed class LegacyOperatorSettingsTests
|
||||
sceneDirectory,
|
||||
resourceDirectory,
|
||||
backgroundDirectory,
|
||||
NavigationExpanded: false);
|
||||
NavigationExpanded: false,
|
||||
ColorTheme: LegacyOperatorColorTheme.Dark,
|
||||
ViewMode: LegacyOperatorViewMode.Cards,
|
||||
StartWorkspace: LegacyOperatorStartWorkspace.LastWorkspace);
|
||||
|
||||
var firstSave = store.Save(settings);
|
||||
var secondSave = store.Save(settings with { NavigationExpanded = true });
|
||||
@@ -370,6 +373,11 @@ public sealed class LegacyOperatorSettingsTests
|
||||
Assert.Null(secondSave.WarningMessage);
|
||||
Assert.True(loaded.LoadedFromDisk);
|
||||
Assert.True(loaded.Settings.NavigationExpanded);
|
||||
Assert.Equal(LegacyOperatorColorTheme.Dark, loaded.Settings.ColorTheme);
|
||||
Assert.Equal(LegacyOperatorViewMode.Cards, loaded.Settings.ViewMode);
|
||||
Assert.Equal(
|
||||
LegacyOperatorStartWorkspace.LastWorkspace,
|
||||
loaded.Settings.StartWorkspace);
|
||||
Assert.Equal(Path.GetFullPath(sceneDirectory), loaded.Settings.SceneDirectory);
|
||||
Assert.Equal(Path.GetFullPath(resourceDirectory), loaded.Settings.ResourceDirectory);
|
||||
Assert.Equal(
|
||||
@@ -389,9 +397,20 @@ public sealed class LegacyOperatorSettingsTests
|
||||
"sceneDirectory",
|
||||
"resourceDirectory",
|
||||
"backgroundDirectory",
|
||||
"navigationExpanded"
|
||||
"navigationExpanded",
|
||||
"colorTheme",
|
||||
"viewMode",
|
||||
"startWorkspace"
|
||||
],
|
||||
names);
|
||||
Assert.Equal(
|
||||
LegacyOperatorSettings.CurrentSchemaVersion,
|
||||
document.RootElement.GetProperty("schemaVersion").GetInt32());
|
||||
Assert.Equal("dark", document.RootElement.GetProperty("colorTheme").GetString());
|
||||
Assert.Equal("cards", document.RootElement.GetProperty("viewMode").GetString());
|
||||
Assert.Equal(
|
||||
"lastWorkspace",
|
||||
document.RootElement.GetProperty("startWorkspace").GetString());
|
||||
Assert.DoesNotContain(
|
||||
document.RootElement.EnumerateObject(),
|
||||
property => property.Name.Contains("password", StringComparison.OrdinalIgnoreCase) ||
|
||||
@@ -399,13 +418,38 @@ public sealed class LegacyOperatorSettingsTests
|
||||
property.Name.Contains("live", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_LegacySchemaUsesClosedAppearanceDefaults()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var configurationPath = Path.Combine(directory.Path, "settings.json");
|
||||
File.WriteAllText(
|
||||
configurationPath,
|
||||
"{\"schemaVersion\":1,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":false}",
|
||||
new UTF8Encoding(false));
|
||||
|
||||
var result = new LegacyOperatorSettingsStore(configurationPath).Load();
|
||||
|
||||
Assert.True(result.LoadedFromDisk);
|
||||
Assert.Equal(LegacyOperatorSettingsStoreFailure.None, result.Failure);
|
||||
Assert.False(result.Settings.NavigationExpanded);
|
||||
Assert.Equal(LegacyOperatorColorTheme.System, result.Settings.ColorTheme);
|
||||
Assert.Equal(LegacyOperatorViewMode.Automatic, result.Settings.ViewMode);
|
||||
Assert.Equal(
|
||||
LegacyOperatorStartWorkspace.StockCut,
|
||||
result.Settings.StartWorkspace);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"schemaVersion\":2,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true}", LegacyOperatorSettingsStoreFailure.UnsupportedSchema)]
|
||||
[InlineData("{\"schemaVersion\":3,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true}", LegacyOperatorSettingsStoreFailure.UnsupportedSchema)]
|
||||
[InlineData("{\"schemaVersion\":1,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true,\"unexpected\":1}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"schemaVersion\":1,\"schemaVersion\":1,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"SchemaVersion\":1,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"schemaVersion\":1,\"sceneDirectory\":\"relative\",\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true}", LegacyOperatorSettingsStoreFailure.InvalidSettings)]
|
||||
[InlineData("{\"schemaVersion\":2,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true,\"colorTheme\":\"mbn\",\"viewMode\":\"automatic\",\"startWorkspace\":\"stockCut\"}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"schemaVersion\":2,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true,\"colorTheme\":\"system\",\"viewMode\":\"grid\",\"startWorkspace\":\"stockCut\"}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
[InlineData("{\"schemaVersion\":2,\"sceneDirectory\":null,\"resourceDirectory\":null,\"backgroundDirectory\":null,\"navigationExpanded\":true,\"colorTheme\":\"system\",\"viewMode\":\"automatic\",\"startWorkspace\":\"other\"}", LegacyOperatorSettingsStoreFailure.InvalidJson)]
|
||||
public void Load_StrictMalformedOrUnsafeJsonFailsClosed(
|
||||
string json,
|
||||
LegacyOperatorSettingsStoreFailure expectedFailure)
|
||||
@@ -463,6 +507,31 @@ public sealed class LegacyOperatorSettingsTests
|
||||
AssertPathFree(result.WarningMessage, settings.SceneDirectory!);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(99, 0, 0)]
|
||||
[InlineData(0, 99, 0)]
|
||||
[InlineData(0, 0, 99)]
|
||||
public void Save_RejectsUndefinedAppearanceValuesWithoutCreatingAConfigurationFile(
|
||||
int colorTheme,
|
||||
int viewMode,
|
||||
int startWorkspace)
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var configurationPath = Path.Combine(directory.Path, "settings.json");
|
||||
var settings = LegacyOperatorSettings.Default with
|
||||
{
|
||||
ColorTheme = (LegacyOperatorColorTheme)colorTheme,
|
||||
ViewMode = (LegacyOperatorViewMode)viewMode,
|
||||
StartWorkspace = (LegacyOperatorStartWorkspace)startWorkspace
|
||||
};
|
||||
|
||||
var result = new LegacyOperatorSettingsStore(configurationPath).Save(settings);
|
||||
|
||||
Assert.False(result.Succeeded);
|
||||
Assert.Equal(LegacyOperatorSettingsStoreFailure.InvalidSettings, result.Failure);
|
||||
Assert.False(File.Exists(configurationPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AbbreviateForDisplay_IsBoundedAndNeverReturnsInvalidInput()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user