Restore SEBPatch
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Communication.Contracts;
|
||||
using SafeExamBrowser.Communication.Contracts.Data;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ClientOperationTests
|
||||
{
|
||||
private Action clientReady;
|
||||
private Action terminated;
|
||||
private AppConfig appConfig;
|
||||
private Mock<IClientProxy> proxy;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IProcess> process;
|
||||
private Mock<IProcessFactory> processFactory;
|
||||
private Mock<IProxyFactory> proxyFactory;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
private AppSettings settings;
|
||||
private ClientOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new AppConfig();
|
||||
clientReady = new Action(() => runtimeHost.Raise(h => h.ClientReady += null));
|
||||
logger = new Mock<ILogger>();
|
||||
process = new Mock<IProcess>();
|
||||
processFactory = new Mock<IProcessFactory>();
|
||||
proxy = new Mock<IClientProxy>();
|
||||
proxyFactory = new Mock<IProxyFactory>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
settings = new AppSettings();
|
||||
terminated = new Action(() =>
|
||||
{
|
||||
runtimeHost.Raise(h => h.ClientDisconnected += null);
|
||||
process.Raise(p => p.Terminated += null, 0);
|
||||
});
|
||||
|
||||
appConfig.ClientLogFilePath = "";
|
||||
session.AppConfig = appConfig;
|
||||
session.Settings = settings;
|
||||
sessionContext.Current = session;
|
||||
sessionContext.Next = session;
|
||||
proxyFactory.Setup(f => f.CreateClientProxy(It.IsAny<string>(), It.IsAny<Interlocutor>())).Returns(proxy.Object);
|
||||
|
||||
sut = new ClientOperation(logger.Object, processFactory.Object, proxyFactory.Object, runtimeHost.Object, sessionContext, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustStartClient()
|
||||
{
|
||||
var result = default(OperationResult);
|
||||
var response = new AuthenticationResponse { ProcessId = 1234 };
|
||||
var communication = new CommunicationResult<AuthenticationResponse>(true, response);
|
||||
|
||||
process.SetupGet(p => p.Id).Returns(response.ProcessId);
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(clientReady);
|
||||
proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>(), true)).Returns(true);
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(process.Object, sessionContext.ClientProcess);
|
||||
Assert.AreEqual(proxy.Object, sessionContext.ClientProxy);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailStartupImmediatelyIfClientTerminates()
|
||||
{
|
||||
const int ONE_SECOND = 1000;
|
||||
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
var result = default(OperationResult);
|
||||
var terminateClient = new Action(() => Task.Delay(100).ContinueWith(_ => process.Raise(p => p.Terminated += null, 0)));
|
||||
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(terminateClient);
|
||||
sut = new ClientOperation(logger.Object, processFactory.Object, proxyFactory.Object, runtimeHost.Object, sessionContext, ONE_SECOND);
|
||||
|
||||
before = DateTime.Now;
|
||||
result = sut.Perform();
|
||||
after = DateTime.Now;
|
||||
|
||||
Assert.IsTrue(after - before < new TimeSpan(0, 0, ONE_SECOND));
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailStartupIfConnectionToClientNotEstablished()
|
||||
{
|
||||
var result = default(OperationResult);
|
||||
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(clientReady);
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>(), true)).Returns(false);
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
Assert.IsNotNull(sessionContext.ClientProcess);
|
||||
Assert.IsNotNull(sessionContext.ClientProxy);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailStartupIfAuthenticationNotSuccessful()
|
||||
{
|
||||
var result = default(OperationResult);
|
||||
var response = new AuthenticationResponse { ProcessId = -1 };
|
||||
var communication = new CommunicationResult<AuthenticationResponse>(true, response);
|
||||
|
||||
process.SetupGet(p => p.Id).Returns(1234);
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(clientReady);
|
||||
proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>(), true)).Returns(true);
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
Assert.IsNotNull(sessionContext.ClientProcess);
|
||||
Assert.IsNotNull(sessionContext.ClientProxy);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustStartClient()
|
||||
{
|
||||
var result = default(OperationResult);
|
||||
var response = new AuthenticationResponse { ProcessId = 1234 };
|
||||
var communication = new CommunicationResult<AuthenticationResponse>(true, response);
|
||||
|
||||
process.SetupGet(p => p.Id).Returns(response.ProcessId);
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(clientReady);
|
||||
proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>(), true)).Returns(true);
|
||||
|
||||
result = sut.Repeat();
|
||||
|
||||
Assert.AreEqual(process.Object, sessionContext.ClientProcess);
|
||||
Assert.AreEqual(proxy.Object, sessionContext.ClientProxy);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustStopClient()
|
||||
{
|
||||
proxy.Setup(p => p.Disconnect()).Callback(terminated);
|
||||
|
||||
PerformNormally();
|
||||
sut.Revert();
|
||||
|
||||
proxy.Verify(p => p.InitiateShutdown(), Times.Once);
|
||||
proxy.Verify(p => p.Disconnect(), Times.Once);
|
||||
process.Verify(p => p.TryKill(It.IsAny<int>()), Times.Never);
|
||||
|
||||
Assert.IsNull(sessionContext.ClientProcess);
|
||||
Assert.IsNull(sessionContext.ClientProxy);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustKillClientIfStoppingFailed()
|
||||
{
|
||||
process.Setup(p => p.TryKill(It.IsAny<int>())).Callback(() => process.SetupGet(p => p.HasTerminated).Returns(true));
|
||||
|
||||
PerformNormally();
|
||||
sut.Revert();
|
||||
|
||||
process.Verify(p => p.TryKill(It.IsAny<int>()), Times.AtLeastOnce);
|
||||
|
||||
Assert.IsNull(sessionContext.ClientProcess);
|
||||
Assert.IsNull(sessionContext.ClientProxy);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustAttemptToKillFiveTimesThenAbort()
|
||||
{
|
||||
PerformNormally();
|
||||
sut.Revert();
|
||||
|
||||
process.Verify(p => p.TryKill(It.IsAny<int>()), Times.Exactly(5));
|
||||
|
||||
Assert.IsNotNull(sessionContext.ClientProcess);
|
||||
Assert.IsNotNull(sessionContext.ClientProxy);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotStopClientIfAlreadyTerminated()
|
||||
{
|
||||
process.SetupGet(p => p.HasTerminated).Returns(true);
|
||||
|
||||
sut.Revert();
|
||||
|
||||
proxy.Verify(p => p.InitiateShutdown(), Times.Never);
|
||||
proxy.Verify(p => p.Disconnect(), Times.Never);
|
||||
process.Verify(p => p.TryKill(It.IsAny<int>()), Times.Never);
|
||||
|
||||
Assert.IsNull(sessionContext.ClientProcess);
|
||||
Assert.IsNull(sessionContext.ClientProxy);
|
||||
}
|
||||
|
||||
private void PerformNormally()
|
||||
{
|
||||
var response = new AuthenticationResponse { ProcessId = 1234 };
|
||||
var communication = new CommunicationResult<AuthenticationResponse>(true, response);
|
||||
|
||||
process.SetupGet(p => p.Id).Returns(response.ProcessId);
|
||||
processFactory.Setup(f => f.StartNew(It.IsAny<string>(), It.IsAny<string[]>())).Returns(process.Object).Callback(clientReady);
|
||||
proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
|
||||
proxy.Setup(p => p.Connect(It.IsAny<Guid>(), true)).Returns(true);
|
||||
|
||||
sut.Perform();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Communication.Contracts;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ClientTerminationOperationTests
|
||||
{
|
||||
private Action clientReady;
|
||||
private Action terminated;
|
||||
private AppConfig appConfig;
|
||||
private Mock<IClientProxy> proxy;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IProcess> process;
|
||||
private Mock<IProcessFactory> processFactory;
|
||||
private Mock<IProxyFactory> proxyFactory;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private ClientTerminationOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new AppConfig();
|
||||
clientReady = new Action(() => runtimeHost.Raise(h => h.ClientReady += null));
|
||||
logger = new Mock<ILogger>();
|
||||
process = new Mock<IProcess>();
|
||||
processFactory = new Mock<IProcessFactory>();
|
||||
proxy = new Mock<IClientProxy>();
|
||||
proxyFactory = new Mock<IProxyFactory>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
terminated = new Action(() =>
|
||||
{
|
||||
runtimeHost.Raise(h => h.ClientDisconnected += null);
|
||||
process.Raise(p => p.Terminated += null, 0);
|
||||
});
|
||||
|
||||
session.AppConfig = appConfig;
|
||||
sessionContext.ClientProcess = process.Object;
|
||||
sessionContext.ClientProxy = proxy.Object;
|
||||
sessionContext.Current = session;
|
||||
sessionContext.Next = session;
|
||||
proxyFactory.Setup(f => f.CreateClientProxy(It.IsAny<string>(), It.IsAny<Interlocutor>())).Returns(proxy.Object);
|
||||
|
||||
sut = new ClientTerminationOperation(logger.Object, processFactory.Object, proxyFactory.Object, runtimeHost.Object, sessionContext, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustTerminateClientOnRepeat()
|
||||
{
|
||||
var terminated = new Action(() =>
|
||||
{
|
||||
runtimeHost.Raise(h => h.ClientDisconnected += null);
|
||||
process.Raise(p => p.Terminated += null, 0);
|
||||
});
|
||||
|
||||
proxy.Setup(p => p.Disconnect()).Callback(terminated);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
proxy.Verify(p => p.InitiateShutdown(), Times.Once);
|
||||
proxy.Verify(p => p.Disconnect(), Times.Once);
|
||||
process.Verify(p => p.TryKill(default(int)), Times.Never);
|
||||
|
||||
Assert.IsNull(sessionContext.ClientProcess);
|
||||
Assert.IsNull(sessionContext.ClientProxy);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnRepeatIfNoClientRunning()
|
||||
{
|
||||
process.SetupGet(p => p.HasTerminated).Returns(true);
|
||||
sessionContext.ClientProcess = process.Object;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
process.VerifyGet(p => p.HasTerminated, Times.Once);
|
||||
|
||||
process.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
proxy.VerifyNoOtherCalls();
|
||||
proxyFactory.VerifyNoOtherCalls();
|
||||
runtimeHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnPerform()
|
||||
{
|
||||
var result = sut.Perform();
|
||||
|
||||
process.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
proxy.VerifyNoOtherCalls();
|
||||
proxyFactory.VerifyNoOtherCalls();
|
||||
runtimeHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnRevert()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
process.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
proxy.VerifyNoOtherCalls();
|
||||
proxyFactory.VerifyNoOtherCalls();
|
||||
runtimeHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,647 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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.IO;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Communication.Contracts.Data;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ConfigurationOperationTests
|
||||
{
|
||||
private const string FILE_NAME = "SebClientSettings.seb";
|
||||
|
||||
private AppConfig appConfig;
|
||||
private Mock<IFileSystem> fileSystem;
|
||||
private Mock<IHashAlgorithm> hashAlgorithm;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IConfigurationRepository> repository;
|
||||
private SessionConfiguration currentSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new AppConfig();
|
||||
fileSystem = new Mock<IFileSystem>();
|
||||
hashAlgorithm = new Mock<IHashAlgorithm>();
|
||||
logger = new Mock<ILogger>();
|
||||
repository = new Mock<IConfigurationRepository>();
|
||||
currentSession = new SessionConfiguration();
|
||||
nextSession = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
appConfig.AppDataFilePath = $@"C:\Not\Really\AppData\File.xml";
|
||||
appConfig.ProgramDataFilePath = $@"C:\Not\Really\ProgramData\File.xml";
|
||||
currentSession.AppConfig = appConfig;
|
||||
nextSession.AppConfig = appConfig;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustUseCommandLineArgumentAs1stPrio()
|
||||
{
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
var location = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
|
||||
appConfig.AppDataFilePath = location;
|
||||
appConfig.ProgramDataFilePath = location;
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
var resource = new Uri(url);
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustUseProgramDataAs2ndPrio()
|
||||
{
|
||||
var location = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
var settings = default(AppSettings);
|
||||
|
||||
appConfig.ProgramDataFilePath = location;
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(location)), out settings, It.IsAny<PasswordParameters>()), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustUseAppDataAs3rdPrio()
|
||||
{
|
||||
var location = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
var settings = default(AppSettings);
|
||||
|
||||
appConfig.AppDataFilePath = location;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(location)), out settings, It.IsAny<PasswordParameters>()), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyHandleBrowserResource()
|
||||
{
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
nextSession.Settings = settings;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.LoadWithBrowser);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.IsFalse(settings.Browser.DeleteCacheOnShutdown);
|
||||
Assert.IsFalse(settings.Browser.DeleteCookiesOnShutdown);
|
||||
Assert.IsTrue(settings.Security.AllowReconfiguration);
|
||||
Assert.AreEqual(url, settings.Browser.StartUrl);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFallbackToDefaultsAsLastPrio()
|
||||
{
|
||||
var defaultSettings = new AppSettings();
|
||||
|
||||
repository.Setup(r => r.LoadDefaultSettings()).Returns(defaultSettings);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfWishedByUser()
|
||||
{
|
||||
var settings = new AppSettings();
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
sessionContext.Current = null;
|
||||
settings.ConfigurationMode = ConfigurationMode.ConfigureClient;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is ConfigurationCompletedEventArgs c)
|
||||
{
|
||||
c.AbortStartup = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotAbortIfNotWishedByUser()
|
||||
{
|
||||
var settings = new AppSettings();
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
settings.ConfigurationMode = ConfigurationMode.ConfigureClient;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is ConfigurationCompletedEventArgs c)
|
||||
{
|
||||
c.AbortStartup = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInformAboutClientConfigurationError()
|
||||
{
|
||||
var informed = false;
|
||||
var settings = new AppSettings();
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
settings.ConfigurationMode = ConfigurationMode.ConfigureClient;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.UnexpectedError);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is ClientConfigurationErrorMessageArgs)
|
||||
{
|
||||
informed = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(informed);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotAllowToAbortIfNotInConfigureClientMode()
|
||||
{
|
||||
var settings = new AppSettings();
|
||||
|
||||
settings.ConfigurationMode = ConfigurationMode.Exam;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is ConfigurationCompletedEventArgs c)
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotFailWithoutCommandLineArgs()
|
||||
{
|
||||
var defaultSettings = new AppSettings();
|
||||
var result = OperationResult.Failed;
|
||||
|
||||
repository.Setup(r => r.LoadDefaultSettings()).Returns(defaultSettings);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
|
||||
sut = new ConfigurationOperation(new string[] { }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Exactly(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotFailWithInvalidUri()
|
||||
{
|
||||
var uri = @"an/invalid\uri.'*%yolo/()你好";
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", uri }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustOnlyAllowToEnterAdminPasswordFiveTimes()
|
||||
{
|
||||
var count = 0;
|
||||
var localSettings = new AppSettings();
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
appConfig.AppDataFilePath = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
localSettings.Security.AdminPasswordHash = "1234";
|
||||
settings.Security.AdminPasswordHash = "9876";
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.LocalPath.Contains(FILE_NAME)), out localSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
nextSession.Settings = settings;
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p && p.Purpose == PasswordRequestPurpose.LocalAdministrator)
|
||||
{
|
||||
count++;
|
||||
p.Success = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(5, count);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustOnlyAllowToEnterSettingsPasswordFiveTimes()
|
||||
{
|
||||
var count = 0;
|
||||
var settings = default(AppSettings);
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.PasswordNeeded);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p && p.Purpose == PasswordRequestPurpose.Settings)
|
||||
{
|
||||
count++;
|
||||
p.Success = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>()), Times.Exactly(6));
|
||||
|
||||
Assert.AreEqual(5, count);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfAdminPasswordCorrect()
|
||||
{
|
||||
var password = "test";
|
||||
var currentSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var nextSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
currentSettings.Security.AdminPasswordHash = "1234";
|
||||
nextSession.Settings = nextSettings;
|
||||
nextSettings.Security.AdminPasswordHash = "9876";
|
||||
hashAlgorithm.Setup(h => h.GenerateHashFor(It.Is<string>(p => p == password))).Returns(currentSettings.Security.AdminPasswordHash);
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.AbsoluteUri == url), out nextSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p && p.Purpose == PasswordRequestPurpose.LocalAdministrator)
|
||||
{
|
||||
p.Password = password;
|
||||
p.Success = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotAuthenticateIfSameAdminPassword()
|
||||
{
|
||||
var currentSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var nextSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
currentSettings.Security.AdminPasswordHash = "1234";
|
||||
nextSession.Settings = nextSettings;
|
||||
nextSettings.Security.AdminPasswordHash = "1234";
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.AbsoluteUri == url), out nextSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs)
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
hashAlgorithm.Verify(h => h.GenerateHashFor(It.IsAny<string>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfSettingsPasswordCorrect()
|
||||
{
|
||||
var password = "test";
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.PasswordNeeded);
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.Is<PasswordParameters>(p => p.Password == password))).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p)
|
||||
{
|
||||
p.Password = password;
|
||||
p.Success = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.Is<PasswordParameters>(p => p.Password == password)), Times.AtLeastOnce);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustUseCurrentPasswordIfAvailable()
|
||||
{
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
var location = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
|
||||
appConfig.AppDataFilePath = location;
|
||||
settings.Security.AdminPasswordHash = "1234";
|
||||
|
||||
repository
|
||||
.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>()))
|
||||
.Returns(LoadStatus.PasswordNeeded);
|
||||
repository
|
||||
.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(new Uri(location))), out settings, It.IsAny<PasswordParameters>()))
|
||||
.Returns(LoadStatus.Success);
|
||||
repository
|
||||
.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.Is<PasswordParameters>(p => p.IsHash == true && p.Password == settings.Security.AdminPasswordHash)))
|
||||
.Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.Is<PasswordParameters>(p => p.Password == settings.Security.AdminPasswordHash)), Times.AtLeastOnce);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortAskingForAdminPasswordIfDecidedByUser()
|
||||
{
|
||||
var password = "test";
|
||||
var currentSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var nextSettings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
appConfig.AppDataFilePath = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
currentSettings.Security.AdminPasswordHash = "1234";
|
||||
nextSession.Settings = nextSettings;
|
||||
nextSettings.Security.AdminPasswordHash = "9876";
|
||||
|
||||
hashAlgorithm.Setup(h => h.GenerateHashFor(It.Is<string>(p => p == password))).Returns(currentSettings.Security.AdminPasswordHash);
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.AbsoluteUri == url), out nextSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p && p.Purpose == PasswordRequestPurpose.LocalAdministrator)
|
||||
{
|
||||
p.Success = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortAskingForSettingsPasswordIfDecidedByUser()
|
||||
{
|
||||
var settings = default(AppSettings);
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.PasswordNeeded);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p)
|
||||
{
|
||||
p.Success = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustPerformForExamWithCorrectUri()
|
||||
{
|
||||
var currentSettings = new AppSettings();
|
||||
var location = Path.GetDirectoryName(GetType().Assembly.Location);
|
||||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Once);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.AtLeastOnce);
|
||||
repository.Verify(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustPerformForClientConfigurationWithCorrectUri()
|
||||
{
|
||||
var currentSettings = new AppSettings();
|
||||
var location = Path.GetDirectoryName(GetType().Assembly.Location);
|
||||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Once);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.AtLeastOnce);
|
||||
repository.Verify(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustDeleteTemporaryFileAfterClientConfiguration()
|
||||
{
|
||||
var currentSettings = new AppSettings();
|
||||
var location = Path.GetDirectoryName(GetType().Assembly.Location);
|
||||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var delete = 0;
|
||||
var configure = 0;
|
||||
var order = 0;
|
||||
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
fileSystem.Setup(f => f.Delete(It.IsAny<string>())).Callback(() => delete = ++order);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success).Callback(() => configure = ++order);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Once);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.AtLeastOnce);
|
||||
repository.Verify(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, configure);
|
||||
Assert.AreEqual(2, delete);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustFailWithInvalidUri()
|
||||
{
|
||||
var resource = new Uri("file:///C:/does/not/exist.txt");
|
||||
var settings = default(AppSettings);
|
||||
|
||||
sessionContext.ReconfigurationFilePath = null;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Never);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.Never);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Never);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.Never);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAbortForSettingsPasswordIfWishedByUser()
|
||||
{
|
||||
var currentSettings = new AppSettings();
|
||||
var location = Path.GetDirectoryName(GetType().Assembly.Location);
|
||||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new AppSettings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.PasswordNeeded);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
{
|
||||
if (args is PasswordRequiredEventArgs p)
|
||||
{
|
||||
p.Success = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.Is<string>(s => s == resource.LocalPath)), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var sut = new ConfigurationOperation(null, repository.Object, fileSystem.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Revert();
|
||||
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
hashAlgorithm.VerifyNoOtherCalls();
|
||||
repository.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class DisclaimerOperationTests
|
||||
{
|
||||
private Mock<ILogger> logger;
|
||||
private AppSettings settings;
|
||||
private SessionContext context;
|
||||
|
||||
private DisclaimerOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new SessionContext();
|
||||
logger = new Mock<ILogger>();
|
||||
settings = new AppSettings();
|
||||
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.Settings = settings;
|
||||
sut = new DisclaimerOperation(logger.Object, context);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustShowDisclaimerWhenProctoringEnabled()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
settings.Proctoring.ScreenProctoring.Enabled = true;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
count++;
|
||||
m.Result = MessageBoxResult.Ok;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(1, count);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfDisclaimerNotConfirmed()
|
||||
{
|
||||
var disclaimerShown = false;
|
||||
|
||||
settings.Proctoring.ScreenProctoring.Enabled = true;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
disclaimerShown = true;
|
||||
m.Result = MessageBoxResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
Assert.IsTrue(disclaimerShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDoNothingIfProctoringNotEnabled()
|
||||
{
|
||||
var disclaimerShown = false;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
disclaimerShown = true;
|
||||
m.Result = MessageBoxResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.IsFalse(disclaimerShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustShowDisclaimerWhenProctoringEnabled()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
settings.Proctoring.ScreenProctoring.Enabled = true;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
count++;
|
||||
m.Result = MessageBoxResult.Ok;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(1, count);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAbortIfDisclaimerNotConfirmed()
|
||||
{
|
||||
var disclaimerShown = false;
|
||||
|
||||
settings.Proctoring.ScreenProctoring.Enabled = true;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
disclaimerShown = true;
|
||||
m.Result = MessageBoxResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
Assert.IsTrue(disclaimerShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustDoNothingIfProctoringNotEnabled()
|
||||
{
|
||||
var disclaimerShown = false;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
disclaimerShown = true;
|
||||
m.Result = MessageBoxResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
Assert.IsFalse(disclaimerShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var disclaimerShown = false;
|
||||
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs m)
|
||||
{
|
||||
disclaimerShown = true;
|
||||
m.Result = MessageBoxResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
Assert.IsFalse(disclaimerShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Display;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Monitoring;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class DisplayMonitorOperationTests
|
||||
{
|
||||
private SessionContext context;
|
||||
private Mock<IDisplayMonitor> displayMonitor;
|
||||
private Mock<ILogger> logger;
|
||||
private AppSettings settings;
|
||||
private Mock<IText> text;
|
||||
|
||||
private DisplayMonitorOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new SessionContext();
|
||||
displayMonitor = new Mock<IDisplayMonitor>();
|
||||
logger = new Mock<ILogger>();
|
||||
settings = new AppSettings();
|
||||
text = new Mock<IText>();
|
||||
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.Settings = settings;
|
||||
sut = new DisplayMonitorOperation(displayMonitor.Object, logger.Object, context, text.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfDisplayConfigurationAllowed()
|
||||
{
|
||||
displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>())).Returns(new ValidationResult { IsAllowed = true });
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>()), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfDisplayConfigurationNotAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>())).Returns(new ValidationResult { IsAllowed = false });
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>()), Times.Once);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfDisplayConfigurationAllowed()
|
||||
{
|
||||
displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>())).Returns(new ValidationResult { IsAllowed = true });
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>()), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustFailIfDisplayConfigurationNotAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>())).Returns(new ValidationResult { IsAllowed = false });
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny<DisplaySettings>()), Times.Once);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
displayMonitor.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class KioskModeOperationTests
|
||||
{
|
||||
private SessionConfiguration currentSession;
|
||||
private AppSettings currentSettings;
|
||||
private Mock<IDesktopFactory> desktopFactory;
|
||||
private Mock<IDesktopMonitor> desktopMonitor;
|
||||
private Mock<IExplorerShell> explorerShell;
|
||||
private Mock<ILogger> logger;
|
||||
private SessionConfiguration nextSession;
|
||||
private AppSettings nextSettings;
|
||||
private Mock<IProcessFactory> processFactory;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private KioskModeOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
currentSession = new SessionConfiguration();
|
||||
currentSettings = new AppSettings();
|
||||
desktopFactory = new Mock<IDesktopFactory>();
|
||||
desktopMonitor = new Mock<IDesktopMonitor>();
|
||||
explorerShell = new Mock<IExplorerShell>();
|
||||
logger = new Mock<ILogger>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new AppSettings();
|
||||
processFactory = new Mock<IProcessFactory>();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
currentSession.Settings = currentSettings;
|
||||
nextSession.Settings = nextSettings;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
sut = new KioskModeOperation(desktopFactory.Object, desktopMonitor.Object, explorerShell.Object, logger.Object, processFactory.Object, sessionContext);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeCreateNewDesktop()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var getCurrrent = 0;
|
||||
var createNew = 0;
|
||||
var activate = 0;
|
||||
var setStartup = 0;
|
||||
var startMonitor = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Callback(() => getCurrrent = ++order).Returns(originalDesktop.Object);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Callback(() => createNew = ++order).Returns(randomDesktop.Object);
|
||||
randomDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.IsAny<IDesktop>()).Callback(() => setStartup = ++order);
|
||||
desktopMonitor.Setup(m => m.Start(It.IsAny<IDesktop>())).Callback(() => startMonitor = ++order);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
|
||||
desktopFactory.Verify(f => f.CreateRandom(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = randomDesktop.Object, Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
Assert.AreEqual(1, getCurrrent);
|
||||
Assert.AreEqual(2, createNew);
|
||||
Assert.AreEqual(3, activate);
|
||||
Assert.AreEqual(4, setStartup);
|
||||
Assert.AreEqual(5, startMonitor);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeDisableExplorerShell()
|
||||
{
|
||||
var order = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
explorerShell.Setup(s => s.HideAllWindows()).Callback(() => Assert.AreEqual(1, ++order));
|
||||
explorerShell.Setup(s => s.Terminate()).Callback(() => Assert.AreEqual(2, ++order));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.Terminate(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromCreateNewDesktopToDisableExplorerShell()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var activate = 0;
|
||||
var close = 0;
|
||||
var hide = 0;
|
||||
var startupDesktop = 0;
|
||||
var terminate = 0;
|
||||
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
desktopFactory.Reset();
|
||||
explorerShell.Reset();
|
||||
explorerShell.Setup(s => s.HideAllWindows()).Callback(() => hide = ++order);
|
||||
explorerShell.Setup(s => s.Terminate()).Callback(() => terminate = ++order);
|
||||
randomDesktop.Reset();
|
||||
randomDesktop.Setup(d => d.Close()).Callback(() => close = ++order);
|
||||
originalDesktop.Reset();
|
||||
originalDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
processFactory.Reset();
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == originalDesktop.Object)).Callback(() => startupDesktop = ++order);
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.Terminate(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Close(), Times.Once);
|
||||
originalDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == originalDesktop.Object), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, activate);
|
||||
Assert.AreEqual(2, startupDesktop);
|
||||
Assert.AreEqual(3, close);
|
||||
Assert.AreEqual(4, hide);
|
||||
Assert.AreEqual(5, terminate);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromCreateNewDesktopToNone()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var activate = 0;
|
||||
var close = 0;
|
||||
var startupDesktop = 0;
|
||||
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
desktopFactory.Reset();
|
||||
explorerShell.Reset();
|
||||
randomDesktop.Reset();
|
||||
randomDesktop.Setup(d => d.Close()).Callback(() => close = ++order);
|
||||
originalDesktop.Reset();
|
||||
originalDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
processFactory.Reset();
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == originalDesktop.Object)).Callback(() => startupDesktop = ++order);
|
||||
nextSettings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Close(), Times.Once);
|
||||
originalDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == originalDesktop.Object), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, activate);
|
||||
Assert.AreEqual(2, startupDesktop);
|
||||
Assert.AreEqual(3, close);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromDisableExplorerShellToCreateNewDesktop()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var activate = 0;
|
||||
var current = 0;
|
||||
var restore = 0;
|
||||
var start = 0;
|
||||
var startupDesktop = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
desktopFactory.Reset();
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object).Callback(() => current = ++order);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
explorerShell.Reset();
|
||||
explorerShell.Setup(s => s.RestoreAllWindows()).Callback(() => restore = ++order);
|
||||
explorerShell.Setup(s => s.Start()).Callback(() => start = ++order);
|
||||
randomDesktop.Reset();
|
||||
randomDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
originalDesktop.Reset();
|
||||
processFactory.Reset();
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == randomDesktop.Object)).Callback(() => startupDesktop = ++order);
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
|
||||
desktopFactory.Verify(f => f.CreateRandom(), Times.Once);
|
||||
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.Start(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
originalDesktop.VerifyNoOtherCalls();
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == randomDesktop.Object), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, start);
|
||||
Assert.AreEqual(2, restore);
|
||||
Assert.AreEqual(3, current);
|
||||
Assert.AreEqual(4, activate);
|
||||
Assert.AreEqual(5, startupDesktop);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromDisableExplorerShellToNone()
|
||||
{
|
||||
var order = 0;
|
||||
var restore = 0;
|
||||
var start = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
explorerShell.Reset();
|
||||
explorerShell.Setup(s => s.RestoreAllWindows()).Callback(() => restore = ++order);
|
||||
explorerShell.Setup(s => s.Start()).Callback(() => start = ++order);
|
||||
processFactory.Reset();
|
||||
nextSettings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.Start(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.IsAny<IDesktop>(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, start);
|
||||
Assert.AreEqual(2, restore);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromNoneToCreateNewDesktop()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var activate = 0;
|
||||
var current = 0;
|
||||
var startup = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
desktopFactory.Reset();
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object).Callback(() => current = ++order);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
explorerShell.Reset();
|
||||
randomDesktop.Reset();
|
||||
randomDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
originalDesktop.Reset();
|
||||
processFactory.Reset();
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == randomDesktop.Object)).Callback(() => startup = ++order);
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
|
||||
desktopFactory.Verify(f => f.CreateRandom(), Times.Once);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
originalDesktop.VerifyNoOtherCalls();
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == randomDesktop.Object), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, current);
|
||||
Assert.AreEqual(2, activate);
|
||||
Assert.AreEqual(3, startup);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchFromNoneToDisableExplorerShell()
|
||||
{
|
||||
var order = 0;
|
||||
var hide = 0;
|
||||
var terminate = 0;
|
||||
|
||||
nextSettings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
desktopFactory.Reset();
|
||||
explorerShell.Reset();
|
||||
explorerShell.Setup(s => s.HideAllWindows()).Callback(() => hide = ++order);
|
||||
explorerShell.Setup(s => s.Terminate()).Callback(() => terminate = ++order);
|
||||
processFactory.Reset();
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.Terminate(), Times.Once);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = It.IsAny<IDesktop>(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(1, hide);
|
||||
Assert.AreEqual(2, terminate);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustNotReinitializeCreateNewDesktopIfAlreadyActive()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var success = true;
|
||||
|
||||
currentSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
|
||||
success &= sut.Perform() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
|
||||
Assert.IsTrue(success);
|
||||
|
||||
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
|
||||
desktopFactory.Verify(f => f.CreateRandom(), Times.Once);
|
||||
desktopMonitor.Verify(m => m.Start(It.IsAny<IDesktop>()), Times.Once);
|
||||
desktopMonitor.Verify(m => m.Stop(), Times.Never);
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
randomDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
randomDesktop.Verify(d => d.Close(), Times.Never);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = randomDesktop.Object, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustNotReinitializeDisableExplorerShellIfAlreadyActive()
|
||||
{
|
||||
var success = true;
|
||||
|
||||
currentSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
|
||||
success &= sut.Perform() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
success &= sut.Repeat() == OperationResult.Success;
|
||||
|
||||
Assert.IsTrue(success);
|
||||
|
||||
explorerShell.Verify(s => s.Start(), Times.Never);
|
||||
explorerShell.Verify(s => s.Terminate(), Times.Once);
|
||||
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
|
||||
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustCorrectlyRevertCreateNewDesktop()
|
||||
{
|
||||
var originalDesktop = new Mock<IDesktop>();
|
||||
var randomDesktop = new Mock<IDesktop>();
|
||||
var order = 0;
|
||||
var activate = 0;
|
||||
var setStartup = 0;
|
||||
var stopMonitor = 0;
|
||||
var close = 0;
|
||||
|
||||
currentSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
nextSettings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
|
||||
desktopFactory.Setup(f => f.CreateRandom()).Returns(randomDesktop.Object);
|
||||
|
||||
var performResult = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, performResult);
|
||||
|
||||
desktopFactory.Reset();
|
||||
desktopMonitor.Setup(m => m.Stop()).Callback(() => stopMonitor = ++order);
|
||||
explorerShell.Reset();
|
||||
originalDesktop.Reset();
|
||||
originalDesktop.Setup(d => d.Activate()).Callback(() => activate = ++order);
|
||||
processFactory.SetupSet(f => f.StartupDesktop = It.Is<IDesktop>(d => d == originalDesktop.Object)).Callback(() => setStartup = ++order);
|
||||
randomDesktop.Reset();
|
||||
randomDesktop.Setup(d => d.Close()).Callback(() => close = ++order);
|
||||
|
||||
var revertResult = sut.Revert();
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
originalDesktop.Verify(d => d.Activate(), Times.Once);
|
||||
processFactory.VerifySet(f => f.StartupDesktop = originalDesktop.Object, Times.Once);
|
||||
randomDesktop.Verify(d => d.Close(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, performResult);
|
||||
Assert.AreEqual(OperationResult.Success, revertResult);
|
||||
Assert.AreEqual(1, stopMonitor);
|
||||
Assert.AreEqual(2, activate);
|
||||
Assert.AreEqual(3, setStartup);
|
||||
Assert.AreEqual(4, close);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustCorrectlyRevertDisableExplorerShell()
|
||||
{
|
||||
var order = 0;
|
||||
|
||||
currentSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
nextSettings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
explorerShell.Setup(s => s.Start()).Callback(() => Assert.AreEqual(1, ++order));
|
||||
explorerShell.Setup(s => s.RestoreAllWindows()).Callback(() => Assert.AreEqual(2, ++order));
|
||||
|
||||
var performResult = sut.Perform();
|
||||
var revertResult = sut.Revert();
|
||||
|
||||
explorerShell.Verify(s => s.Start(), Times.Once);
|
||||
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, performResult);
|
||||
Assert.AreEqual(OperationResult.Success, revertResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingWithoutKioskMode()
|
||||
{
|
||||
nextSettings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Perform());
|
||||
Assert.AreEqual(OperationResult.Success, sut.Repeat());
|
||||
Assert.AreEqual(OperationResult.Success, sut.Repeat());
|
||||
Assert.AreEqual(OperationResult.Success, sut.Repeat());
|
||||
Assert.AreEqual(OperationResult.Success, sut.Repeat());
|
||||
Assert.AreEqual(OperationResult.Success, sut.Revert());
|
||||
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class RemoteSessionOperationTests
|
||||
{
|
||||
private SessionContext context;
|
||||
private Mock<IRemoteSessionDetector> detector;
|
||||
private Mock<ILogger> logger;
|
||||
private AppSettings settings;
|
||||
|
||||
private RemoteSessionOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new SessionContext();
|
||||
detector = new Mock<IRemoteSessionDetector>();
|
||||
logger = new Mock<ILogger>();
|
||||
settings = new AppSettings();
|
||||
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.Settings = settings;
|
||||
sut = new RemoteSessionOperation(detector.Object, logger.Object, context);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfRemoteSessionNotAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(true);
|
||||
settings.Service.DisableRemoteConnections = true;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.Once);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfRemoteSessionAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(true);
|
||||
settings.Service.DisableRemoteConnections = false;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.AtMostOnce);
|
||||
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfNoRemoteSession()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(false);
|
||||
settings.Service.DisableRemoteConnections = true;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.Once);
|
||||
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAbortIfRemoteSessionNotAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(true);
|
||||
settings.Service.DisableRemoteConnections = true;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.Once);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfRemoteSessionAllowed()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(true);
|
||||
settings.Service.DisableRemoteConnections = false;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.AtMostOnce);
|
||||
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfNoRemoteSession()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(false);
|
||||
settings.Service.DisableRemoteConnections = true;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsRemoteSession(), Times.Once);
|
||||
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNoting()
|
||||
{
|
||||
var messageShown = false;
|
||||
|
||||
detector.Setup(d => d.IsRemoteSession()).Returns(true);
|
||||
settings.Service.DisableRemoteConnections = false;
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is MessageEventArgs)
|
||||
{
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
detector.VerifyNoOtherCalls();
|
||||
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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.Configuration.Contracts;
|
||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Server.Contracts;
|
||||
using SafeExamBrowser.Server.Contracts.Data;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Server;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ServerOperationTests
|
||||
{
|
||||
private SessionContext context;
|
||||
private Mock<IFileSystem> fileSystem;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IServerProxy> server;
|
||||
private Mock<IConfigurationRepository> configuration;
|
||||
|
||||
private ServerOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
configuration = new Mock<IConfigurationRepository>();
|
||||
context = new SessionContext();
|
||||
fileSystem = new Mock<IFileSystem>();
|
||||
logger = new Mock<ILogger>();
|
||||
server = new Mock<IServerProxy>();
|
||||
|
||||
context.Current = new SessionConfiguration();
|
||||
context.Current.AppConfig = new AppConfig();
|
||||
context.Current.Settings = new AppSettings();
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.AppConfig = new AppConfig();
|
||||
context.Next.Settings = new AppSettings();
|
||||
|
||||
sut = new ServerOperation(new string[0], configuration.Object, fileSystem.Object, logger.Object, context, server.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeServerSession()
|
||||
{
|
||||
var connect = 0;
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var counter = 0;
|
||||
var delete = 0;
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSelection = 0;
|
||||
var examSettings = new AppSettings();
|
||||
var getConfiguration = 0;
|
||||
var getConnection = 0;
|
||||
var getExams = 0;
|
||||
var initialize = 0;
|
||||
var initialSettings = context.Next.Settings;
|
||||
var serverSettings = context.Next.Settings.Server;
|
||||
|
||||
configuration
|
||||
.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>()))
|
||||
.Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
fileSystem.Setup(f => f.Delete(It.IsAny<string>())).Callback(() => delete = ++counter);
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true)).Callback(() => connect = ++counter);
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>())).Callback(() => initialize = ++counter);
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection).Callback(() => getConnection = ++counter);
|
||||
server.Setup(s => s.SendSelectedExam(It.IsAny<Exam>())).Returns(new ServerResponse<string>(true, default));
|
||||
server
|
||||
.Setup(s => s.GetAvailableExams(It.IsAny<string>()))
|
||||
.Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)))
|
||||
.Callback(() => getExams = ++counter);
|
||||
server
|
||||
.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>()))
|
||||
.Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")))
|
||||
.Callback(() => getConfiguration = ++counter);
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
examSelection = ++counter;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
server.Verify(s => s.SendSelectedExam(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
|
||||
Assert.AreEqual(1, initialize);
|
||||
Assert.AreEqual(2, connect);
|
||||
Assert.AreEqual(3, getExams);
|
||||
Assert.AreEqual(4, examSelection);
|
||||
Assert.AreEqual(5, getConfiguration);
|
||||
Assert.AreEqual(6, getConnection);
|
||||
Assert.AreEqual(7, delete);
|
||||
Assert.AreEqual(connection.Api, context.Next.AppConfig.ServerApi);
|
||||
Assert.AreEqual(connection.ConnectionToken, context.Next.AppConfig.ServerConnectionToken);
|
||||
Assert.AreEqual(connection.Oauth2Token, context.Next.AppConfig.ServerOauth2Token);
|
||||
Assert.AreEqual(exam.Id, context.Next.AppConfig.ServerExamId);
|
||||
Assert.AreEqual(exam.Url, context.Next.Settings.Browser.StartUrl);
|
||||
Assert.AreSame(examSettings, context.Next.Settings);
|
||||
Assert.AreSame(serverSettings, context.Next.Settings.Server);
|
||||
Assert.AreNotSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(SessionMode.Server, context.Next.Settings.SessionMode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfSettingsCouldNotBeLoaded()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var initialSettings = context.Next.Settings;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.UnexpectedError);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
|
||||
Assert.AreNotEqual(connection.Api, context.Next.AppConfig.ServerApi);
|
||||
Assert.AreNotEqual(connection.ConnectionToken, context.Next.AppConfig.ServerConnectionToken);
|
||||
Assert.AreNotEqual(connection.Oauth2Token, context.Next.AppConfig.ServerOauth2Token);
|
||||
Assert.AreNotEqual(exam.Id, context.Next.AppConfig.ServerExamId);
|
||||
Assert.AreNotEqual(exam.Url, context.Next.Settings.Browser.StartUrl);
|
||||
Assert.AreNotSame(examSettings, context.Next.Settings);
|
||||
Assert.AreSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.AreEqual(SessionMode.Server, context.Next.Settings.SessionMode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyAbort()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var messageShown = false;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(false, default(Uri)));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
|
||||
if (args is ServerFailureEventArgs s)
|
||||
{
|
||||
s.Abort = true;
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Never);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Never);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyFallback()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var messageShown = false;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(false, default(Uri)));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
|
||||
if (args is ServerFailureEventArgs s)
|
||||
{
|
||||
s.Fallback = true;
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Never);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Never);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAutomaticallySelectExam()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var serverSettings = context.Next.Settings.Server;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
context.Next.Settings.Server.ExamId = "some id";
|
||||
fileSystem.Setup(f => f.Delete(It.IsAny<string>()));
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, new[] { exam }));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")));
|
||||
server.Setup(s => s.SendSelectedExam(It.IsAny<Exam>())).Returns(new ServerResponse<string>(true, default));
|
||||
sut.ActionRequired += (args) => Assert.Fail();
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
server.Verify(s => s.SendSelectedExam(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDoNothingIfNormalSession()
|
||||
{
|
||||
var initialSettings = context.Next.Settings;
|
||||
|
||||
context.Next.Settings.SessionMode = SessionMode.Normal;
|
||||
sut.ActionRequired += (_) => Assert.Fail();
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
configuration.VerifyNoOtherCalls();
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlyInitializeServerSession()
|
||||
{
|
||||
var connect = 0;
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var counter = 0;
|
||||
var delete = 0;
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSelection = 0;
|
||||
var examSettings = new AppSettings();
|
||||
var getConfiguration = 0;
|
||||
var getConnection = 0;
|
||||
var getExams = 0;
|
||||
var initialize = 0;
|
||||
var initialSettings = context.Next.Settings;
|
||||
var serverSettings = context.Next.Settings.Server;
|
||||
|
||||
configuration
|
||||
.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>()))
|
||||
.Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
fileSystem.Setup(f => f.Delete(It.IsAny<string>())).Callback(() => delete = ++counter);
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true)).Callback(() => connect = ++counter);
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>())).Callback(() => initialize = ++counter);
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection).Callback(() => getConnection = ++counter);
|
||||
server.Setup(s => s.SendSelectedExam(It.IsAny<Exam>())).Returns(new ServerResponse<string>(true, default));
|
||||
server
|
||||
.Setup(s => s.GetAvailableExams(It.IsAny<string>()))
|
||||
.Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)))
|
||||
.Callback(() => getExams = ++counter);
|
||||
server
|
||||
.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>()))
|
||||
.Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")))
|
||||
.Callback(() => getConfiguration = ++counter);
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
examSelection = ++counter;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
server.Verify(s => s.SendSelectedExam(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
|
||||
Assert.AreEqual(1, initialize);
|
||||
Assert.AreEqual(2, connect);
|
||||
Assert.AreEqual(3, getExams);
|
||||
Assert.AreEqual(4, examSelection);
|
||||
Assert.AreEqual(5, getConfiguration);
|
||||
Assert.AreEqual(6, getConnection);
|
||||
Assert.AreEqual(7, delete);
|
||||
Assert.AreEqual(connection.Api, context.Next.AppConfig.ServerApi);
|
||||
Assert.AreEqual(connection.ConnectionToken, context.Next.AppConfig.ServerConnectionToken);
|
||||
Assert.AreEqual(connection.Oauth2Token, context.Next.AppConfig.ServerOauth2Token);
|
||||
Assert.AreEqual(exam.Id, context.Next.AppConfig.ServerExamId);
|
||||
Assert.AreEqual(exam.Url, context.Next.Settings.Browser.StartUrl);
|
||||
Assert.AreSame(examSettings, context.Next.Settings);
|
||||
Assert.AreSame(serverSettings, context.Next.Settings.Server);
|
||||
Assert.AreNotSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreEqual(SessionMode.Server, context.Next.Settings.SessionMode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustFailIfSettingsCouldNotBeLoaded()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var initialSettings = context.Next.Settings;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.UnexpectedError);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
|
||||
Assert.AreNotEqual(connection.Api, context.Next.AppConfig.ServerApi);
|
||||
Assert.AreNotEqual(connection.ConnectionToken, context.Next.AppConfig.ServerConnectionToken);
|
||||
Assert.AreNotEqual(connection.Oauth2Token, context.Next.AppConfig.ServerOauth2Token);
|
||||
Assert.AreNotEqual(exam.Id, context.Next.AppConfig.ServerExamId);
|
||||
Assert.AreNotEqual(exam.Url, context.Next.Settings.Browser.StartUrl);
|
||||
Assert.AreNotSame(examSettings, context.Next.Settings);
|
||||
Assert.AreSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.AreEqual(SessionMode.Server, context.Next.Settings.SessionMode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlyAbort()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var messageShown = false;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(false, default(Uri)));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
|
||||
if (args is ServerFailureEventArgs s)
|
||||
{
|
||||
s.Abort = true;
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Never);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Never);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlyFallback()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var messageShown = false;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, default(IEnumerable<Exam>)));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(false, default(Uri)));
|
||||
sut.ActionRequired += (args) =>
|
||||
{
|
||||
if (args is ExamSelectionEventArgs e)
|
||||
{
|
||||
e.Success = true;
|
||||
e.SelectedExam = exam;
|
||||
}
|
||||
|
||||
if (args is ServerFailureEventArgs s)
|
||||
{
|
||||
s.Fallback = true;
|
||||
messageShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Never);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Never);
|
||||
|
||||
Assert.IsTrue(messageShown);
|
||||
Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAutomaticallySelectExam()
|
||||
{
|
||||
var connection = new ConnectionInfo { Api = "some API", ConnectionToken = "some token", Oauth2Token = "some OAuth2 token" };
|
||||
var exam = new Exam { Id = "some id", LmsName = "some LMS", Name = "some name", Url = "some URL" };
|
||||
var examSettings = new AppSettings();
|
||||
var serverSettings = context.Next.Settings.Server;
|
||||
|
||||
configuration.Setup(c => c.TryLoadSettings(It.IsAny<Uri>(), out examSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
context.Next.Settings.Server.ExamId = "some id";
|
||||
fileSystem.Setup(f => f.Delete(It.IsAny<string>()));
|
||||
server.Setup(s => s.Connect()).Returns(new ServerResponse(true));
|
||||
server.Setup(s => s.Initialize(It.IsAny<ServerSettings>()));
|
||||
server.Setup(s => s.GetConnectionInfo()).Returns(connection);
|
||||
server.Setup(s => s.GetAvailableExams(It.IsAny<string>())).Returns(new ServerResponse<IEnumerable<Exam>>(true, new[] { exam }));
|
||||
server.Setup(s => s.GetConfigurationFor(It.IsAny<Exam>())).Returns(new ServerResponse<Uri>(true, new Uri("file:///configuration.seb")));
|
||||
server.Setup(s => s.SendSelectedExam(It.IsAny<Exam>())).Returns(new ServerResponse<string>(true, default));
|
||||
sut.ActionRequired += (args) => Assert.Fail();
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
fileSystem.Verify(f => f.Delete(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.Connect(), Times.Once);
|
||||
server.Verify(s => s.Initialize(It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.GetAvailableExams(It.IsAny<string>()), Times.Once);
|
||||
server.Verify(s => s.GetConfigurationFor(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
server.Verify(s => s.GetConnectionInfo(), Times.Once);
|
||||
server.Verify(s => s.SendSelectedExam(It.Is<Exam>(e => e == exam)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustNotAllowToReconfigureServerSession()
|
||||
{
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
context.Current.AppConfig.ServerApi = "api";
|
||||
context.Current.AppConfig.ServerConnectionToken = "token";
|
||||
context.Current.AppConfig.ServerExamId = "id";
|
||||
context.Current.AppConfig.ServerOauth2Token = "oauth2";
|
||||
context.Current.Settings.SessionMode = SessionMode.Server;
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
};
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
configuration.VerifyNoOtherCalls();
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.VerifyNoOtherCalls();
|
||||
|
||||
Assert.IsNull(context.Next.AppConfig.ServerApi);
|
||||
Assert.IsNull(context.Next.AppConfig.ServerConnectionToken);
|
||||
Assert.IsNull(context.Next.AppConfig.ServerOauth2Token);
|
||||
Assert.IsInstanceOfType(args, typeof(MessageEventArgs));
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustDoNothingIfNormalSession()
|
||||
{
|
||||
var initialSettings = context.Next.Settings;
|
||||
|
||||
context.Current.Settings.SessionMode = SessionMode.Normal;
|
||||
context.Next.Settings.SessionMode = SessionMode.Normal;
|
||||
sut.ActionRequired += (_) => Assert.Fail();
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
configuration.VerifyNoOtherCalls();
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreSame(initialSettings, context.Next.Settings);
|
||||
Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDisconnectFromServerWhenSessionRunning()
|
||||
{
|
||||
context.Current.Settings.SessionMode = SessionMode.Server;
|
||||
context.Next = default;
|
||||
server.Setup(s => s.Disconnect()).Returns(new ServerResponse(true));
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDisconnectFromServerWhenSessionStartFailed()
|
||||
{
|
||||
context.Current = default;
|
||||
context.Next.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Disconnect()).Returns(new ServerResponse(true));
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustFailWhenDisconnectionUnsuccesful()
|
||||
{
|
||||
context.Current.Settings.SessionMode = SessionMode.Server;
|
||||
server.Setup(s => s.Disconnect()).Returns(new ServerResponse(false));
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothingIfNormalSession()
|
||||
{
|
||||
context.Current.Settings.SessionMode = SessionMode.Normal;
|
||||
sut.ActionRequired += (_) => Assert.Fail();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
configuration.VerifyNoOtherCalls();
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
server.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,564 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Service;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ServiceOperationTests
|
||||
{
|
||||
private SessionContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private Mock<IServiceProxy> service;
|
||||
private EventWaitHandle serviceEvent;
|
||||
private Mock<IUserInfo> userInfo;
|
||||
private ServiceOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
var serviceEventName = $"{nameof(SafeExamBrowser)}-{nameof(ServiceOperationTests)}";
|
||||
|
||||
logger = new Mock<ILogger>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
service = new Mock<IServiceProxy>();
|
||||
serviceEvent = new EventWaitHandle(false, EventResetMode.AutoReset, serviceEventName);
|
||||
context = new SessionContext();
|
||||
userInfo = new Mock<IUserInfo>();
|
||||
|
||||
context.Current = new SessionConfiguration();
|
||||
context.Current.AppConfig = new AppConfig();
|
||||
context.Current.AppConfig.ServiceEventName = serviceEventName;
|
||||
context.Current.Settings = new AppSettings();
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.AppConfig = new AppConfig();
|
||||
context.Next.AppConfig.ServiceEventName = serviceEventName;
|
||||
context.Next.Settings = new AppSettings();
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, context, 0, userInfo.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustConnectToService()
|
||||
{
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Optional;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
service.Verify(s => s.Connect(null, true), Times.Exactly(2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotConnectToServiceWithIgnoreSet()
|
||||
{
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
context.Next.Settings.Service.IgnoreService = true;
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Optional;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
service.Verify(s => s.Connect(null, true), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustStartSessionIfConnected()
|
||||
{
|
||||
context.Next.SessionId = Guid.NewGuid();
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Optional;
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.Is<ServiceConfiguration>(c => c.SessionId == context.Next.SessionId)), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
userInfo.Verify(u => u.GetUserName(), Times.Once);
|
||||
userInfo.Verify(u => u.GetUserSid(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfSessionStartUnsuccessful()
|
||||
{
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfSessionNotStartedWithinTimeout()
|
||||
{
|
||||
const int TIMEOUT = 50;
|
||||
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true));
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, context, TIMEOUT, userInfo.Object);
|
||||
|
||||
before = DateTime.Now;
|
||||
var result = sut.Perform();
|
||||
after = DateTime.Now;
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, TIMEOUT));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotStartSessionIfNotConnected()
|
||||
{
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(false);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustHandleCommunicationFailureWhenStartingSession()
|
||||
{
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(false));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfServiceMandatoryAndNotAvailable()
|
||||
{
|
||||
var errorShown = false;
|
||||
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(false);
|
||||
sut.ActionRequired += (args) => errorShown = args is MessageEventArgs m && m.Icon == MessageBoxIcon.Error;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(errorShown);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotFailIfServiceOptionalAndNotAvailable()
|
||||
{
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Optional;
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(false);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustShowWarningIfServiceNotAvailableAndPolicyWarn()
|
||||
{
|
||||
var warningShown = false;
|
||||
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Warn;
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(false);
|
||||
sut.ActionRequired += (args) => warningShown = args is MessageEventArgs m && m.Icon == MessageBoxIcon.Warning;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsTrue(warningShown);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustStopCurrentAndStartNewSession()
|
||||
{
|
||||
var order = 0;
|
||||
var start1 = 0;
|
||||
var stop1 = 0;
|
||||
var start2 = 0;
|
||||
var session1Id = Guid.NewGuid();
|
||||
var session2Id = Guid.NewGuid();
|
||||
|
||||
context.Next.SessionId = session1Id;
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service
|
||||
.Setup(s => s.StartSession(It.Is<ServiceConfiguration>(c => c.SessionId == session1Id)))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => { start1 = ++order; serviceEvent.Set(); });
|
||||
service
|
||||
.Setup(s => s.StartSession(It.Is<ServiceConfiguration>(c => c.SessionId == session2Id)))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => { start2 = ++order; serviceEvent.Set(); });
|
||||
service
|
||||
.Setup(s => s.StopSession(It.IsAny<Guid>()))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => { stop1 = ++order; serviceEvent.Set(); });
|
||||
|
||||
sut.Perform();
|
||||
|
||||
context.Current.SessionId = session1Id;
|
||||
context.Next.SessionId = session2Id;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.Connect(It.IsAny<Guid?>(), It.IsAny<bool>()), Times.Once);
|
||||
service.Verify(s => s.StopSession(It.Is<Guid>(id => id == session1Id)), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.Is<ServiceConfiguration>(c => c.SessionId == session1Id)), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.Is<ServiceConfiguration>(c => c.SessionId == session2Id)), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsTrue(start1 == 1);
|
||||
Assert.IsTrue(stop1 == 2);
|
||||
Assert.IsTrue(start2 == 3);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustEstablishConnectionIfNotConnected()
|
||||
{
|
||||
PerformNormally();
|
||||
|
||||
service.Reset();
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true).Callback(() => service.SetupGet(s => s.IsConnected).Returns(true));
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.Connect(It.IsAny<Guid?>(), It.IsAny<bool>()), Times.Once);
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustNotEstablishConnectionWithIgnoreSet()
|
||||
{
|
||||
PerformNormally();
|
||||
|
||||
context.Next.Settings.Service.IgnoreService = true;
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
service.Reset();
|
||||
service.SetupGet(s => s.IsConnected).Returns(false);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true).Callback(() => service.SetupGet(s => s.IsConnected).Returns(true));
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.Connect(It.IsAny<Guid?>(), It.IsAny<bool>()), Times.Never);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustStopSessionAndCloseConnectionWithIgnoreSet()
|
||||
{
|
||||
var connected = true;
|
||||
|
||||
PerformNormally();
|
||||
|
||||
context.Next.Settings.Service.IgnoreService = true;
|
||||
context.Next.Settings.Service.Policy = ServicePolicy.Mandatory;
|
||||
|
||||
service.Reset();
|
||||
service.SetupGet(s => s.IsConnected).Returns(() => connected);
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.Disconnect()).Returns(true).Callback(() => connected = false);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.Connect(It.IsAny<Guid?>(), It.IsAny<bool>()), Times.Never);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Never);
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustFailIfCurrentSessionWasNotStoppedSuccessfully()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(false));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustFailIfSessionNotStoppedWithinTimeout()
|
||||
{
|
||||
const int TIMEOUT = 50;
|
||||
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true));
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, context, TIMEOUT, userInfo.Object);
|
||||
|
||||
PerformNormally();
|
||||
|
||||
before = DateTime.Now;
|
||||
var result = sut.Repeat();
|
||||
after = DateTime.Now;
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, TIMEOUT));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustNotStopSessionIfNoSessionRunning()
|
||||
{
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDisconnect()
|
||||
{
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(true));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustHandleCommunicationFailureWhenStoppingSession()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(false));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustHandleCommunicationFailureWhenInitiatingSystemConfigurationUpdate()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(false));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustFailIfSessionStopUnsuccessful()
|
||||
{
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustFailIfSessionNotStoppedWithinTimeout()
|
||||
{
|
||||
const int TIMEOUT = 50;
|
||||
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true));
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, context, TIMEOUT, userInfo.Object);
|
||||
|
||||
PerformNormally();
|
||||
|
||||
before = DateTime.Now;
|
||||
var result = sut.Revert();
|
||||
after = DateTime.Now;
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, TIMEOUT));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotStopSessionWhenNotConnected()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotStopSessionIfNoSessionRunning()
|
||||
{
|
||||
context.Current = null;
|
||||
context.Next = null;
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotDisconnnectIfNotConnected()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustStopSessionIfConnected()
|
||||
{
|
||||
context.Next.SessionId = Guid.NewGuid();
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
service.Setup(s => s.StopSession(It.IsAny<Guid>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(true));
|
||||
|
||||
PerformNormally();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.Is<Guid>(id => id == context.Next.SessionId)), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
service.Verify(s => s.RunSystemConfigurationUpdate(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustStopSessionIfNewSessionNotCompletelyStarted()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
|
||||
context.Current.SessionId = Guid.NewGuid();
|
||||
context.Next.SessionId = sessionId;
|
||||
|
||||
PerformNormally();
|
||||
|
||||
context.Current.SessionId = default(Guid);
|
||||
context.Next.SessionId = default(Guid);
|
||||
service.Setup(s => s.StopSession(It.Is<Guid>(id => id == sessionId))).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
service.Setup(s => s.RunSystemConfigurationUpdate()).Returns(new CommunicationResult(true));
|
||||
service.Setup(s => s.Disconnect()).Returns(true);
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
service.Verify(s => s.StopSession(It.Is<Guid>(id => id == sessionId)), Times.Once);
|
||||
service.Verify(s => s.StopSession(It.Is<Guid>(id => id == default(Guid))), Times.Never);
|
||||
service.Verify(s => s.Disconnect(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
private void PerformNormally()
|
||||
{
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true)).Callback(() => serviceEvent.Set());
|
||||
|
||||
sut.Perform();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class SessionActivationOperationTests
|
||||
{
|
||||
private SessionConfiguration currentSession;
|
||||
private Mock<ILogger> logger;
|
||||
private SessionConfiguration nextSession;
|
||||
private AppSettings nextSettings;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private SessionActivationOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
currentSession = new SessionConfiguration();
|
||||
logger = new Mock<ILogger>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new AppSettings();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
nextSession.Settings = nextSettings;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
sut = new SessionActivationOperation(logger.Object, sessionContext);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyActivateFirstSession()
|
||||
{
|
||||
sessionContext.Current = null;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(sessionContext.Current, nextSession);
|
||||
Assert.IsNull(sessionContext.Next);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlySwitchLogSeverity()
|
||||
{
|
||||
nextSettings.LogLevel = LogLevel.Info;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
logger.VerifySet(l => l.LogLevel = It.Is<LogLevel>(ll => ll == nextSettings.LogLevel));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchSession()
|
||||
{
|
||||
var result = sut.Repeat();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(sessionContext.Current, nextSession);
|
||||
Assert.IsNull(sessionContext.Next);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustCorrectlySwitchLogSeverity()
|
||||
{
|
||||
nextSettings.LogLevel = LogLevel.Warning;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
logger.VerifySet(l => l.LogLevel = It.Is<LogLevel>(ll => ll == nextSettings.LogLevel));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustAlwaysCompleteSuccessfully()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class SessionInitializationOperationTests
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private Mock<IConfigurationRepository> configuration;
|
||||
private Mock<IFileSystem> fileSystem;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private SessionInitializationOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new AppConfig();
|
||||
configuration = new Mock<IConfigurationRepository>();
|
||||
fileSystem = new Mock<IFileSystem>();
|
||||
logger = new Mock<ILogger>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
configuration.Setup(c => c.InitializeSessionConfiguration()).Returns(session);
|
||||
session.AppConfig = appConfig;
|
||||
sessionContext.Next = session;
|
||||
|
||||
sut = new SessionInitializationOperation(configuration.Object, fileSystem.Object, logger.Object, runtimeHost.Object, sessionContext);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeConfiguration()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
appConfig.TemporaryDirectory = @"C:\Some\Random\Path";
|
||||
session.ClientAuthenticationToken = token;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
configuration.Verify(c => c.InitializeSessionConfiguration(), Times.Once);
|
||||
fileSystem.Verify(f => f.CreateDirectory(It.Is<string>(s => s == appConfig.TemporaryDirectory)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsNull(sessionContext.Current);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustInitializeConfiguration()
|
||||
{
|
||||
var currentSession = new SessionConfiguration();
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
appConfig.TemporaryDirectory = @"C:\Some\Random\Path";
|
||||
session.ClientAuthenticationToken = token;
|
||||
sessionContext.Current = currentSession;
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
configuration.Verify(c => c.InitializeSessionConfiguration(), Times.Once);
|
||||
fileSystem.Verify(f => f.CreateDirectory(It.Is<string>(s => s == appConfig.TemporaryDirectory)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(currentSession,sessionContext.Current);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
configuration.VerifyNoOtherCalls();
|
||||
fileSystem.VerifyNoOtherCalls();
|
||||
logger.VerifyNoOtherCalls();
|
||||
runtimeHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
|
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2024 ETH Zürich, IT Services
|
||||
*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class VirtualMachineOperationTests
|
||||
{
|
||||
private Mock<IVirtualMachineDetector> detector;
|
||||
private Mock<ILogger> logger;
|
||||
private SessionContext context;
|
||||
private VirtualMachineOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
detector = new Mock<IVirtualMachineDetector>();
|
||||
logger = new Mock<ILogger>();
|
||||
context = new SessionContext();
|
||||
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.Settings = new AppSettings();
|
||||
|
||||
sut = new VirtualMachineOperation(detector.Object, logger.Object, context);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfVirtualMachineNotAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfVirtualMachineAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMostOnce);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMost(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfNotAVirtualMachine()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAbortIfVirtualMachineNotAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfVirtualMachineAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMostOnce);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMost(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfNotAVirtualMachine()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
detector.VerifyNoOtherCalls();
|
||||
logger.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user