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));