diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs index c2b3be65..150f46b8 100644 --- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs @@ -528,6 +528,28 @@ namespace SafeExamBrowser.Client.UnitTests Assert.IsFalse(args.Cancel); } + [TestMethod] + public void Shutdown_MustAbortAskingUserForQuitPassword() + { + var args = new System.ComponentModel.CancelEventArgs(); + var dialog = new Mock(); + var dialogResult = new Mock(); + + settings.QuitPasswordHash = "1234"; + dialog.Setup(d => d.Show(It.IsAny())).Returns(dialogResult.Object); + dialogResult.SetupGet(r => r.Success).Returns(false); + runtimeProxy.Setup(r => r.RequestShutdown()).Returns(new CommunicationResult(true)); + uiFactory.Setup(u => u.CreatePasswordDialog(It.IsAny(), It.IsAny())).Returns(dialog.Object); + + sut.TryStart(); + taskbar.Raise(t => t.QuitButtonClicked += null, args as object); + + uiFactory.Verify(u => u.CreatePasswordDialog(It.IsAny(), It.IsAny()), Times.Once); + runtimeProxy.Verify(p => p.RequestShutdown(), Times.Never); + + Assert.IsTrue(args.Cancel); + } + [TestMethod] public void Shutdown_MustNotInitiateIfQuitPasswordIncorrect() { @@ -640,6 +662,33 @@ namespace SafeExamBrowser.Client.UnitTests taskbar.Verify(t => t.Show(), Times.Never); } + [TestMethod] + public void TerminationActivator_MustCorrectlyInitiateShutdown() + { + var order = 0; + var pause = 0; + var resume = 0; + + messageBox.Setup(m => m.Show( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).Returns(MessageBoxResult.Yes); + runtimeProxy.Setup(r => r.RequestShutdown()).Returns(new CommunicationResult(true)); + terminationActivator.Setup(t => t.Pause()).Callback(() => pause = ++order); + terminationActivator.Setup(t => t.Resume()).Callback(() => resume = ++order); + + sut.TryStart(); + terminationActivator.Raise(t => t.Activated += null); + + Assert.AreEqual(1, pause); + Assert.AreEqual(2, resume); + terminationActivator.Verify(t => t.Pause(), Times.Once); + terminationActivator.Verify(t => t.Resume(), Times.Once); + runtimeProxy.Verify(p => p.RequestShutdown(), Times.Once); + } + [TestMethod] public void WindowMonitor_MustHandleAllowedWindowChangeCorrectly() { diff --git a/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs b/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs index ee0fd333..7ebfbaf1 100644 --- a/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs @@ -51,19 +51,28 @@ namespace SafeExamBrowser.Client.UnitTests.Communication sut.StartupToken = token; - var response = sut.Connect(Guid.Empty); - - Assert.IsNotNull(response); - Assert.IsFalse(response.ConnectionEstablished); - Assert.IsFalse(sut.IsConnected); - - response = sut.Connect(token); + var response = sut.Connect(token); Assert.IsNotNull(response); Assert.IsTrue(response.ConnectionEstablished); Assert.IsTrue(sut.IsConnected); } + + [TestMethod] + public void MustRejectConnectionIfTokenInvalid() + { + var token = Guid.NewGuid(); + + sut.StartupToken = token; + + var response = sut.Connect(Guid.NewGuid()); + + Assert.IsNotNull(response); + Assert.IsFalse(response.ConnectionEstablished); + Assert.IsFalse(sut.IsConnected); + } + [TestMethod] public void MustOnlyAllowOneConcurrentConnection() { diff --git a/SafeExamBrowser.Client.UnitTests/Notifications/AboutNotificationControllerTests.cs b/SafeExamBrowser.Client.UnitTests/Notifications/AboutNotificationControllerTests.cs index 515c8ca9..1ec93949 100644 --- a/SafeExamBrowser.Client.UnitTests/Notifications/AboutNotificationControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Notifications/AboutNotificationControllerTests.cs @@ -73,5 +73,13 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications Assert.IsTrue(button.HasSubscribed); } + + [TestMethod] + public void MustNotFailToTerminateIfNotStarted() + { + var sut = new AboutNotificationController(appConfig.Object, uiFactory.Object); + + sut.Terminate(); + } } } diff --git a/SafeExamBrowser.Client.UnitTests/Notifications/LogNotificationControllerTests.cs b/SafeExamBrowser.Client.UnitTests/Notifications/LogNotificationControllerTests.cs index 55db13aa..89f4608f 100644 --- a/SafeExamBrowser.Client.UnitTests/Notifications/LogNotificationControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Notifications/LogNotificationControllerTests.cs @@ -18,14 +18,14 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications [TestClass] public class LogNotificationControllerTests { - private Mock loggerMock; - private Mock uiFactoryMock; + private Mock logger; + private Mock uiFactory; [TestInitialize] public void Initialize() { - loggerMock = new Mock(); - uiFactoryMock = new Mock(); + logger = new Mock(); + uiFactory = new Mock(); } [TestMethod] @@ -33,9 +33,9 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications { var button = new NotificationButtonMock(); var window = new Mock(); - var sut = new LogNotificationController(loggerMock.Object, uiFactoryMock.Object); + var sut = new LogNotificationController(logger.Object, uiFactory.Object); - uiFactoryMock.Setup(u => u.CreateLogWindow(It.IsAny())).Returns(window.Object); + uiFactory.Setup(u => u.CreateLogWindow(It.IsAny())).Returns(window.Object); sut.RegisterNotification(button); button.Click(); sut.Terminate(); @@ -48,9 +48,9 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications { var button = new NotificationButtonMock(); var window = new Mock(); - var sut = new LogNotificationController(loggerMock.Object, uiFactoryMock.Object); + var sut = new LogNotificationController(logger.Object, uiFactory.Object); - uiFactoryMock.Setup(u => u.CreateLogWindow(It.IsAny())).Returns(window.Object); + uiFactory.Setup(u => u.CreateLogWindow(It.IsAny())).Returns(window.Object); sut.RegisterNotification(button); button.Click(); button.Click(); @@ -58,7 +58,7 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications button.Click(); button.Click(); - uiFactoryMock.Verify(u => u.CreateLogWindow(It.IsAny()), Times.Once); + uiFactory.Verify(u => u.CreateLogWindow(It.IsAny()), Times.Once); window.Verify(u => u.Show(), Times.Once); window.Verify(u => u.BringToForeground(), Times.Exactly(4)); } @@ -67,11 +67,19 @@ namespace SafeExamBrowser.Client.UnitTests.Notifications public void MustSubscribeToClickEvent() { var button = new NotificationButtonMock(); - var sut = new LogNotificationController(loggerMock.Object, uiFactoryMock.Object); + var sut = new LogNotificationController(logger.Object, uiFactory.Object); sut.RegisterNotification(button); Assert.IsTrue(button.HasSubscribed); } + + [TestMethod] + public void MustNotFailToTerminateIfNotStarted() + { + var sut = new LogNotificationController(logger.Object, uiFactory.Object); + + sut.Terminate(); + } } } diff --git a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs index c4eab709..25fdc454 100644 --- a/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs +++ b/SafeExamBrowser.Client.UnitTests/Operations/ShellOperationTests.cs @@ -25,7 +25,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations public class ShellOperationTests { private Mock actionCenter; - private Mock> activators; + private List activators; private ActionCenterSettings actionCenterSettings; private Mock logger; private TaskbarSettings taskbarSettings; @@ -48,7 +48,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations public void Initialize() { actionCenter = new Mock(); - activators = new Mock>(); + activators = new List(); actionCenterSettings = new ActionCenterSettings(); logger = new Mock(); aboutInfo = new Mock(); @@ -65,16 +65,11 @@ namespace SafeExamBrowser.Client.UnitTests.Operations text = new Mock(); uiFactory = new Mock(); - taskbarSettings.ShowApplicationLog = true; - taskbarSettings.ShowKeyboardLayout = true; - taskbarSettings.ShowWirelessNetwork = true; - taskbarSettings.EnableTaskbar = true; - systemInfo.SetupGet(s => s.HasBattery).Returns(true); uiFactory.Setup(u => u.CreateNotificationControl(It.IsAny(), It.IsAny())).Returns(new Mock().Object); sut = new ShellOperation( actionCenter.Object, - activators.Object, + activators, actionCenterSettings, logger.Object, aboutInfo.Object, @@ -93,23 +88,198 @@ namespace SafeExamBrowser.Client.UnitTests.Operations } [TestMethod] - public void MustPerformCorrectly() + public void Perform_MustInitializeActivators() { + var activatorMocks = new List> + { + new Mock(), + new Mock(), + new Mock() + }; + + actionCenterSettings.EnableActionCenter = true; + + foreach (var activator in activatorMocks) + { + activators.Add(activator.Object); + } + + sut.Perform(); + + terminationActivator.Verify(t => t.Start(), Times.Once); + + foreach (var activator in activatorMocks) + { + activator.Verify(a => a.Start(), Times.Once); + } + } + + [TestMethod] + public void Perform_MustInitializeClock() + { + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowClock = true; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowClock = true; + + sut.Perform(); + + actionCenter.VerifySet(a => a.ShowClock = true, Times.Once); + taskbar.VerifySet(t => t.ShowClock = true, Times.Once); + } + + [TestMethod] + public void Perform_MustNotInitializeClock() + { + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowClock = false; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowClock = false; + + sut.Perform(); + + actionCenter.VerifySet(a => a.ShowClock = false, Times.Once); + taskbar.VerifySet(t => t.ShowClock = false, Times.Once); + } + + [TestMethod] + public void Perform_MustInitializeNotifications() + { + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowApplicationLog = true; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowApplicationLog = true; + + sut.Perform(); + + actionCenter.Verify(a => a.AddNotificationControl(It.IsAny()), Times.AtLeast(2)); + taskbar.Verify(t => t.AddNotificationControl(It.IsAny()), Times.AtLeast(2)); + } + + [TestMethod] + public void Perform_MustNotInitializeNotifications() + { + var logControl = new Mock(); + + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowApplicationLog = false; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowApplicationLog = false; + + uiFactory.Setup(f => f.CreateNotificationControl(It.Is(i => i == logInfo.Object), It.IsAny())).Returns(logControl.Object); + + sut.Perform(); + + actionCenter.Verify(a => a.AddNotificationControl(It.Is(i => i == logControl.Object)), Times.Never); + taskbar.Verify(t => t.AddNotificationControl(It.Is(i => i == logControl.Object)), Times.Never); + } + + [TestMethod] + public void Perform_MustInitializeSystemComponents() + { + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowKeyboardLayout = true; + actionCenterSettings.ShowWirelessNetwork = true; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowKeyboardLayout = true; + taskbarSettings.ShowWirelessNetwork = true; + + systemInfo.SetupGet(s => s.HasBattery).Returns(true); + uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny())).Returns(new Mock().Object); + uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny())).Returns(new Mock().Object); + uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny())).Returns(new Mock().Object); + sut.Perform(); keyboardLayout.Verify(k => k.Initialize(), Times.Once); powerSupply.Verify(p => p.Initialize(), Times.Once); wirelessNetwork.Verify(w => w.Initialize(), Times.Once); - taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Exactly(3)); - taskbar.Verify(t => t.AddNotificationControl(It.IsAny()), Times.Exactly(2)); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Once); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Once); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Once); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Once); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Once); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Once); } [TestMethod] - public void MustRevertCorrectly() + public void Perform_MustNotInitializeSystemComponents() + { + actionCenterSettings.EnableActionCenter = true; + actionCenterSettings.ShowKeyboardLayout = false; + actionCenterSettings.ShowWirelessNetwork = false; + taskbarSettings.EnableTaskbar = true; + taskbarSettings.ShowKeyboardLayout = false; + taskbarSettings.ShowWirelessNetwork = false; + + systemInfo.SetupGet(s => s.HasBattery).Returns(false); + uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny())).Returns(new Mock().Object); + uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny())).Returns(new Mock().Object); + uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny())).Returns(new Mock().Object); + + sut.Perform(); + + keyboardLayout.Verify(k => k.Initialize(), Times.Once); + powerSupply.Verify(p => p.Initialize(), Times.Once); + wirelessNetwork.Verify(w => w.Initialize(), Times.Once); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Never); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Never); + actionCenter.Verify(a => a.AddSystemControl(It.IsAny()), Times.Never); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Never); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Never); + taskbar.Verify(t => t.AddSystemControl(It.IsAny()), Times.Never); + } + + [TestMethod] + public void Perform_MustNotInitializeActionCenterIfNotEnabled() + { + actionCenterSettings.EnableActionCenter = false; + sut.Perform(); + actionCenter.VerifyNoOtherCalls(); + } + + [TestMethod] + public void Perform_MustNotInitializeTaskbarIfNotEnabled() + { + taskbarSettings.EnableTaskbar = false; + sut.Perform(); + taskbar.VerifyNoOtherCalls(); + } + + [TestMethod] + public void Revert_MustTerminateActivators() + { + var activatorMocks = new List> + { + new Mock(), + new Mock(), + new Mock() + }; + + actionCenterSettings.EnableActionCenter = true; + + foreach (var activator in activatorMocks) + { + activators.Add(activator.Object); + } + + sut.Revert(); + + terminationActivator.Verify(t => t.Stop(), Times.Once); + + foreach (var activator in activatorMocks) + { + activator.Verify(a => a.Stop(), Times.Once); + } + } + + [TestMethod] + public void Revert_MustTerminateControllers() { sut.Revert(); aboutController.Verify(c => c.Terminate(), Times.Once); + logController.Verify(c => c.Terminate(), Times.Once); keyboardLayout.Verify(k => k.Terminate(), Times.Once); powerSupply.Verify(p => p.Terminate(), Times.Once); wirelessNetwork.Verify(w => w.Terminate(), Times.Once); diff --git a/SafeExamBrowser.Client/Operations/ShellOperation.cs b/SafeExamBrowser.Client/Operations/ShellOperation.cs index 8fa11e35..d6bb506a 100644 --- a/SafeExamBrowser.Client/Operations/ShellOperation.cs +++ b/SafeExamBrowser.Client/Operations/ShellOperation.cs @@ -109,6 +109,15 @@ namespace SafeExamBrowser.Client.Operations private void InitializeActivators() { terminationActivator.Start(); + + if (actionCenterSettings.EnableActionCenter) + { + foreach (var activator in activators) + { + actionCenter.Register(activator); + activator.Start(); + } + } } private void InitializeActionCenter() @@ -124,12 +133,6 @@ namespace SafeExamBrowser.Client.Operations InitializeKeyboardLayoutForActionCenter(); InitializeWirelessNetworkForActionCenter(); InitializePowerSupplyForActionCenter(); - - foreach (var activator in activators) - { - actionCenter.Register(activator); - activator.Start(); - } } else { diff --git a/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs b/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs index 6e6b83f8..34fc0b4b 100644 --- a/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs +++ b/SafeExamBrowser.Configuration.UnitTests/SubStreamTests.cs @@ -95,15 +95,16 @@ namespace SafeExamBrowser.Configuration.UnitTests { var sut = new SubStream(stream.Object, 100, 200); - stream.SetupGet(s => s.Position).Returns(-100); + sut.Position = -100; Assert.AreEqual(-1, sut.ReadByte()); - stream.SetupGet(s => s.Position).Returns(200); + sut.Position = 200; Assert.AreEqual(-1, sut.ReadByte()); - stream.SetupGet(s => s.Position).Returns(25); + sut.Position = 25; sut.ReadByte(); - stream.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), Times.AtLeastOnce); + + stream.Verify(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] diff --git a/SafeExamBrowser.Logging.UnitTests/LoggerTests.cs b/SafeExamBrowser.Logging.UnitTests/LoggerTests.cs index 587b4bb2..31e7583f 100644 --- a/SafeExamBrowser.Logging.UnitTests/LoggerTests.cs +++ b/SafeExamBrowser.Logging.UnitTests/LoggerTests.cs @@ -178,6 +178,43 @@ namespace SafeExamBrowser.Logging.UnitTests Assert.IsTrue(message.Equals((messages[1] as ILogMessage).Message)); } + [TestMethod] + public void MustRespectLogLevel() + { + var sut = new Logger(); + + sut.LogLevel = LogLevel.Error; + sut.Debug("debug"); + sut.Info("info"); + sut.Warn("warn"); + + Assert.AreEqual(0, sut.GetLog().Count); + + sut = new Logger(); + sut.LogLevel = LogLevel.Warning; + sut.Debug("debug"); + sut.Info("info"); + sut.Warn("warn"); + + Assert.AreEqual(1, sut.GetLog().Count); + + sut = new Logger(); + sut.LogLevel = LogLevel.Info; + sut.Debug("debug"); + sut.Info("info"); + sut.Warn("warn"); + + Assert.AreEqual(2, sut.GetLog().Count); + + sut = new Logger(); + sut.LogLevel = LogLevel.Debug; + sut.Debug("debug"); + sut.Info("info"); + sut.Warn("warn"); + + Assert.AreEqual(3, sut.GetLog().Count); + } + [TestMethod] public void MustUnsubscribeObserver() { diff --git a/SafeExamBrowser.Logging.UnitTests/ModuleLoggerTests.cs b/SafeExamBrowser.Logging.UnitTests/ModuleLoggerTests.cs index 83e5449c..0fa669ee 100644 --- a/SafeExamBrowser.Logging.UnitTests/ModuleLoggerTests.cs +++ b/SafeExamBrowser.Logging.UnitTests/ModuleLoggerTests.cs @@ -39,6 +39,9 @@ namespace SafeExamBrowser.Logging.UnitTests var logText = new LogText("Log text"); var sut = new ModuleLogger(loggerMock.Object, nameof(ModuleLoggerTests)); + loggerMock.SetupGet(l => l.LogLevel).Returns(LogLevel.Error); + + sut.LogLevel = LogLevel.Debug; sut.Debug("Debug"); sut.Info("Info"); sut.Warn("Warning"); @@ -49,6 +52,7 @@ namespace SafeExamBrowser.Logging.UnitTests sut.Unsubscribe(logObserverMock.Object); sut.GetLog(); + loggerMock.VerifySet(l => l.LogLevel = LogLevel.Debug, Times.Once); loggerMock.Verify(l => l.Debug($"[{nameof(ModuleLoggerTests)}] Debug"), Times.Once); loggerMock.Verify(l => l.Info($"[{nameof(ModuleLoggerTests)}] Info"), Times.Once); loggerMock.Verify(l => l.Warn($"[{nameof(ModuleLoggerTests)}] Warning"), Times.Once); @@ -58,6 +62,8 @@ namespace SafeExamBrowser.Logging.UnitTests loggerMock.Verify(l => l.Subscribe(logObserverMock.Object), Times.Once); loggerMock.Verify(l => l.Unsubscribe(logObserverMock.Object), Times.Once); loggerMock.Verify(l => l.GetLog(), Times.Once); + + Assert.AreEqual(LogLevel.Error, sut.LogLevel); } } } diff --git a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs index 9b0f95fd..392f4fa3 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs @@ -56,6 +56,20 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication Assert.IsTrue(response.ConnectionEstablished); } + [TestMethod] + public void MustRejectConnectionIfTokenInvalid() + { + var token = Guid.NewGuid(); + + sut.AllowConnection = true; + sut.StartupToken = token; + + var response = sut.Connect(Guid.NewGuid()); + + Assert.IsNotNull(response); + Assert.IsFalse(response.ConnectionEstablished); + } + [TestMethod] public void MustOnlyAllowOneConcurrentConnection() {