diff --git a/Keybinding.Test/DefaultProfileReactivationTests.cs b/Keybinding.Test/DefaultProfileReactivationTests.cs new file mode 100644 index 0000000..e56adc2 --- /dev/null +++ b/Keybinding.Test/DefaultProfileReactivationTests.cs @@ -0,0 +1,76 @@ +// Copyright (c) 2023-2026 ktsu-dev contributors + +namespace ktsu.Keybinding.Test; + +using ktsu.Keybinding.Core; +using ktsu.Keybinding.Core.Models; + +[TestClass] +public class DefaultProfileReactivationTests +{ + private string _testDataDirectory = null!; + + [TestInitialize] + public void Setup() + { + _testDataDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(_testDataDirectory); + } + + [TestCleanup] + public void Cleanup() + { + if (Directory.Exists(_testDataDirectory)) + { + Directory.Delete(_testDataDirectory, recursive: true); + } + } + + [TestMethod] + public async Task CreateDefaultProfile_AfterActiveProfileWasDeleted_ActivatesExistingDefaultOnNextLaunch() + { + { + using KeybindingManager manager = new(_testDataDirectory); + await manager.InitializeAsync().ConfigureAwait(false); + manager.CreateDefaultProfile(); + manager.Profiles.CreateProfile("vim", "Vim"); + Assert.IsTrue(manager.Profiles.SetActiveProfile("vim")); + Assert.IsTrue(manager.Profiles.DeleteProfile("vim")); + await manager.SaveAsync().ConfigureAwait(false); + } + + { + using KeybindingManager manager = new(_testDataDirectory); + await manager.InitializeAsync().ConfigureAwait(false); + manager.CreateDefaultProfile(); + manager.RegisterCommands([new Command("file.save", "Save")]); + + Assert.AreEqual("default", manager.Profiles.GetActiveProfile()?.Id); + Assert.IsTrue(manager.Keybindings.BindChord("file.save", Chord.Parse("Ctrl+S"))); + Assert.AreEqual("file.save", manager.Keybindings.ExecuteChord(Chord.Parse("Ctrl+S"))); + } + } + + [TestMethod] + public void CreateDefaultProfile_ExistingDefaultWhileAnotherIsActive_LeavesActiveProfileAlone() + { + using KeybindingManager manager = new(_testDataDirectory); + manager.CreateDefaultProfile(); + manager.Profiles.CreateProfile("vim", "Vim"); + Assert.IsTrue(manager.Profiles.SetActiveProfile("vim")); + + Assert.IsNull(manager.CreateDefaultProfile()); + Assert.AreEqual("vim", manager.Profiles.GetActiveProfile()?.Id); + } + + [TestMethod] + public void CreateDefaultProfile_ExistingDefaultWithDoNotActivate_LeavesNoActiveProfile() + { + using KeybindingManager manager = new(_testDataDirectory); + manager.CreateDefaultProfile(); + manager.Profiles.ClearActiveProfile(); + + Assert.IsNull(manager.CreateDefaultProfile(activation: ProfileActivation.DoNotActivate)); + Assert.IsNull(manager.Profiles.GetActiveProfile()); + } +} diff --git a/Keybinding/KeybindingManager.cs b/Keybinding/KeybindingManager.cs index b73c08d..e1b2a6a 100644 --- a/Keybinding/KeybindingManager.cs +++ b/Keybinding/KeybindingManager.cs @@ -150,7 +150,11 @@ public async Task SaveAsync() /// /// The ID for the default profile /// The name for the default profile - /// Whether to set as the active profile + /// + /// Whether to set as the active profile. When the profile already exists, it is activated only if no + /// profile is active, so a startup call recovers from a deleted or unset active profile without + /// overriding the one the user chose. + /// /// The created profile, or null if a profile already exists with the given ID public Profile? CreateDefaultProfile(string profileId = "default", string profileName = "Default", ProfileActivation activation = ProfileActivation.Activate) { @@ -158,6 +162,11 @@ public async Task SaveAsync() if (Profiles.ProfileExists(profileId)) { + if (activation == ProfileActivation.Activate && Profiles.GetActiveProfile() is null) + { + Profiles.SetActiveProfile(profileId); + } + return null; }