diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs index d9522729..0b79fecd 100644 --- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs @@ -6,7 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using SafeExamBrowser.Client.Behaviour; @@ -33,139 +32,145 @@ namespace SafeExamBrowser.Client.UnitTests private ClientController sut; - [TestInitialize] - public void Initialize() - { - displayMonitorMock = new Mock(); - loggerMock = new Mock(); - processMonitorMock = new Mock(); - operationSequenceMock = new Mock(); - runtimeProxyMock = new Mock(); - taskbarMock = new Mock(); - uiFactoryMock = new Mock(); - windowMonitorMock= new Mock(); - - operationSequenceMock.Setup(o => o.TryPerform()).Returns(true); - - sut = new ClientController( - displayMonitorMock.Object, - loggerMock.Object, - operationSequenceMock.Object, - processMonitorMock.Object, - runtimeProxyMock.Object, - new Action(() => { }), - taskbarMock.Object, - uiFactoryMock.Object, - windowMonitorMock.Object); - - sut.TryStart(); - } - [TestMethod] - public void MustHandleDisplayChangeCorrectly() + public void TODO() { - var order = 0; - var workingArea = 0; - var taskbar = 0; - - displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order); - taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order); - - displayMonitorMock.Raise(d => d.DisplayChanged += null); - - displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once); - taskbarMock.Verify(t => t.InitializeBounds(), Times.Once); - - Assert.IsTrue(workingArea == 1); - Assert.IsTrue(taskbar == 2); + Assert.Fail(); } - [TestMethod] - public void MustHandleExplorerStartCorrectly() - { - var order = 0; - var processManager = 0; - var workingArea = 0; - var taskbar = 0; + //[TestInitialize] + //public void Initialize() + //{ + // displayMonitorMock = new Mock(); + // loggerMock = new Mock(); + // processMonitorMock = new Mock(); + // operationSequenceMock = new Mock(); + // runtimeProxyMock = new Mock(); + // taskbarMock = new Mock(); + // uiFactoryMock = new Mock(); + // windowMonitorMock= new Mock(); - processMonitorMock.Setup(p => p.CloseExplorerShell()).Callback(() => processManager = ++order); - displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order); - taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order); + // operationSequenceMock.Setup(o => o.TryPerform()).Returns(true); - processMonitorMock.Raise(p => p.ExplorerStarted += null); + // sut = new ClientController( + // displayMonitorMock.Object, + // loggerMock.Object, + // operationSequenceMock.Object, + // processMonitorMock.Object, + // runtimeProxyMock.Object, + // new Action(() => { }), + // taskbarMock.Object, + // uiFactoryMock.Object, + // windowMonitorMock.Object); - processMonitorMock.Verify(p => p.CloseExplorerShell(), Times.Once); - displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once); - taskbarMock.Verify(t => t.InitializeBounds(), Times.Once); + // sut.TryStart(); + //} - Assert.IsTrue(processManager == 1); - Assert.IsTrue(workingArea == 2); - Assert.IsTrue(taskbar == 3); - } + //[TestMethod] + //public void MustHandleDisplayChangeCorrectly() + //{ + // var order = 0; + // var workingArea = 0; + // var taskbar = 0; - [TestMethod] - public void MustHandleAllowedWindowChangeCorrectly() - { - var window = new IntPtr(12345); + // displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order); + // taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order); - processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(true); + // displayMonitorMock.Raise(d => d.DisplayChanged += null); - windowMonitorMock.Raise(w => w.WindowChanged += null, window); + // displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once); + // taskbarMock.Verify(t => t.InitializeBounds(), Times.Once); - processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); - windowMonitorMock.Verify(w => w.Hide(window), Times.Never); - windowMonitorMock.Verify(w => w.Close(window), Times.Never); - } + // Assert.IsTrue(workingArea == 1); + // Assert.IsTrue(taskbar == 2); + //} - [TestMethod] - public void MustHandleUnallowedWindowHideCorrectly() - { - var order = 0; - var belongs = 0; - var hide = 0; - var window = new IntPtr(12345); + //[TestMethod] + //public void MustHandleExplorerStartCorrectly() + //{ + // var order = 0; + // var processManager = 0; + // var workingArea = 0; + // var taskbar = 0; - processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order); - windowMonitorMock.Setup(w => w.Hide(window)).Returns(true).Callback(() => hide = ++order); + // processMonitorMock.Setup(p => p.CloseExplorerShell()).Callback(() => processManager = ++order); + // displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order); + // taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order); - windowMonitorMock.Raise(w => w.WindowChanged += null, window); + // processMonitorMock.Raise(p => p.ExplorerStarted += null); - processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); - windowMonitorMock.Verify(w => w.Hide(window), Times.Once); - windowMonitorMock.Verify(w => w.Close(window), Times.Never); + // processMonitorMock.Verify(p => p.CloseExplorerShell(), Times.Once); + // displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once); + // taskbarMock.Verify(t => t.InitializeBounds(), Times.Once); - Assert.IsTrue(belongs == 1); - Assert.IsTrue(hide == 2); - } + // Assert.IsTrue(processManager == 1); + // Assert.IsTrue(workingArea == 2); + // Assert.IsTrue(taskbar == 3); + //} - [TestMethod] - public void MustHandleUnallowedWindowCloseCorrectly() - { - var order = 0; - var belongs = 0; - var hide = 0; - var close = 0; - var window = new IntPtr(12345); + //[TestMethod] + //public void MustHandleAllowedWindowChangeCorrectly() + //{ + // var window = new IntPtr(12345); - processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order); - windowMonitorMock.Setup(w => w.Hide(window)).Returns(false).Callback(() => hide = ++order); - windowMonitorMock.Setup(w => w.Close(window)).Callback(() => close = ++order); + // processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(true); - windowMonitorMock.Raise(w => w.WindowChanged += null, window); + // windowMonitorMock.Raise(w => w.WindowChanged += null, window); - processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); - windowMonitorMock.Verify(w => w.Hide(window), Times.Once); - windowMonitorMock.Verify(w => w.Close(window), Times.Once); + // processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); + // windowMonitorMock.Verify(w => w.Hide(window), Times.Never); + // windowMonitorMock.Verify(w => w.Close(window), Times.Never); + //} - Assert.IsTrue(belongs == 1); - Assert.IsTrue(hide == 2); - Assert.IsTrue(close == 3); - } + //[TestMethod] + //public void MustHandleUnallowedWindowHideCorrectly() + //{ + // var order = 0; + // var belongs = 0; + // var hide = 0; + // var window = new IntPtr(12345); - [TestCleanup] - public void Cleanup() - { - // TODO sut.Stop(); - } + // processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order); + // windowMonitorMock.Setup(w => w.Hide(window)).Returns(true).Callback(() => hide = ++order); + + // windowMonitorMock.Raise(w => w.WindowChanged += null, window); + + // processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); + // windowMonitorMock.Verify(w => w.Hide(window), Times.Once); + // windowMonitorMock.Verify(w => w.Close(window), Times.Never); + + // Assert.IsTrue(belongs == 1); + // Assert.IsTrue(hide == 2); + //} + + //[TestMethod] + //public void MustHandleUnallowedWindowCloseCorrectly() + //{ + // var order = 0; + // var belongs = 0; + // var hide = 0; + // var close = 0; + // var window = new IntPtr(12345); + + // processMonitorMock.Setup(p => p.BelongsToAllowedProcess(window)).Returns(false).Callback(() => belongs = ++order); + // windowMonitorMock.Setup(w => w.Hide(window)).Returns(false).Callback(() => hide = ++order); + // windowMonitorMock.Setup(w => w.Close(window)).Callback(() => close = ++order); + + // windowMonitorMock.Raise(w => w.WindowChanged += null, window); + + // processMonitorMock.Verify(p => p.BelongsToAllowedProcess(window), Times.Once); + // windowMonitorMock.Verify(w => w.Hide(window), Times.Once); + // windowMonitorMock.Verify(w => w.Close(window), Times.Once); + + // Assert.IsTrue(belongs == 1); + // Assert.IsTrue(hide == 2); + // Assert.IsTrue(close == 3); + //} + + //[TestCleanup] + //public void Cleanup() + //{ + // // TODO sut.Stop(); + //} } } diff --git a/SafeExamBrowser.Client/Behaviour/ClientController.cs b/SafeExamBrowser.Client/Behaviour/ClientController.cs index 846a6d5b..8b0a6a3e 100644 --- a/SafeExamBrowser.Client/Behaviour/ClientController.cs +++ b/SafeExamBrowser.Client/Behaviour/ClientController.cs @@ -80,7 +80,7 @@ namespace SafeExamBrowser.Client.Behaviour splashScreen = uiFactory.CreateSplashScreen(); operations.ProgressIndicator = splashScreen; - var success = operations.TryPerform(); + var success = operations.TryPerform() == OperationResult.Success; if (success) { diff --git a/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs index f2def3b3..d423f805 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs @@ -24,7 +24,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ITaskbar taskbar; private IUserInterfaceFactory uiFactory; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public BrowserOperation( @@ -41,7 +40,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.uiFactory = uiFactory; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing browser..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeBrowser, true); @@ -52,11 +51,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations browserController.RegisterApplicationButton(browserButton); taskbar.AddApplication(browserButton); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs index 748afcdc..d5d41a93 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs @@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private INativeMethods nativeMethods; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public ClipboardOperation(ILogger logger, INativeMethods nativeMethods) @@ -28,14 +27,16 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.nativeMethods = nativeMethods; } - public void Perform() + public OperationResult Perform() { EmptyClipboard(); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs index 814e7590..7b27edec 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs @@ -22,7 +22,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IRuntimeProxy runtime; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public ConfigurationOperation(ClientConfiguration configuration, ILogger logger, IRuntimeProxy runtime) @@ -32,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.runtime = runtime; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing application configuration..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration); @@ -50,12 +49,16 @@ namespace SafeExamBrowser.Client.Behaviour.Operations catch (Exception e) { logger.Error("An unexpected error occurred while trying to retrieve the application configuration!", e); + + return OperationResult.Failed; } + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs index fcd887f0..84845921 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs @@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private ITaskbar taskbar; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar) @@ -31,7 +30,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.taskbar = taskbar; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing working area..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeWorkingArea); @@ -39,11 +38,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations displayMonitor.PreventSleepMode(); displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight()); displayMonitor.StartMonitoringDisplayChanges(); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs index abb70169..2f87b070 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs @@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private INativeMethods nativeMethods; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public KeyboardInterceptorOperation( @@ -34,17 +33,19 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.nativeMethods = nativeMethods; } - public void Perform() + public OperationResult Perform() { logger.Info("Starting keyboard interception..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartKeyboardInterception); nativeMethods.RegisterKeyboardHook(keyboardInterceptor); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs index 15f8e330..fcf9a087 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs @@ -21,7 +21,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private IMouseInterceptor mouseInterceptor; private INativeMethods nativeMethods; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public MouseInterceptorOperation( @@ -34,17 +33,19 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.nativeMethods = nativeMethods; } - public void Perform() + public OperationResult Perform() { logger.Info("Starting mouse interception..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartMouseInterception); nativeMethods.RegisterMouseHook(mouseInterceptor); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs index 0e2a0fb9..94bcce9c 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs @@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IProcessMonitor processMonitor; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor) @@ -28,7 +27,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.processMonitor = processMonitor; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing process monitoring..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_WaitExplorerTermination, true); @@ -39,11 +38,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeProcessMonitoring); // TODO: Implement process monitoring... + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs index 8775d1f7..5a62a7f4 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs @@ -22,7 +22,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private IRuntimeProxy runtime; private Guid token; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public RuntimeConnectionOperation(ILogger logger, IRuntimeProxy runtime, Guid token) @@ -32,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.token = token; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing runtime connection..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeRuntimeConnection); @@ -46,20 +45,21 @@ namespace SafeExamBrowser.Client.Behaviour.Operations logger.Error("An unexpected error occurred while trying to connect to the runtime!", e); } - if (connected) + if (!connected) { - logger.Info("Successfully connected to the runtime."); - } - else - { - Abort = true; logger.Error("Failed to connect to the runtime. Aborting startup..."); + + return OperationResult.Failed; } + + logger.Info("Successfully connected to the runtime."); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs index 32f37644..3ffe568f 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs @@ -32,7 +32,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private IUserInterfaceFactory uiFactory; private IText text; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public TaskbarOperation( @@ -61,7 +60,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.wirelessNetwork = wirelessNetwork; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing taskbar..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeTaskbar); @@ -85,11 +84,13 @@ namespace SafeExamBrowser.Client.Behaviour.Operations { AddWirelessNetworkControl(); } + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs index 514b3269..27319b23 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs @@ -19,7 +19,6 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IWindowMonitor windowMonitor; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor) @@ -28,18 +27,20 @@ namespace SafeExamBrowser.Client.Behaviour.Operations this.windowMonitor = windowMonitor; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing window monitoring..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeWindowMonitoring); windowMonitor.HideAllWindows(); windowMonitor.StartMonitoringWindows(); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Contracts/Behaviour/Operations/IOperation.cs b/SafeExamBrowser.Contracts/Behaviour/Operations/IOperation.cs index 32cd9cdb..2e71b44c 100644 --- a/SafeExamBrowser.Contracts/Behaviour/Operations/IOperation.cs +++ b/SafeExamBrowser.Contracts/Behaviour/Operations/IOperation.cs @@ -12,11 +12,6 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations { public interface IOperation { - /// - /// Determines whether the procedure to which this operation belongs to should be aborted. - /// - bool Abort { get; } - /// /// The progress indicator to be used to show status information to the user. Will be ignored if null. /// @@ -25,15 +20,15 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations /// /// Performs the operation. /// - void Perform(); + OperationResult Perform(); /// /// Repeats the operation. /// - void Repeat(); + OperationResult Repeat(); /// - /// Reverts all changes which were made when performing the operation. + /// Reverts all changes which were made when executing the operation. /// void Revert(); } diff --git a/SafeExamBrowser.Contracts/Behaviour/Operations/IOperationSequence.cs b/SafeExamBrowser.Contracts/Behaviour/Operations/IOperationSequence.cs index b0f94591..26945ef8 100644 --- a/SafeExamBrowser.Contracts/Behaviour/Operations/IOperationSequence.cs +++ b/SafeExamBrowser.Contracts/Behaviour/Operations/IOperationSequence.cs @@ -13,22 +13,23 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations public interface IOperationSequence { /// - /// The progress indicator to be used when performing any action. Will be ignored if null. + /// The progress indicator to be used when executing an operation. Will be ignored if null. /// IProgressIndicator ProgressIndicator { set; } /// - /// Tries to perform the operations of this sequence. Returns true if the procedure was successful, false otherwise. + /// Tries to perform the operations of this sequence. /// - bool TryPerform(); + OperationResult TryPerform(); /// - /// Tries to repeat the operations of this sequence. Returns true if the procedure was successful, false otherwise. + /// Tries to repeat the operations of this sequence. /// - bool TryRepeat(); + OperationResult TryRepeat(); /// - /// Tries to revert the operations of this sequence. Returns true if the procedure was successful, false otherwise. + /// Tries to revert the operations of this sequence. Returns true if all operations were reverted without errors, + /// otherwise false. /// bool TryRevert(); } diff --git a/SafeExamBrowser.Contracts/Behaviour/Operations/OperationResult.cs b/SafeExamBrowser.Contracts/Behaviour/Operations/OperationResult.cs new file mode 100644 index 00000000..6036fbd1 --- /dev/null +++ b/SafeExamBrowser.Contracts/Behaviour/Operations/OperationResult.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +namespace SafeExamBrowser.Contracts.Behaviour.Operations +{ + public enum OperationResult + { + /// + /// Indicates that the operation has been aborted due to an expected condition, e.g. as result of a user decision. + /// + Aborted, + + /// + /// Indicates that the operation has failed due to an invalid or unexpected condition. + /// + Failed, + + /// + /// Indicates that the operation has been executed successfully. + /// + Success + } +} diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj index f87bbcf4..1dd5f84b 100644 --- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj +++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj @@ -56,6 +56,7 @@ + diff --git a/SafeExamBrowser.Core.UnitTests/Behaviour/Operations/OperationSequenceTests.cs b/SafeExamBrowser.Core.UnitTests/Behaviour/Operations/OperationSequenceTests.cs index 9add7677..c20a0bed 100644 --- a/SafeExamBrowser.Core.UnitTests/Behaviour/Operations/OperationSequenceTests.cs +++ b/SafeExamBrowser.Core.UnitTests/Behaviour/Operations/OperationSequenceTests.cs @@ -36,6 +36,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success); + operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); @@ -61,14 +65,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); - operationB.SetupGet(o => o.Abort).Returns(true); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Aborted); operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryPerform(); + var result = sut.TryPerform(); operationA.Verify(o => o.Perform(), Times.Once); operationA.Verify(o => o.Revert(), Times.Once); @@ -77,7 +82,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationC.Verify(o => o.Perform(), Times.Never); operationC.Verify(o => o.Revert(), Times.Never); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Aborted, result); } [TestMethod] @@ -88,12 +93,16 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success); + operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryPerform(); + var result = sut.TryPerform(); operationA.Verify(o => o.Perform(), Times.Once); operationA.Verify(o => o.Revert(), Times.Never); @@ -102,7 +111,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationC.Verify(o => o.Perform(), Times.Once); operationC.Verify(o => o.Revert(), Times.Never); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); } [TestMethod] @@ -114,18 +123,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); - operationA.Setup(o => o.Perform()).Callback(() => a = ++current); - operationB.Setup(o => o.Perform()).Callback(() => b = ++current); - operationC.Setup(o => o.Perform()).Callback(() => c = ++current); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => a = ++current); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => b = ++current); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success).Callback(() => c = ++current); operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryPerform(); + var result = sut.TryPerform(); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); Assert.IsTrue(a == 1); Assert.IsTrue(b == 2); Assert.IsTrue(c == 3); @@ -140,6 +149,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationD = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); operationC.Setup(o => o.Perform()).Throws(); operations.Enqueue(operationA.Object); @@ -148,7 +159,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operations.Enqueue(operationD.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryPerform(); + var result = sut.TryPerform(); operationA.Verify(o => o.Perform(), Times.Once); operationA.Verify(o => o.Revert(), Times.Once); @@ -159,7 +170,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationD.Verify(o => o.Perform(), Times.Never); operationD.Verify(o => o.Revert(), Times.Never); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Failed, result); } [TestMethod] @@ -172,10 +183,12 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationD = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); operationA.Setup(o => o.Revert()).Callback(() => a = ++current); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); operationB.Setup(o => o.Revert()).Callback(() => b = ++current); - operationC.Setup(o => o.Revert()).Callback(() => c = ++current); operationC.Setup(o => o.Perform()).Throws(); + operationC.Setup(o => o.Revert()).Callback(() => c = ++current); operationD.Setup(o => o.Revert()).Callback(() => d = ++current); operations.Enqueue(operationA.Object); @@ -184,9 +197,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operations.Enqueue(operationD.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryPerform(); + var result = sut.TryPerform(); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Failed, result); Assert.IsTrue(d == 0); Assert.IsTrue(c == 1); Assert.IsTrue(b == 2); @@ -201,7 +214,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); operationC.Setup(o => o.Perform()).Throws(); + operationC.Setup(o => o.Revert()).Throws(); operationB.Setup(o => o.Revert()).Throws(); operationA.Setup(o => o.Revert()).Throws(); @@ -225,9 +241,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations public void MustSucceedWithEmptyQueue() { var sut = new OperationSequence(loggerMock.Object, new Queue()); - var success = sut.TryPerform(); + var result = sut.TryPerform(); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); } @@ -240,9 +256,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations indicatorMock.Setup(i => i.SetMaxValue(It.IsAny())).Throws(); sut.ProgressIndicator = indicatorMock.Object; - var success = sut.TryPerform(); + var result = sut.TryPerform(); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Failed, result); } #endregion @@ -257,14 +273,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); - operationB.SetupGet(o => o.Abort).Returns(true); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Aborted); operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); operationA.Verify(o => o.Repeat(), Times.Once); operationA.Verify(o => o.Revert(), Times.Never); @@ -273,7 +290,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationC.Verify(o => o.Repeat(), Times.Never); operationC.Verify(o => o.Revert(), Times.Never); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Aborted, result); } [TestMethod] @@ -284,12 +301,16 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); operationA.Verify(o => o.Perform(), Times.Never); operationA.Verify(o => o.Repeat(), Times.Once); @@ -301,7 +322,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationC.Verify(o => o.Repeat(), Times.Once); operationC.Verify(o => o.Revert(), Times.Never); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); } [TestMethod] @@ -313,18 +334,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); - operationA.Setup(o => o.Repeat()).Callback(() => a = ++current); - operationB.Setup(o => o.Repeat()).Callback(() => b = ++current); - operationC.Setup(o => o.Repeat()).Callback(() => c = ++current); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => a = ++current); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => b = ++current); + operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success).Callback(() => c = ++current); operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); Assert.IsTrue(a == 1); Assert.IsTrue(b == 2); Assert.IsTrue(c == 3); @@ -339,6 +360,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationD = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success); operationC.Setup(o => o.Repeat()).Throws(); operations.Enqueue(operationA.Object); @@ -347,7 +370,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operations.Enqueue(operationD.Object); var sut = new OperationSequence(loggerMock.Object, operations); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); operationA.Verify(o => o.Repeat(), Times.Once); operationA.Verify(o => o.Revert(), Times.Never); @@ -358,25 +381,25 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations operationD.Verify(o => o.Repeat(), Times.Never); operationD.Verify(o => o.Revert(), Times.Never); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Failed, result); } [TestMethod] public void MustSucceedRepeatingWithEmptyQueue() { var sut = new OperationSequence(loggerMock.Object, new Queue()); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); } [TestMethod] public void MustSucceedRepeatingWithoutCallingPerform() { var sut = new OperationSequence(loggerMock.Object, new Queue()); - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); - Assert.IsTrue(success); + Assert.AreEqual(OperationResult.Success, result); } [TestMethod] @@ -388,9 +411,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations indicatorMock.Setup(i => i.SetMaxValue(It.IsAny())).Throws(); sut.ProgressIndicator = indicatorMock.Object; - var success = sut.TryRepeat(); + var result = sut.TryRepeat(); - Assert.IsFalse(success); + Assert.AreEqual(OperationResult.Failed, result); } #endregion @@ -405,6 +428,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationC.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); operations.Enqueue(operationC.Object); @@ -431,6 +461,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationA.Setup(o => o.Revert()).Callback(() => a = ++current); operationB.Setup(o => o.Revert()).Callback(() => b = ++current); operationC.Setup(o => o.Revert()).Callback(() => c = ++current); @@ -459,6 +493,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationC.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationA.Setup(o => o.Revert()).Throws(); operationB.Setup(o => o.Revert()).Throws(); operationC.Setup(o => o.Revert()).Throws(); @@ -488,7 +526,10 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations var operationC = new Mock(); var operations = new Queue(); - operationB.SetupGet(o => o.Abort).Returns(true); + operationA.Setup(o => o.Perform()).Returns(OperationResult.Success); + operationA.Setup(o => o.Repeat()).Returns(OperationResult.Success); + operationB.Setup(o => o.Perform()).Returns(OperationResult.Aborted); + operationB.Setup(o => o.Repeat()).Returns(OperationResult.Success); operations.Enqueue(operationA.Object); operations.Enqueue(operationB.Object); diff --git a/SafeExamBrowser.Core/Behaviour/Operations/CommunicationOperation.cs b/SafeExamBrowser.Core/Behaviour/Operations/CommunicationOperation.cs index 7ae5891b..2894a589 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/CommunicationOperation.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/CommunicationOperation.cs @@ -19,7 +19,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations private ICommunicationHost host; private ILogger logger; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public CommunicationOperation(ICommunicationHost host, ILogger logger) @@ -28,15 +27,17 @@ namespace SafeExamBrowser.Core.Behaviour.Operations this.logger = logger; } - public void Perform() + public OperationResult Perform() { logger.Info("Starting communication host..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartCommunicationHost); host.Start(); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { if (!host.IsRunning) { @@ -46,6 +47,8 @@ namespace SafeExamBrowser.Core.Behaviour.Operations host.Stop(); host.Start(); } + + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Core/Behaviour/Operations/DelayedInitializationOperation.cs b/SafeExamBrowser.Core/Behaviour/Operations/DelayedInitializationOperation.cs index 3a193c8e..5dfbce7d 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/DelayedInitializationOperation.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/DelayedInitializationOperation.cs @@ -17,7 +17,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations private Func initialize; private IOperation operation; - public bool Abort { get; set; } public IProgressIndicator ProgressIndicator { get; set; } public DelayedInitializationOperation(Func initialize) @@ -25,21 +24,19 @@ namespace SafeExamBrowser.Core.Behaviour.Operations this.initialize = initialize; } - public void Perform() + public OperationResult Perform() { operation = initialize.Invoke(); operation.ProgressIndicator = ProgressIndicator; - operation.Perform(); - Abort = operation.Abort; + return operation.Perform(); } - public void Repeat() + public OperationResult Repeat() { operation.ProgressIndicator = ProgressIndicator; - operation.Repeat(); - Abort = operation.Abort; + return operation.Repeat(); } public void Revert() diff --git a/SafeExamBrowser.Core/Behaviour/Operations/DelegateOperation.cs b/SafeExamBrowser.Core/Behaviour/Operations/DelegateOperation.cs index b5c42338..f48f5a75 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/DelegateOperation.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/DelegateOperation.cs @@ -18,7 +18,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations private Action repeat; private Action revert; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public DelegateOperation(Action perform, Action repeat = null, Action revert = null) @@ -28,14 +27,18 @@ namespace SafeExamBrowser.Core.Behaviour.Operations this.revert = revert; } - public void Perform() + public OperationResult Perform() { perform?.Invoke(); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { repeat?.Invoke(); + + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs b/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs index 23e86583..b9481682 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs @@ -22,7 +22,6 @@ namespace SafeExamBrowser.Core.Behaviour.Operations private ILogger logger; private IText text; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public I18nOperation(ILogger logger, IText text) @@ -31,7 +30,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations this.text = text; } - public void Perform() + public OperationResult Perform() { logger.Info($"Loading default text data (the currently active culture is '{CultureInfo.CurrentCulture.Name}')..."); @@ -40,11 +39,13 @@ namespace SafeExamBrowser.Core.Behaviour.Operations var textResource = new XmlTextResource(path); text.Initialize(textResource); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { - // Nothing to do here... + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Core/Behaviour/Operations/OperationSequence.cs b/SafeExamBrowser.Core/Behaviour/Operations/OperationSequence.cs index 3dff57a9..ab00ded2 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/OperationSequence.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/OperationSequence.cs @@ -29,16 +29,16 @@ namespace SafeExamBrowser.Core.Behaviour.Operations this.operations = new Queue(operations); } - public bool TryPerform() + public OperationResult TryPerform() { - var success = false; + var result = OperationResult.Failed; try { Initialize(); - success = Perform(); + result = Perform(); - if (!success) + if (result != OperationResult.Success) { Revert(true); } @@ -48,24 +48,24 @@ namespace SafeExamBrowser.Core.Behaviour.Operations logger.Error("Failed to perform operations!", e); } - return success; + return result; } - public bool TryRepeat() + public OperationResult TryRepeat() { - var success = false; + var result = OperationResult.Failed; try { Initialize(); - success = Repeat(); + result = Repeat(); } catch (Exception e) { logger.Error("Failed to repeat operations!", e); } - return success; + return result; } public bool TryRevert() @@ -98,60 +98,60 @@ namespace SafeExamBrowser.Core.Behaviour.Operations } } - private bool Perform() + private OperationResult Perform() { foreach (var operation in operations) { + var result = OperationResult.Failed; + stack.Push(operation); try { operation.ProgressIndicator = ProgressIndicator; - operation.Perform(); + result = operation.Perform(); } catch (Exception e) { - logger.Error($"Failed to perform operation '{operation.GetType().Name}'!", e); - - return false; + logger.Error($"Caught unexpected exception while performing operation '{operation.GetType().Name}'!", e); } - if (operation.Abort) + if (result != OperationResult.Success) { - return false; + return result; } ProgressIndicator?.Progress(); } - return true; + return OperationResult.Success; } - private bool Repeat() + private OperationResult Repeat() { foreach (var operation in operations) { + var result = OperationResult.Failed; + try { operation.ProgressIndicator = ProgressIndicator; - operation.Repeat(); + result = operation.Repeat(); } catch (Exception e) { - logger.Error($"Failed to repeat operation '{operation.GetType().Name}'!", e); - - return false; + logger.Error($"Caught unexpected exception while repeating operation '{operation.GetType().Name}'!", e); } - if (operation.Abort) + if (result != OperationResult.Success) { - return false; + return result; } ProgressIndicator?.Progress(); } - return true; + return OperationResult.Success; } private bool Revert(bool regress = false) diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs index 04ca2dd3..579d9c3f 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs @@ -10,6 +10,7 @@ using System; using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using SafeExamBrowser.Contracts.Behaviour.Operations; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; @@ -136,9 +137,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations sut = new ConfigurationOperation(repository.Object, logger.Object, info, text.Object, uiFactory.Object, null); - sut.Perform(); + var result = sut.Perform(); - Assert.IsTrue(sut.Abort); + Assert.AreEqual(OperationResult.Aborted, result); } [TestMethod] @@ -148,9 +149,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations sut = new ConfigurationOperation(repository.Object, logger.Object, info, text.Object, uiFactory.Object, null); - sut.Perform(); + var result = sut.Perform(); - Assert.IsFalse(sut.Abort); + Assert.AreEqual(OperationResult.Success, result); } } } diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceConnectionOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceConnectionOperationTests.cs index 05768eff..cbb6e255 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceConnectionOperationTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceConnectionOperationTests.cs @@ -9,6 +9,7 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using SafeExamBrowser.Contracts.Behaviour.Operations; using SafeExamBrowser.Contracts.Communication; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration.Settings; @@ -82,26 +83,27 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations } [TestMethod] - public void MustAbortIfServiceMandatoryAndNotAvailable() + public void MustFailIfServiceMandatoryAndNotAvailable() { service.Setup(s => s.Connect(null)).Returns(false); configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Mandatory }); - sut.Perform(); + var result = sut.Perform(); - Assert.IsTrue(sut.Abort); + Assert.AreEqual(OperationResult.Failed, result); } [TestMethod] - public void MustNotAbortIfServiceOptionalAndNotAvailable() + public void MustNotFailIfServiceOptionalAndNotAvailable() { service.Setup(s => s.Connect(null)).Returns(false); configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional }); - sut.Perform(); + var result = sut.Perform(); service.VerifySet(s => s.Ignore = true); - Assert.IsFalse(sut.Abort); + + Assert.AreEqual(OperationResult.Success, result); } [TestMethod] diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs index 7d5d4923..f750741d 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs @@ -26,7 +26,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IUserInterfaceFactory uiFactory; private string[] commandLineArgs; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public ConfigurationOperation( @@ -45,7 +44,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations this.uiFactory = uiFactory; } - public void Perform() + public OperationResult Perform() { logger.Info("Initializing application configuration..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration); @@ -60,8 +59,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient) { - Abort = IsConfigurationSufficient(); - logger.Info($"The user chose to {(Abort ? "abort" : "continue")} the application startup after successful client configuration."); + var abort = IsConfigurationSufficient(); + + logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration."); + + if (abort) + { + return OperationResult.Aborted; + } } } else @@ -69,13 +74,17 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations logger.Info("No valid settings file specified nor found in PROGRAMDATA or APPDATA - loading default settings..."); settings = repository.LoadDefaultSettings(); } + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { // TODO: How will the new settings be retrieved? Uri passed to the repository? If yes, how does the Uri get here?! // -> IDEA: Use configuration repository as container? // -> IDEA: Introduce IRepeatParams or alike? + + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/KioskModeOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/KioskModeOperation.cs index 17087503..bf6b515d 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/KioskModeOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/KioskModeOperation.cs @@ -21,7 +21,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IConfigurationRepository configuration; private KioskMode kioskMode; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public KioskModeOperation(ILogger logger, IConfigurationRepository configuration) @@ -30,7 +29,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations this.configuration = configuration; } - public void Perform() + public OperationResult Perform() { kioskMode = configuration.CurrentSettings.KioskMode; @@ -46,11 +45,15 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations DisableExplorerShell(); break; } + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { // TODO: Depends on new kiosk mode! + + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceConnectionOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceConnectionOperation.cs index 84a84ce8..b2ad0b7f 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceConnectionOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceConnectionOperation.cs @@ -25,7 +25,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IServiceProxy service; private IText text; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public ServiceConnectionOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text) @@ -36,7 +35,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations this.text = text; } - public void Perform() + public OperationResult Perform() { logger.Info($"Initializing service connection..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceConnection); @@ -53,19 +52,22 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations if (mandatory && !connected) { - Abort = true; logger.Error("Aborting startup because the service is mandatory but not available!"); + + return OperationResult.Failed; } - else - { - service.Ignore = !connected; - logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}"); - } + + service.Ignore = !connected; + logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}"); + + return OperationResult.Success; } - public void Repeat() + public OperationResult Repeat() { // TODO: Re-check if mandatory, if so, try to connect (if not connected) - otherwise, no action required (except maybe logging of status?) + + return OperationResult.Success; } public void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs index 154f6145..e0d63f2e 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using SafeExamBrowser.Contracts.Behaviour.Operations; using SafeExamBrowser.Contracts.Communication; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Logging; @@ -25,14 +26,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations { } - public override void Perform() + public override OperationResult Perform() { - StartSession(); + return StartSession(); } - public override void Repeat() + public override OperationResult Repeat() { - StartSession(); + return StartSession(); } public override void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs index 86d76471..2c49b169 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs @@ -30,7 +30,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IServiceProxy service; private ISession session; - public bool Abort { get; private set; } public IProgressIndicator ProgressIndicator { private get; set; } public SessionSequenceOperation( @@ -49,11 +48,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations this.service = service; } - public abstract void Perform(); - public abstract void Repeat(); + public abstract OperationResult Perform(); + public abstract OperationResult Repeat(); public abstract void Revert(); - protected void StartSession() + protected OperationResult StartSession() { logger.Info("Starting new session..."); ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartSession, true); @@ -66,19 +65,20 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations sessionRunning = TryStartClient(); - if (sessionRunning) + if (!sessionRunning) { - logger.Info($"Successfully started new session with identifier '{session.Id}'."); - } - else - { - Abort = true; logger.Info($"Failed to start new session! Reverting service session and aborting procedure..."); service.StopSession(session.Id); + + return OperationResult.Failed; } + + logger.Info($"Successfully started new session with identifier '{session.Id}'."); + + return OperationResult.Success; } - protected void StopSession() + protected OperationResult StopSession() { if (sessionRunning) { @@ -96,6 +96,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations sessionRunning = false; logger.Info($"Successfully stopped session with identifier '{session.Id}'."); } + + return OperationResult.Success; } private bool TryStartClient() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs index 1baf2def..811301a2 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using SafeExamBrowser.Contracts.Behaviour.Operations; using SafeExamBrowser.Contracts.Communication; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Logging; @@ -25,14 +26,14 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations { } - public override void Perform() + public override OperationResult Perform() { - // Nothing to do here... + return OperationResult.Success; } - public override void Repeat() + public override OperationResult Repeat() { - StopSession(); + return StopSession(); } public override void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs b/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs index e23a779a..84b3a66c 100644 --- a/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs +++ b/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs @@ -71,7 +71,7 @@ namespace SafeExamBrowser.Runtime.Behaviour splashScreen.Show(); - var initialized = bootstrapSequence.TryPerform(); + var initialized = bootstrapSequence.TryPerform() == OperationResult.Success; if (initialized) { @@ -101,7 +101,6 @@ namespace SafeExamBrowser.Runtime.Behaviour if (sessionRunning) { - DeregisterSessionEvents(); StopSession(); } @@ -141,9 +140,9 @@ namespace SafeExamBrowser.Runtime.Behaviour DeregisterSessionEvents(); } - sessionRunning = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat(); + var result = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat(); - if (sessionRunning) + if (result == OperationResult.Success) { RegisterSessionEvents(); @@ -155,12 +154,17 @@ namespace SafeExamBrowser.Runtime.Behaviour { runtimeWindow.Hide(); } + + sessionRunning = true; } else { - logger.Info(">>>--- Session procedure was aborted! ---<<<"); - // TODO: Not when user chose to terminate after reconfiguration! Probably needs IOperationSequenceResult or alike... - uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error); + logger.Info($">>>--- Session procedure {(result == OperationResult.Aborted ? "was aborted." : "has failed!")} ---<<<"); + + if (result == OperationResult.Failed) + { + uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error); + } if (!initial) { @@ -176,6 +180,8 @@ namespace SafeExamBrowser.Runtime.Behaviour runtimeWindow.ShowProgressBar(); logger.Info(">>>--- Reverting session operations ---<<<"); + DeregisterSessionEvents(); + var success = sessionSequence.TryRevert(); if (success)