Implemented unit tests for startup- and shutdown-controller.
This commit is contained in:
		
							parent
							
								
									1153fea091
								
							
						
					
					
						commit
						e7b8404254
					
				
					 13 changed files with 339 additions and 53 deletions
				
			
		| 
						 | 
					@ -15,6 +15,6 @@ namespace SafeExamBrowser.Contracts.Behaviour
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Reverts any changes performed during the startup or runtime and releases all used resources.
 | 
							/// Reverts any changes performed during the startup or runtime and releases all used resources.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void FinalizeApplication(Stack<IOperation> operations);
 | 
							void FinalizeApplication(Queue<IOperation> operations);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,10 +13,9 @@ namespace SafeExamBrowser.Contracts.Behaviour
 | 
				
			||||||
	public interface IStartupController
 | 
						public interface IStartupController
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Tries to initialize the application. Returns <c>true</c> if the initialization was successful,
 | 
							/// Tries to initialize the application according to the given queue of operations.
 | 
				
			||||||
		/// <c>false</c> otherwise. All operations performed during the startup procedure will be registered
 | 
							/// Returns <c>true</c> if the initialization was successful, <c>false</c> otherwise.
 | 
				
			||||||
		/// to the given <c>out</c> parameter.
 | 
					 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		bool TryInitializeApplication(out Stack<IOperation> operations);
 | 
							bool TryInitializeApplication(Queue<IOperation> operations);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,115 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2017 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/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
				
			||||||
 | 
					using Moq;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Monitoring;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Core.Behaviour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Core.UnitTests.Behaviour
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						[TestClass]
 | 
				
			||||||
 | 
						public class ShutdownControllerTests
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private Mock<IApplicationController> browserControllerMock;
 | 
				
			||||||
 | 
							private Mock<IApplicationInfo> browserInfoMock;
 | 
				
			||||||
 | 
							private Mock<ILogger> loggerMock;
 | 
				
			||||||
 | 
							private Mock<IMessageBox> messageBoxMock;
 | 
				
			||||||
 | 
							private Mock<INotificationInfo> aboutInfoMock;
 | 
				
			||||||
 | 
							private Mock<IProcessMonitor> processMonitorMock;
 | 
				
			||||||
 | 
							private Mock<ISettings> settingsMock;
 | 
				
			||||||
 | 
							private Mock<ITaskbar> taskbarMock;
 | 
				
			||||||
 | 
							private Mock<IText> textMock;
 | 
				
			||||||
 | 
							private Mock<IUiElementFactory> uiFactoryMock;
 | 
				
			||||||
 | 
							private Mock<IWorkingArea> workingAreaMock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private IShutdownController sut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestInitialize]
 | 
				
			||||||
 | 
							public void Initialize()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								browserControllerMock = new Mock<IApplicationController>();
 | 
				
			||||||
 | 
								browserInfoMock = new Mock<IApplicationInfo>();
 | 
				
			||||||
 | 
								loggerMock = new Mock<ILogger>();
 | 
				
			||||||
 | 
								messageBoxMock = new Mock<IMessageBox>();
 | 
				
			||||||
 | 
								aboutInfoMock = new Mock<INotificationInfo>();
 | 
				
			||||||
 | 
								processMonitorMock = new Mock<IProcessMonitor>();
 | 
				
			||||||
 | 
								settingsMock = new Mock<ISettings>();
 | 
				
			||||||
 | 
								taskbarMock = new Mock<ITaskbar>();
 | 
				
			||||||
 | 
								textMock = new Mock<IText>();
 | 
				
			||||||
 | 
								uiFactoryMock = new Mock<IUiElementFactory>();
 | 
				
			||||||
 | 
								workingAreaMock = new Mock<IWorkingArea>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								uiFactoryMock.Setup(f => f.CreateSplashScreen(settingsMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut = new ShutdownController(
 | 
				
			||||||
 | 
									loggerMock.Object,
 | 
				
			||||||
 | 
									messageBoxMock.Object,
 | 
				
			||||||
 | 
									processMonitorMock.Object,
 | 
				
			||||||
 | 
									settingsMock.Object,
 | 
				
			||||||
 | 
									textMock.Object,
 | 
				
			||||||
 | 
									uiFactoryMock.Object,
 | 
				
			||||||
 | 
									workingAreaMock.Object);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustRevertOperations()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.FinalizeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
								operationB.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
								operationC.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustRevertOperationsInSequence()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								int current = 0, a = 0, b = 0, c = 0;
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
 | 
				
			||||||
 | 
								operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
 | 
				
			||||||
 | 
								operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.FinalizeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsTrue(a == 1);
 | 
				
			||||||
 | 
								Assert.IsTrue(b == 2);
 | 
				
			||||||
 | 
								Assert.IsTrue(c == 3);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustNotFailWithEmptyQueue()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sut.FinalizeApplication(new Queue<IOperation>());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,183 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2017 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/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
				
			||||||
 | 
					using Moq;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Monitoring;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Core.Behaviour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Core.UnitTests.Behaviour
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						[TestClass]
 | 
				
			||||||
 | 
						public class StartupControllerTests
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private Mock<IApplicationController> browserControllerMock;
 | 
				
			||||||
 | 
							private Mock<IApplicationInfo> browserInfoMock;
 | 
				
			||||||
 | 
							private Mock<ILogger> loggerMock;
 | 
				
			||||||
 | 
							private Mock<IMessageBox> messageBoxMock;
 | 
				
			||||||
 | 
							private Mock<INotificationInfo> aboutInfoMock;
 | 
				
			||||||
 | 
							private Mock<IProcessMonitor> processMonitorMock;
 | 
				
			||||||
 | 
							private Mock<ISettings> settingsMock;
 | 
				
			||||||
 | 
							private Mock<ITaskbar> taskbarMock;
 | 
				
			||||||
 | 
							private Mock<IText> textMock;
 | 
				
			||||||
 | 
							private Mock<IUiElementFactory> uiFactoryMock;
 | 
				
			||||||
 | 
							private Mock<IWorkingArea> workingAreaMock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private IStartupController sut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestInitialize]
 | 
				
			||||||
 | 
							public void Initialize()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								browserControllerMock = new Mock<IApplicationController>();
 | 
				
			||||||
 | 
								browserInfoMock = new Mock<IApplicationInfo>();
 | 
				
			||||||
 | 
								loggerMock = new Mock<ILogger>();
 | 
				
			||||||
 | 
								messageBoxMock = new Mock<IMessageBox>();
 | 
				
			||||||
 | 
								aboutInfoMock = new Mock<INotificationInfo>();
 | 
				
			||||||
 | 
								processMonitorMock = new Mock<IProcessMonitor>();
 | 
				
			||||||
 | 
								settingsMock = new Mock<ISettings>();
 | 
				
			||||||
 | 
								taskbarMock = new Mock<ITaskbar>();
 | 
				
			||||||
 | 
								textMock = new Mock<IText>();
 | 
				
			||||||
 | 
								uiFactoryMock = new Mock<IUiElementFactory>();
 | 
				
			||||||
 | 
								workingAreaMock = new Mock<IWorkingArea>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								uiFactoryMock.Setup(f => f.CreateSplashScreen(settingsMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut = new StartupController(
 | 
				
			||||||
 | 
									browserControllerMock.Object,
 | 
				
			||||||
 | 
									browserInfoMock.Object,
 | 
				
			||||||
 | 
									loggerMock.Object,
 | 
				
			||||||
 | 
									messageBoxMock.Object,
 | 
				
			||||||
 | 
									aboutInfoMock.Object,
 | 
				
			||||||
 | 
									processMonitorMock.Object,
 | 
				
			||||||
 | 
									settingsMock.Object,
 | 
				
			||||||
 | 
									taskbarMock.Object,
 | 
				
			||||||
 | 
									textMock.Object,
 | 
				
			||||||
 | 
									uiFactoryMock.Object,
 | 
				
			||||||
 | 
									workingAreaMock.Object);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustPerformOperations()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var result = sut.TryInitializeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationB.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationC.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsTrue(result);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustPerformOperationsInSequence()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								int current = 0, a = 0, b = 0, c = 0;
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Setup(o => o.Perform()).Callback(() => a = ++current);
 | 
				
			||||||
 | 
								operationB.Setup(o => o.Perform()).Callback(() => b = ++current);
 | 
				
			||||||
 | 
								operationC.Setup(o => o.Perform()).Callback(() => c = ++current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.TryInitializeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsTrue(a == 1);
 | 
				
			||||||
 | 
								Assert.IsTrue(b == 2);
 | 
				
			||||||
 | 
								Assert.IsTrue(c == 3);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustRevertOperationsInCaseOfError()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationD = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationC.Setup(o => o.Perform()).Throws<Exception>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationD.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var result = sut.TryInitializeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationA.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
								operationB.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationB.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
								operationC.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationC.Verify(o => o.Revert(), Times.Once);
 | 
				
			||||||
 | 
								operationD.Verify(o => o.Perform(), Times.Never);
 | 
				
			||||||
 | 
								operationD.Verify(o => o.Revert(), Times.Never);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsFalse(result);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustRevertOperationsInSequence()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								int current = 0, a = 0, b = 0, c = 0, d = 0;
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationD = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
 | 
				
			||||||
 | 
								operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
 | 
				
			||||||
 | 
								operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
 | 
				
			||||||
 | 
								operationC.Setup(o => o.Perform()).Throws<Exception>();
 | 
				
			||||||
 | 
								operationD.Setup(o => o.Revert()).Callback(() => d = ++current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationD.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.TryInitializeApplication(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsTrue(d == 0);
 | 
				
			||||||
 | 
								Assert.IsTrue(c == 1);
 | 
				
			||||||
 | 
								Assert.IsTrue(b == 2);
 | 
				
			||||||
 | 
								Assert.IsTrue(a == 3);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustSucceedWithEmptyQueue()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var result = sut.TryInitializeApplication(new Queue<IOperation>());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.IsTrue(result);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,8 @@
 | 
				
			||||||
    <Reference Include="System.Core" />
 | 
					    <Reference Include="System.Core" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Include="Behaviour\StartupControllerTests.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Behaviour\ShutdownControllerTests.cs" />
 | 
				
			||||||
    <Compile Include="I18n\TextTests.cs" />
 | 
					    <Compile Include="I18n\TextTests.cs" />
 | 
				
			||||||
    <Compile Include="Logging\LoggerTests.cs" />
 | 
					    <Compile Include="Logging\LoggerTests.cs" />
 | 
				
			||||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
					    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
					namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	class BrowserInitializationOperation : IOperation
 | 
						public class BrowserInitializationOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private IApplicationController browserController;
 | 
							private IApplicationController browserController;
 | 
				
			||||||
		private IApplicationInfo browserInfo;
 | 
							private IApplicationInfo browserInfo;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
					namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	class ProcessMonitoringOperation : IOperation
 | 
						public class ProcessMonitoringOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IProcessMonitor processMonitor;
 | 
							private IProcessMonitor processMonitor;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
					namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	class TaskbarInitializationOperation : IOperation
 | 
						public class TaskbarInitializationOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private ITaskbar taskbar;
 | 
							private ITaskbar taskbar;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
					namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	class WorkingAreaOperation : IOperation
 | 
						public class WorkingAreaOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IProcessMonitor processMonitor;
 | 
							private IProcessMonitor processMonitor;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour;
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration;
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
| 
						 | 
					@ -48,7 +47,7 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			this.workingArea = workingArea;
 | 
								this.workingArea = workingArea;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void FinalizeApplication(Stack<IOperation> operations)
 | 
							public void FinalizeApplication(Queue<IOperation> operations)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			try
 | 
								try
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -63,17 +62,13 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void RevertOperations(Stack<IOperation> operations)
 | 
							private void RevertOperations(Queue<IOperation> operations)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			while (operations.Any())
 | 
								foreach (var operation in operations)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				var operation = operations.Pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				operation.SplashScreen = splashScreen;
 | 
									operation.SplashScreen = splashScreen;
 | 
				
			||||||
				operation.Revert();
 | 
									operation.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				splashScreen.Progress();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// TODO: Remove!
 | 
									// TODO: Remove!
 | 
				
			||||||
				Thread.Sleep(250);
 | 
									Thread.Sleep(250);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,6 @@ using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Monitoring;
 | 
					using SafeExamBrowser.Contracts.Monitoring;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
using SafeExamBrowser.Core.Behaviour.Operations;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Core.Behaviour
 | 
					namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -35,7 +34,7 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
		private IUiElementFactory uiFactory;
 | 
							private IUiElementFactory uiFactory;
 | 
				
			||||||
		private IWorkingArea workingArea;
 | 
							private IWorkingArea workingArea;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private IEnumerable<IOperation> startupOperations;
 | 
							private Stack<IOperation> stack = new Stack<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public StartupController(
 | 
							public StartupController(
 | 
				
			||||||
			IApplicationController browserController,
 | 
								IApplicationController browserController,
 | 
				
			||||||
| 
						 | 
					@ -63,18 +62,14 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			this.workingArea = workingArea;
 | 
								this.workingArea = workingArea;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool TryInitializeApplication(out Stack<IOperation> operations)
 | 
							public bool TryInitializeApplication(Queue<IOperation> operations)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			operations = new Stack<IOperation>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			try
 | 
								try
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				CreateStartupOperations();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				InitializeApplicationLog();
 | 
									InitializeApplicationLog();
 | 
				
			||||||
				InitializeSplashScreen();
 | 
									InitializeSplashScreen(operations.Count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				operations = PerformOperations();
 | 
									PerformOperations(operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				FinishInitialization();
 | 
									FinishInitialization();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,20 +78,18 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			catch (Exception e)
 | 
								catch (Exception e)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				LogAndShowException(e);
 | 
									LogAndShowException(e);
 | 
				
			||||||
				RevertOperations(operations);
 | 
									RevertOperations();
 | 
				
			||||||
				FinishInitialization(false);
 | 
									FinishInitialization(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private Stack<IOperation> PerformOperations()
 | 
							private void PerformOperations(Queue<IOperation> operations)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var operations = new Stack<IOperation>();
 | 
								foreach (var operation in operations)
 | 
				
			||||||
 | 
					 | 
				
			||||||
			foreach (var operation in startupOperations)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				operations.Push(operation);
 | 
									stack.Push(operation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				operation.SplashScreen = splashScreen;
 | 
									operation.SplashScreen = splashScreen;
 | 
				
			||||||
				operation.Perform();
 | 
									operation.Perform();
 | 
				
			||||||
| 
						 | 
					@ -106,15 +99,13 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
				// TODO: Remove!
 | 
									// TODO: Remove!
 | 
				
			||||||
				Thread.Sleep(250);
 | 
									Thread.Sleep(250);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			return operations;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void RevertOperations(Stack<IOperation> operations)
 | 
							private void RevertOperations()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			while (operations.Any())
 | 
								while (stack.Any())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				var operation = operations.Pop();
 | 
									var operation = stack.Pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				operation.Revert();
 | 
									operation.Revert();
 | 
				
			||||||
				splashScreen.Regress();
 | 
									splashScreen.Regress();
 | 
				
			||||||
| 
						 | 
					@ -124,17 +115,6 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void CreateStartupOperations()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			startupOperations = new IOperation[]
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				new ProcessMonitoringOperation(logger, processMonitor),
 | 
					 | 
				
			||||||
				new WorkingAreaOperation(logger, processMonitor, taskbar, workingArea),
 | 
					 | 
				
			||||||
				new TaskbarInitializationOperation(logger, aboutInfo, taskbar, uiFactory),
 | 
					 | 
				
			||||||
				new BrowserInitializationOperation(browserController, browserInfo, logger, taskbar, uiFactory)
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		private void InitializeApplicationLog()
 | 
							private void InitializeApplicationLog()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var titleLine = $"/* {settings.ProgramTitle}, Version {settings.ProgramVersion}{Environment.NewLine}";
 | 
								var titleLine = $"/* {settings.ProgramTitle}, Version {settings.ProgramVersion}{Environment.NewLine}";
 | 
				
			||||||
| 
						 | 
					@ -147,10 +127,10 @@ namespace SafeExamBrowser.Core.Behaviour
 | 
				
			||||||
			logger.Info("--- Initiating startup procedure ---");
 | 
								logger.Info("--- Initiating startup procedure ---");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void InitializeSplashScreen()
 | 
							private void InitializeSplashScreen(int operationCount)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			splashScreen = uiFactory.CreateSplashScreen(settings, text);
 | 
								splashScreen = uiFactory.CreateSplashScreen(settings, text);
 | 
				
			||||||
			splashScreen.SetMaxProgress(startupOperations.Count());
 | 
								splashScreen.SetMaxProgress(operationCount);
 | 
				
			||||||
			splashScreen.UpdateText(Key.SplashScreen_StartupProcedure);
 | 
								splashScreen.UpdateText(Key.SplashScreen_StartupProcedure);
 | 
				
			||||||
			splashScreen.InvokeShow();
 | 
								splashScreen.InvokeShow();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour;
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
| 
						 | 
					@ -59,12 +60,12 @@ namespace SafeExamBrowser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			instances.BuildObjectGraph();
 | 
								instances.BuildObjectGraph();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var success = instances.StartupController.TryInitializeApplication(out Stack<IOperation> operations);
 | 
								var success = instances.StartupController.TryInitializeApplication(instances.StartupOperations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (success)
 | 
								if (success)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				MainWindow = instances.Taskbar;
 | 
									MainWindow = instances.Taskbar;
 | 
				
			||||||
				MainWindow.Closing += (o, args) => ShutdownApplication(operations);
 | 
									MainWindow.Closing += (o, args) => ShutdownApplication();
 | 
				
			||||||
				MainWindow.Show();
 | 
									MainWindow.Show();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
| 
						 | 
					@ -73,8 +74,10 @@ namespace SafeExamBrowser
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void ShutdownApplication(Stack<IOperation> operations)
 | 
							private void ShutdownApplication()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>(instances.StartupOperations.Reverse());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			MainWindow.Hide();
 | 
								MainWindow.Hide();
 | 
				
			||||||
			instances.ShutdownController.FinalizeApplication(operations);
 | 
								instances.ShutdownController.FinalizeApplication(operations);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
					 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using SafeExamBrowser.Browser;
 | 
					using SafeExamBrowser.Browser;
 | 
				
			||||||
using SafeExamBrowser.Configuration;
 | 
					using SafeExamBrowser.Configuration;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour;
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
| 
						 | 
					@ -15,6 +16,7 @@ using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Monitoring;
 | 
					using SafeExamBrowser.Contracts.Monitoring;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
using SafeExamBrowser.Core.Behaviour;
 | 
					using SafeExamBrowser.Core.Behaviour;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Core.Behaviour.Operations;
 | 
				
			||||||
using SafeExamBrowser.Core.I18n;
 | 
					using SafeExamBrowser.Core.I18n;
 | 
				
			||||||
using SafeExamBrowser.Core.Logging;
 | 
					using SafeExamBrowser.Core.Logging;
 | 
				
			||||||
using SafeExamBrowser.Monitoring.Processes;
 | 
					using SafeExamBrowser.Monitoring.Processes;
 | 
				
			||||||
| 
						 | 
					@ -38,6 +40,7 @@ namespace SafeExamBrowser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public IShutdownController ShutdownController { get; private set; }
 | 
							public IShutdownController ShutdownController { get; private set; }
 | 
				
			||||||
		public IStartupController StartupController { get; private set; }
 | 
							public IStartupController StartupController { get; private set; }
 | 
				
			||||||
 | 
							public Queue<IOperation> StartupOperations { get; private set; }
 | 
				
			||||||
		public Taskbar Taskbar { get; private set; }
 | 
							public Taskbar Taskbar { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void BuildObjectGraph()
 | 
							public void BuildObjectGraph()
 | 
				
			||||||
| 
						 | 
					@ -59,6 +62,12 @@ namespace SafeExamBrowser
 | 
				
			||||||
			workingArea = new WorkingArea(new ModuleLogger(logger, typeof(WorkingArea)));
 | 
								workingArea = new WorkingArea(new ModuleLogger(logger, typeof(WorkingArea)));
 | 
				
			||||||
			ShutdownController = new ShutdownController(logger, messageBox, processMonitor, settings, text, uiFactory, workingArea);
 | 
								ShutdownController = new ShutdownController(logger, messageBox, processMonitor, settings, text, uiFactory, workingArea);
 | 
				
			||||||
			StartupController = new StartupController(browserController, browserInfo, logger, messageBox, aboutInfo, processMonitor, settings, Taskbar, text, uiFactory, workingArea);
 | 
								StartupController = new StartupController(browserController, browserInfo, logger, messageBox, aboutInfo, processMonitor, settings, Taskbar, text, uiFactory, workingArea);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								StartupOperations = new Queue<IOperation>();
 | 
				
			||||||
 | 
								StartupOperations.Enqueue(new ProcessMonitoringOperation(logger, processMonitor));
 | 
				
			||||||
 | 
								StartupOperations.Enqueue(new WorkingAreaOperation(logger, processMonitor, Taskbar, workingArea));
 | 
				
			||||||
 | 
								StartupOperations.Enqueue(new TaskbarInitializationOperation(logger, aboutInfo, Taskbar, uiFactory));
 | 
				
			||||||
 | 
								StartupOperations.Enqueue(new BrowserInitializationOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue