diff --git a/.vscode/settings.json b/.vscode/settings.json index 181a5311a..215362548 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,15 @@ "dotnet restore": true, "git checkout": true, "Test-Path": true, - "git rev-parse": true + "git rev-parse": true, + "/^pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild\\.ps1 -SolutionPath TaskMaster\\.sln -Configuration Debug -Platform 'Any CPU' -EnableNETAnalyzers -EnforceCodeStyleInBuild$/": { + "approve": true, + "matchCommandLine": true + }, + "/^pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/vscode/Invoke-VSBuild\\.ps1 -SolutionPath TaskMaster\\.sln -Configuration Debug -Platform 'Any CPU' -EnableNullable -TreatWarningsAsErrors$/": { + "approve": true, + "matchCommandLine": true + } }, "koverage.coverageFileNames": [ "coverage.cobertura.xml" diff --git a/TaskMaster.Test/AppGlobals/AppOlObjectsTests.cs b/TaskMaster.Test/AppGlobals/AppOlObjectsTests.cs index 5d2d484e8..cabc0c47b 100644 --- a/TaskMaster.Test/AppGlobals/AppOlObjectsTests.cs +++ b/TaskMaster.Test/AppGlobals/AppOlObjectsTests.cs @@ -1,8 +1,14 @@ +using System; +using System.Collections; +using System.Reflection; using System.Runtime.InteropServices; using FluentAssertions; using Microsoft.Office.Interop.Outlook; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using UtilitiesCS; +using UtilitiesCS.Dialogs; +using OutlookApplication = Microsoft.Office.Interop.Outlook.Application; namespace TaskMaster.Test.AppGlobals { @@ -126,5 +132,67 @@ public void WriteJunkPotentialSetting_UpdatesJunkPotentialValue() Properties.Settings.Default.JunkPotential = original; } } + + [TestMethod] + public void LoadJunkCertain_KeepsStoredValue_WhenReplacementSelectionIsCancelled() + { + var originalSetting = Properties.Settings.Default.OlJunkCertain; + var dialogInvokerProperty = typeof(MyBox).GetProperty( + "DialogInvoker", + BindingFlags.Static | BindingFlags.NonPublic + )!; + var originalDialogInvoker = dialogInvokerProperty.GetValue(null); + var expected = "Missing\\Junk Email"; + var namespaceMapi = mockRepository.Create(); + namespaceMapi.Setup(x => x.PickFolder()).Returns((MAPIFolder)null); + var application = mockRepository.Create(); + application.SetupGet(x => x.Application).Returns(application.Object); + application.Setup(x => x.GetNamespace("MAPI")).Returns(namespaceMapi.Object); + var root = CreateRootFolder(); + var sut = new AppOlObjects(application.Object, Mock.Of()); + SetPrivateField(sut, "_root", root.Object); + + try + { + Properties.Settings.Default.OlJunkCertain = expected; + dialogInvokerProperty.SetValue( + null, + new Func(_ => + System.Windows.Forms.DialogResult.OK + ) + ); + + sut.LoadJunkCertain().Should().BeNull(); + AppOlObjects.ReadJunkCertainSetting().Should().Be(expected); + } + finally + { + Properties.Settings.Default.OlJunkCertain = originalSetting; + dialogInvokerProperty.SetValue(null, originalDialogInvoker); + } + } + + private Mock CreateRootFolder() + { + var folders = mockRepository.Create(); + folders.SetupGet(x => x.Count).Returns(0); + folders + .As() + .Setup(x => x.GetEnumerator()) + .Returns(Array.Empty().GetEnumerator()); + + var root = mockRepository.Create(); + root.SetupGet(x => x.Name).Returns("Mailbox"); + root.SetupGet(x => x.FolderPath).Returns(@"\\Mailbox"); + root.SetupGet(x => x.Folders).Returns(folders.Object); + return root; + } + + private static void SetPrivateField(object target, string fieldName, object value) + { + typeof(AppOlObjects) + .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)! + .SetValue(target, value); + } } } diff --git a/TaskMaster.Test/TaskMaster.Test.csproj b/TaskMaster.Test/TaskMaster.Test.csproj index c9f21908f..6b987eb0b 100644 --- a/TaskMaster.Test/TaskMaster.Test.csproj +++ b/TaskMaster.Test/TaskMaster.Test.csproj @@ -244,6 +244,7 @@ + diff --git a/TaskMaster/AppGlobals/AppOlObjects.cs b/TaskMaster/AppGlobals/AppOlObjects.cs index 20fca4765..d471a451e 100644 --- a/TaskMaster/AppGlobals/AppOlObjects.cs +++ b/TaskMaster/AppGlobals/AppOlObjects.cs @@ -194,12 +194,37 @@ public string InboxPath private Folder _junkPotential; public Folder JunkPotential => Initializer.GetOrLoad(ref _junkPotential, LoadJunkPotential); + internal static string ReadJunkCertainSetting() => + Properties.Settings.Default.OlJunkCertain; + + internal static void WriteJunkCertainSetting(string relativePath) => + Properties.Settings.Default.OlJunkCertain = relativePath; + internal static string ReadJunkPotentialSetting() => Properties.Settings.Default.JunkPotential; internal static void WriteJunkPotentialSetting(string relativePath) => Properties.Settings.Default.JunkPotential = relativePath; + internal void ApplyJunkFolderSelections( + string junkCertainRelativePath, + string junkPotentialRelativePath + ) + { + WriteJunkCertainSetting(junkCertainRelativePath); + WriteJunkPotentialSetting(junkPotentialRelativePath); + Properties.Settings.Default.Save(); + RefreshJunkFolderSelections(); + } + + internal void RefreshJunkFolderSelections() + { + _junkCertain = null; + _junkPotential = null; + _ = JunkCertain; + _ = JunkPotential; + } + internal Folder LoadJunkPotential() { var root = new FolderTree(Root).Roots.FirstOrDefault(); @@ -250,7 +275,7 @@ internal Folder LoadJunkPotential() internal Folder LoadJunkCertain() { var root = new FolderTree(Root).Roots.FirstOrDefault(); - var folderPath = Properties.Settings.Default.OlJunkCertain; + var folderPath = ReadJunkCertainSetting(); if (folderPath.IsNullOrEmpty()) { return null; @@ -262,7 +287,7 @@ internal Folder LoadJunkCertain() if (folder is null) { MyBox.ShowDialog( - "Junk Potential Folder not found. Please select it manually.", + "Junk Folder not found. Please select it manually.", "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error @@ -273,7 +298,7 @@ internal Folder LoadJunkCertain() return null; } var wrapper = new FolderWrapper(folder, Root); - Properties.Settings.Default.OlJunkCertain = wrapper.RelativePath; + WriteJunkCertainSetting(wrapper.RelativePath); Properties.Settings.Default.Save(); } return folder; diff --git a/TaskMaster/Ribbon/RibbonExplorer.xml b/TaskMaster/Ribbon/RibbonExplorer.xml index 3693e1471..cb9381e9b 100644 --- a/TaskMaster/Ribbon/RibbonExplorer.xml +++ b/TaskMaster/Ribbon/RibbonExplorer.xml @@ -129,6 +129,12 @@ label="Current Location" /> +