194 lines
6.4 KiB
C#
194 lines
6.4 KiB
C#
/*
|
|
* Copyright (c) 2025 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.Client.Responsibilities;
|
|
using SafeExamBrowser.Communication.Contracts.Proxies;
|
|
using SafeExamBrowser.Configuration.Contracts;
|
|
using SafeExamBrowser.Core.Contracts.OperationModel;
|
|
using SafeExamBrowser.Core.Contracts.ResponsibilityModel;
|
|
using SafeExamBrowser.Logging.Contracts;
|
|
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
|
|
|
namespace SafeExamBrowser.Client.UnitTests
|
|
{
|
|
[TestClass]
|
|
public class ClientControllerTests
|
|
{
|
|
private AppConfig appConfig;
|
|
private ClientContext context;
|
|
private Mock<ILogger> logger;
|
|
private Mock<IOperationSequence> operationSequence;
|
|
private Mock<IResponsibilityCollection<ClientTask>> responsibilities;
|
|
private Mock<IRuntimeProxy> runtimeProxy;
|
|
private Mock<ISplashScreen> splashScreen;
|
|
|
|
private ClientController sut;
|
|
|
|
[TestInitialize]
|
|
public void Initialize()
|
|
{
|
|
appConfig = new AppConfig();
|
|
context = new ClientContext();
|
|
logger = new Mock<ILogger>();
|
|
operationSequence = new Mock<IOperationSequence>();
|
|
responsibilities = new Mock<IResponsibilityCollection<ClientTask>>();
|
|
runtimeProxy = new Mock<IRuntimeProxy>();
|
|
splashScreen = new Mock<ISplashScreen>();
|
|
|
|
operationSequence.Setup(o => o.TryPerform()).Returns(OperationResult.Success);
|
|
operationSequence.Setup(o => o.TryRevert()).Returns(OperationResult.Success);
|
|
runtimeProxy.Setup(r => r.InformClientReady()).Returns(new CommunicationResult(true));
|
|
|
|
sut = new ClientController(
|
|
context,
|
|
logger.Object,
|
|
operationSequence.Object,
|
|
responsibilities.Object,
|
|
runtimeProxy.Object,
|
|
splashScreen.Object);
|
|
|
|
context.AppConfig = appConfig;
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Shutdown_MustDelegateResponsibilities()
|
|
{
|
|
var order = 0;
|
|
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.CloseShell)).Callback(() => Assert.AreEqual(1, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.DeregisterEvents)).Callback(() => Assert.AreEqual(2, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.UpdateSessionIntegrity)).Callback(() => Assert.AreEqual(3, ++order));
|
|
|
|
sut.Terminate();
|
|
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.CloseShell), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.DeregisterEvents), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.UpdateSessionIntegrity), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Shutdown_MustRevertOperations()
|
|
{
|
|
sut.Terminate();
|
|
|
|
operationSequence.Verify(o => o.TryRevert(), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustDelegateResponsibilities()
|
|
{
|
|
var clientReady = int.MaxValue;
|
|
var order = 0;
|
|
|
|
runtimeProxy.Setup(r => r.InformClientReady()).Returns(new CommunicationResult(true)).Callback(() => clientReady = order);
|
|
|
|
// Startup
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.RegisterEvents)).Callback(() => Assert.AreEqual(1, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.ShowShell)).Callback(() => Assert.AreEqual(2, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.AutoStartApplications)).Callback(() => Assert.AreEqual(3, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.ScheduleIntegrityVerification)).Callback(() => Assert.AreEqual(4, ++order));
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.StartMonitoring)).Callback(() => Assert.AreEqual(5, ++order));
|
|
|
|
// Client Ready
|
|
responsibilities.Setup(r => r.Delegate(ClientTask.VerifySessionIntegrity)).Callback(() => Assert.IsTrue(6 == ++order && clientReady < order));
|
|
|
|
sut.TryStart();
|
|
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.RegisterEvents), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.ShowShell), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.AutoStartApplications), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.ScheduleIntegrityVerification), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.StartMonitoring), Times.Once);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.VerifySessionIntegrity), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustNotDelegateStartupResponsibilitiesOnFailure()
|
|
{
|
|
operationSequence.Setup(o => o.TryPerform()).Returns(OperationResult.Failed);
|
|
|
|
sut.TryStart();
|
|
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.RegisterEvents), Times.Never);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.ShowShell), Times.Never);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.AutoStartApplications), Times.Never);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.ScheduleIntegrityVerification), Times.Never);
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.StartMonitoring), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustNotDelegateClientReadyResponsibilitiesOnFailure()
|
|
{
|
|
runtimeProxy.Setup(r => r.InformClientReady()).Returns(new CommunicationResult(false));
|
|
|
|
sut.TryStart();
|
|
|
|
responsibilities.Verify(r => r.Delegate(ClientTask.VerifySessionIntegrity), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustInformRuntime()
|
|
{
|
|
sut.TryStart();
|
|
|
|
runtimeProxy.Verify(r => r.InformClientReady(), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustPerformOperations()
|
|
{
|
|
sut.TryStart();
|
|
|
|
operationSequence.Verify(o => o.TryPerform(), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustSucceed()
|
|
{
|
|
var success = sut.TryStart();
|
|
|
|
Assert.IsTrue(success);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustHandleCommunicationError()
|
|
{
|
|
runtimeProxy.Setup(r => r.InformClientReady()).Returns(new CommunicationResult(false));
|
|
|
|
var success = sut.TryStart();
|
|
|
|
Assert.IsFalse(success);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustHandleFailure()
|
|
{
|
|
var success = true;
|
|
|
|
operationSequence.Setup(o => o.TryPerform()).Returns(OperationResult.Failed);
|
|
success = sut.TryStart();
|
|
|
|
Assert.IsFalse(success);
|
|
|
|
operationSequence.Setup(o => o.TryPerform()).Returns(OperationResult.Aborted);
|
|
success = sut.TryStart();
|
|
|
|
Assert.IsFalse(success);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Startup_MustUpdateAppConfigForSplashScreen()
|
|
{
|
|
sut.UpdateAppConfig();
|
|
splashScreen.VerifySet(s => s.AppConfig = appConfig, Times.Once);
|
|
}
|
|
}
|
|
}
|