From 9014a6e6be5cce16b28510226749a81c096e9733 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Thu, 28 Jun 2018 13:40:30 +0200 Subject: [PATCH] SEBWIN-220: Completed basic set of unit tests for ConfigurationOperation. --- .../ResourceLoader.cs | 22 ++ .../SafeExamBrowser.Configuration.csproj | 1 + .../Configuration/IResourceLoader.cs | 23 ++ .../SafeExamBrowser.Contracts.csproj | 1 + .../Operations/ConfigurationOperationTests.cs | 273 +++++++++++++++--- .../Operations/ConfigurationOperation.cs | 16 +- SafeExamBrowser.Runtime/CompositionRoot.cs | 3 +- 7 files changed, 289 insertions(+), 50 deletions(-) create mode 100644 SafeExamBrowser.Configuration/ResourceLoader.cs create mode 100644 SafeExamBrowser.Contracts/Configuration/IResourceLoader.cs diff --git a/SafeExamBrowser.Configuration/ResourceLoader.cs b/SafeExamBrowser.Configuration/ResourceLoader.cs new file mode 100644 index 00000000..f6b353d7 --- /dev/null +++ b/SafeExamBrowser.Configuration/ResourceLoader.cs @@ -0,0 +1,22 @@ +/* + * 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/. + */ + +using System; +using SafeExamBrowser.Contracts.Configuration; + +namespace SafeExamBrowser.Configuration +{ + public class ResourceLoader : IResourceLoader + { + public bool IsHtmlResource(Uri resource) + { + // TODO + return false; + } + } +} diff --git a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj index 877e2d13..53eef41a 100644 --- a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj +++ b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj @@ -52,6 +52,7 @@ + diff --git a/SafeExamBrowser.Contracts/Configuration/IResourceLoader.cs b/SafeExamBrowser.Contracts/Configuration/IResourceLoader.cs new file mode 100644 index 00000000..6f4352eb --- /dev/null +++ b/SafeExamBrowser.Contracts/Configuration/IResourceLoader.cs @@ -0,0 +1,23 @@ +/* + * 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/. + */ + +using System; + +namespace SafeExamBrowser.Contracts.Configuration +{ + /// + /// Loads configuration data from various sources (e.g. the internet) and provides related resource handling functionality. + /// + public interface IResourceLoader + { + /// + /// Indicates whether the given identifies a HTML resource. + /// + bool IsHtmlResource(Uri resource); + } +} diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj index ca417339..9957f64b 100644 --- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj +++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj @@ -94,6 +94,7 @@ + diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs index 6083e357..07da2c95 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs @@ -11,7 +11,10 @@ using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using SafeExamBrowser.Contracts.Behaviour.OperationModel; +using SafeExamBrowser.Contracts.Communication.Data; +using SafeExamBrowser.Contracts.Communication.Events; using SafeExamBrowser.Contracts.Communication.Hosts; +using SafeExamBrowser.Contracts.Communication.Proxies; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; @@ -26,12 +29,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations [TestClass] public class ConfigurationOperationTests { - private RuntimeInfo info; private Mock logger; private Mock messageBox; private Mock passwordDialog; private Mock repository; + private Mock resourceLoader; private Mock runtimeHost; + private RuntimeInfo runtimeInfo; private Settings settings; private Mock text; private Mock uiFactory; @@ -40,19 +44,22 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations [TestInitialize] public void Initialize() { - info = new RuntimeInfo(); logger = new Mock(); messageBox = new Mock(); passwordDialog = new Mock(); repository = new Mock(); + resourceLoader = new Mock(); runtimeHost = new Mock(); + runtimeInfo = new RuntimeInfo(); settings = new Settings(); text = new Mock(); uiFactory = new Mock(); - info.AppDataFolder = @"C:\Not\Really\AppData"; - info.DefaultSettingsFileName = "SettingsDummy.txt"; - info.ProgramDataFolder = @"C:\Not\Really\ProgramData"; + repository.SetupGet(r => r.CurrentSettings).Returns(settings); + + runtimeInfo.AppDataFolder = @"C:\Not\Really\AppData"; + runtimeInfo.DefaultSettingsFileName = "SettingsDummy.txt"; + runtimeInfo.ProgramDataFolder = @"C:\Not\Really\ProgramData"; uiFactory.Setup(f => f.CreatePasswordDialog(It.IsAny(), It.IsAny())).Returns(passwordDialog.Object); } @@ -63,13 +70,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations var url = @"http://www.safeexambrowser.org/whatever.seb"; var location = Path.GetDirectoryName(GetType().Assembly.Location); - info.ProgramDataFolder = location; - info.AppDataFolder = location; + runtimeInfo.ProgramDataFolder = location; + runtimeInfo.AppDataFolder = location; - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); sut.Perform(); var resource = new Uri(url); @@ -82,13 +88,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations { var location = Path.GetDirectoryName(GetType().Assembly.Location); - info.ProgramDataFolder = location; - info.AppDataFolder = $@"{location}\WRONG"; + runtimeInfo.ProgramDataFolder = location; + runtimeInfo.AppDataFolder = $@"{location}\WRONG"; - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); sut.Perform(); var resource = new Uri(Path.Combine(location, "SettingsDummy.txt")); @@ -101,12 +106,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations { var location = Path.GetDirectoryName(GetType().Assembly.Location); - info.AppDataFolder = location; + runtimeInfo.AppDataFolder = location; - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); sut.Perform(); var resource = new Uri(Path.Combine(location, "SettingsDummy.txt")); @@ -117,7 +121,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations [TestMethod] public void MustFallbackToDefaultsAsLastPrio() { - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); sut.Perform(); repository.Verify(r => r.LoadDefaultSettings(), Times.Once); @@ -126,12 +130,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations [TestMethod] public void MustAbortIfWishedByUser() { - info.ProgramDataFolder = Path.GetDirectoryName(GetType().Assembly.Location); + runtimeInfo.ProgramDataFolder = Path.GetDirectoryName(GetType().Assembly.Location); messageBox.Setup(m => m.Show(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.Yes); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); var result = sut.Perform(); @@ -142,10 +145,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations public void MustNotAbortIfNotWishedByUser() { messageBox.Setup(m => m.Show(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.No); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); var result = sut.Perform(); @@ -156,10 +158,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations public void MustNotAllowToAbortIfNotInConfigureClientMode() { settings.ConfigurationMode = ConfigurationMode.Exam; - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); sut.Perform(); messageBox.Verify(m => m.Show(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); @@ -170,10 +171,10 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations { repository.Setup(r => r.LoadDefaultSettings()); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, null); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); sut.Perform(); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new string[] { }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new string[] { }); sut.Perform(); repository.Verify(r => r.LoadDefaultSettings(), Times.Exactly(2)); @@ -184,7 +185,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations { var uri = @"an/invalid\uri.'*%yolo/()你好"; - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", uri }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", uri }); sut.Perform(); } @@ -195,10 +196,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations var url = @"http://www.safeexambrowser.org/whatever.seb"; passwordDialog.Setup(d => d.Show(null)).Returns(result); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.AdminPasswordNeeded); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); sut.Perform(); repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Exactly(5)); @@ -211,10 +211,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations var url = @"http://www.safeexambrowser.org/whatever.seb"; passwordDialog.Setup(d => d.Show(null)).Returns(result); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); sut.Perform(); repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Exactly(5)); @@ -228,15 +227,14 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations var url = @"http://www.safeexambrowser.org/whatever.seb"; passwordDialog.Setup(d => d.Show(null)).Returns(result); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.AdminPasswordNeeded); repository.Setup(r => r.LoadSettings(It.IsAny(), password, null)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); sut.Perform(); - repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Exactly(1)); - repository.Verify(r => r.LoadSettings(It.IsAny(), password, null), Times.Exactly(1)); + repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Once); + repository.Verify(r => r.LoadSettings(It.IsAny(), password, null), Times.Once); } [TestMethod] @@ -247,15 +245,212 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations var url = @"http://www.safeexambrowser.org/whatever.seb"; passwordDialog.Setup(d => d.Show(null)).Returns(result); - repository.SetupGet(r => r.CurrentSettings).Returns(settings); repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); repository.Setup(r => r.LoadSettings(It.IsAny(), null, password)).Returns(LoadStatus.Success); - sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, runtimeHost.Object, info, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); sut.Perform(); - repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Exactly(1)); - repository.Verify(r => r.LoadSettings(It.IsAny(), null, password), Times.Exactly(1)); + repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Once); + repository.Verify(r => r.LoadSettings(It.IsAny(), null, password), Times.Once); + } + + [TestMethod] + public void MustAbortAskingForAdminPasswordIfDecidedByUser() + { + var dialogResult = new PasswordDialogResultStub { Success = false }; + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + passwordDialog.Setup(d => d.Show(null)).Returns(dialogResult); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.AdminPasswordNeeded); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + + var result = sut.Perform(); + + Assert.AreEqual(OperationResult.Aborted, result); + } + + [TestMethod] + public void MustAbortAskingForSettingsPasswordIfDecidedByUser() + { + var dialogResult = new PasswordDialogResultStub { Success = false }; + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + passwordDialog.Setup(d => d.Show(null)).Returns(dialogResult); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + + var result = sut.Perform(); + + Assert.AreEqual(OperationResult.Aborted, result); + } + + [TestMethod] + public void MustAllowEnteringBothPasswords() + { + var adminPassword = "xyz"; + var adminResult = new PasswordDialogResultStub { Password = adminPassword, Success = true }; + var adminCallback = new Action(() => passwordDialog.Setup(d => d.Show(null)).Returns(adminResult)); + var settingsPassword = "abc"; + var settingsResult = new PasswordDialogResultStub { Password = settingsPassword, Success = true }; + var settingsCallback = new Action(() => passwordDialog.Setup(d => d.Show(null)).Returns(settingsResult)); + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded).Callback(settingsCallback); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, settingsPassword)).Returns(LoadStatus.AdminPasswordNeeded).Callback(adminCallback); + repository.Setup(r => r.LoadSettings(It.IsAny(), adminPassword, settingsPassword)).Returns(LoadStatus.Success); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut.Perform(); + + repository.Verify(r => r.LoadSettings(It.IsAny(), null, null), Times.Once); + repository.Verify(r => r.LoadSettings(It.IsAny(), null, settingsPassword), Times.Once); + repository.Verify(r => r.LoadSettings(It.IsAny(), adminPassword, settingsPassword), Times.Once); + } + + [TestMethod] + public void MustRequestPasswordViaDialogOnDefaultDesktop() + { + var clientProxy = new Mock(); + var session = new Mock(); + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + passwordDialog.Setup(d => d.Show(null)).Returns(new PasswordDialogResultStub { Success = true }); + repository.SetupGet(r => r.CurrentSession).Returns(session.Object); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); + session.SetupGet(r => r.ClientProxy).Returns(clientProxy.Object); + settings.KioskMode = KioskMode.DisableExplorerShell; + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut.Perform(); + + clientProxy.Verify(c => c.RequestPassword(It.IsAny(), It.IsAny()), Times.Never); + passwordDialog.Verify(p => p.Show(null), Times.AtLeastOnce); + session.VerifyGet(s => s.ClientProxy, Times.Never); + } + + [TestMethod] + public void MustRequestPasswordViaClientDuringReconfigurationOnNewDesktop() + { + var clientProxy = new Mock(); + var passwordReceived = new Action((p, id) => + { + runtimeHost.Raise(r => r.PasswordReceived += null, new PasswordEventArgs { RequestId = id }); + }); + var session = new Mock(); + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Callback(passwordReceived); + passwordDialog.Setup(d => d.Show(null)).Returns(new PasswordDialogResultStub { Success = true }); + repository.SetupGet(r => r.CurrentSession).Returns(session.Object); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); + session.SetupGet(r => r.ClientProxy).Returns(clientProxy.Object); + settings.KioskMode = KioskMode.CreateNewDesktop; + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + sut.Perform(); + + clientProxy.Verify(c => c.RequestPassword(It.IsAny(), It.IsAny()), Times.AtLeastOnce); + passwordDialog.Verify(p => p.Show(null), Times.Never); + session.VerifyGet(s => s.ClientProxy, Times.AtLeastOnce); + } + + [TestMethod] + public void MustAbortAskingForPasswordViaClientIfDecidedByUser() + { + var clientProxy = new Mock(); + var passwordReceived = new Action((p, id) => + { + runtimeHost.Raise(r => r.PasswordReceived += null, new PasswordEventArgs { RequestId = id, Success = false }); + }); + var session = new Mock(); + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Callback(passwordReceived); + passwordDialog.Setup(d => d.Show(null)).Returns(new PasswordDialogResultStub { Success = true }); + repository.SetupGet(r => r.CurrentSession).Returns(session.Object); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded); + session.SetupGet(r => r.ClientProxy).Returns(clientProxy.Object); + settings.KioskMode = KioskMode.CreateNewDesktop; + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + + var result = sut.Perform(); + + Assert.AreEqual(OperationResult.Aborted, result); + } + + [TestMethod] + public void MustHandleInvalidData() + { + var url = @"http://www.safeexambrowser.org/whatever.seb"; + + resourceLoader.Setup(r => r.IsHtmlResource(It.IsAny())).Returns(false); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.InvalidData); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + + var result = sut.Perform(); + + Assert.AreEqual(OperationResult.Failed, result); + } + + [TestMethod] + public void MustHandleHtmlAsInvalidData() + { + var url = "http://www.blubb.org/some/resource.html"; + + resourceLoader.Setup(r => r.IsHtmlResource(It.IsAny())).Returns(true); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.InvalidData); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, new[] { "blubb.exe", url }); + + var result = sut.Perform(); + + Assert.AreEqual(OperationResult.Success, result); + Assert.AreEqual(url, settings.Browser.StartUrl); + } + + [TestMethod] + public void MustReconfigureSuccessfullyWithCorrectUri() + { + var location = Path.GetDirectoryName(GetType().Assembly.Location); + var resource = new Uri(Path.Combine(location, "SettingsDummy.txt")); + + repository.SetupGet(r => r.ReconfigurationFilePath).Returns(resource.AbsolutePath); + repository.Setup(r => r.LoadSettings(It.Is(u => u.Equals(resource)), null, null)).Returns(LoadStatus.Success); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); + + var result = sut.Repeat(); + + repository.Verify(r => r.LoadSettings(It.Is(u => u.Equals(resource)), null, null), Times.Once); + + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void MustFailToReconfigureWithInvalidUri() + { + var resource = new Uri("file:///C:/does/not/exist.txt"); + + repository.SetupGet(r => r.ReconfigurationFilePath).Returns(null as string); + repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.Success); + + sut = new ConfigurationOperation(repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, runtimeInfo, text.Object, uiFactory.Object, null); + + var result = sut.Repeat(); + + repository.Verify(r => r.LoadSettings(It.Is(u => u.Equals(resource)), null, null), Times.Never); + Assert.AreEqual(OperationResult.Failed, result); + + repository.SetupGet(r => r.ReconfigurationFilePath).Returns(resource.AbsolutePath); + result = sut.Repeat(); + + repository.Verify(r => r.LoadSettings(It.Is(u => u.Equals(resource)), null, null), Times.Never); + Assert.AreEqual(OperationResult.Failed, result); } } } diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs index a5caf563..1c4c5dec 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs @@ -27,6 +27,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IConfigurationRepository repository; private ILogger logger; private IMessageBox messageBox; + private IResourceLoader resourceLoader; private IRuntimeHost runtimeHost; private RuntimeInfo runtimeInfo; private IText text; @@ -39,6 +40,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations IConfigurationRepository repository, ILogger logger, IMessageBox messageBox, + IResourceLoader resourceLoader, IRuntimeHost runtimeHost, RuntimeInfo runtimeInfo, IText text, @@ -48,11 +50,12 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations this.repository = repository; this.logger = logger; this.messageBox = messageBox; - this.commandLineArgs = commandLineArgs; + this.resourceLoader = resourceLoader; this.runtimeHost = runtimeHost; this.runtimeInfo = runtimeInfo; this.text = text; this.uiFactory = uiFactory; + this.commandLineArgs = commandLineArgs; } public OperationResult Perform() @@ -215,11 +218,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private void HandleInvalidData(ref LoadStatus status, Uri uri) { - if (IsHtmlPage(uri)) + if (resourceLoader.IsHtmlResource(uri)) { repository.LoadDefaultSettings(); repository.CurrentSettings.Browser.StartUrl = uri.AbsoluteUri; - logger.Info($"The specified URI '{uri.AbsoluteUri}' appears to point to a HTML page, setting it as startup URL."); + logger.Info($"The specified URI '{uri.AbsoluteUri}' appears to point to a HTML resource, setting it as startup URL."); status = LoadStatus.Success; } @@ -229,13 +232,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations } } - private bool IsHtmlPage(Uri uri) - { - // TODO - - return false; - } - private bool TryInitializeSettingsUri(out Uri uri) { var path = string.Empty; diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs index e4e4b9d6..735174ed 100644 --- a/SafeExamBrowser.Runtime/CompositionRoot.cs +++ b/SafeExamBrowser.Runtime/CompositionRoot.cs @@ -54,6 +54,7 @@ namespace SafeExamBrowser.Runtime var desktop = new Desktop(new ModuleLogger(logger, typeof(Desktop))); var processFactory = new ProcessFactory(desktop, new ModuleLogger(logger, typeof(ProcessFactory))); var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger); + var resourceLoader = new ResourceLoader(); var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, typeof(RuntimeHost))); var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, typeof(ServiceProxy))); @@ -63,7 +64,7 @@ namespace SafeExamBrowser.Runtime bootstrapOperations.Enqueue(new I18nOperation(logger, text)); bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger)); - sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, messageBox, runtimeHost, runtimeInfo, text, uiFactory, args)); + sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, messageBox, resourceLoader, runtimeHost, runtimeInfo, text, uiFactory, args)); sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost)); sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text)); sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, TEN_SECONDS));