From a0a577991fbca72d507f9204afa9841dfa47d67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20B=C3=BCchel?= Date: Tue, 27 Jul 2021 13:52:49 +0200 Subject: [PATCH] Extended unit tests for client component. --- .../Operations/DisclaimerOperationTests.cs | 189 +++++++++++ .../DisplayMonitorOperationTests.cs | 124 +++++++ .../ProctoringWorkaroundOperationTests.cs | 100 ++++++ .../Operations/RemoteSessionOperationTests.cs | 205 ++++++++++++ .../Operations/ServerOperationTests.cs | 316 ++++++++++++++++++ .../SafeExamBrowser.Runtime.UnitTests.csproj | 13 + 6 files changed, 947 insertions(+) create mode 100644 SafeExamBrowser.Runtime.UnitTests/Operations/DisclaimerOperationTests.cs create mode 100644 SafeExamBrowser.Runtime.UnitTests/Operations/DisplayMonitorOperationTests.cs create mode 100644 SafeExamBrowser.Runtime.UnitTests/Operations/ProctoringWorkaroundOperationTests.cs create mode 100644 SafeExamBrowser.Runtime.UnitTests/Operations/RemoteSessionOperationTests.cs create mode 100644 SafeExamBrowser.Runtime.UnitTests/Operations/ServerOperationTests.cs diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/DisclaimerOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/DisclaimerOperationTests.cs new file mode 100644 index 00000000..da803dbc --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Operations/DisclaimerOperationTests.cs @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using 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 logger; + private AppSettings settings; + private SessionContext context; + + private DisclaimerOperation sut; + + [TestInitialize] + public void Initialize() + { + context = new SessionContext(); + logger = new Mock(); + settings = new AppSettings(); + + context.Next = new SessionConfiguration(); + context.Next.Settings = settings; + sut = new DisclaimerOperation(logger.Object, context); + } + + [TestMethod] + public void Perform_MustShowDisclaimerWhenProctoringEnabled() + { + var disclaimerShown = false; + + settings.Proctoring.Enabled = true; + sut.ActionRequired += (args) => + { + if (args is MessageEventArgs m) + { + disclaimerShown = true; + m.Result = MessageBoxResult.Ok; + } + }; + + var result = sut.Perform(); + + Assert.IsTrue(disclaimerShown); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Perform_MustAbortIfDisclaimerNotConfirmed() + { + var disclaimerShown = false; + + settings.Proctoring.Enabled = true; + sut.ActionRequired += (args) => + { + if (args is MessageEventArgs m) + { + disclaimerShown = true; + m.Result = MessageBoxResult.Cancel; + } + }; + + var result = sut.Perform(); + + Assert.IsTrue(disclaimerShown); + Assert.AreEqual(OperationResult.Aborted, result); + } + + [TestMethod] + public void Perform_MustDoNothingIfProctoringNotEnabled() + { + var disclaimerShown = false; + + settings.Proctoring.Enabled = 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 disclaimerShown = false; + + settings.Proctoring.Enabled = true; + sut.ActionRequired += (args) => + { + if (args is MessageEventArgs m) + { + disclaimerShown = true; + m.Result = MessageBoxResult.Ok; + } + }; + + var result = sut.Repeat(); + + Assert.IsTrue(disclaimerShown); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Repeat_MustAbortIfDisclaimerNotConfirmed() + { + var disclaimerShown = false; + + settings.Proctoring.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; + + settings.Proctoring.Enabled = 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; + + settings.Proctoring.Enabled = true; + 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); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/DisplayMonitorOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/DisplayMonitorOperationTests.cs new file mode 100644 index 00000000..a445f99d --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Operations/DisplayMonitorOperationTests.cs @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using 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 displayMonitor; + private Mock logger; + private AppSettings settings; + private Mock text; + + private DisplayMonitorOperation sut; + + [TestInitialize] + public void Initialize() + { + context = new SessionContext(); + displayMonitor = new Mock(); + logger = new Mock(); + settings = new AppSettings(); + text = new Mock(); + + 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())).Returns(new ValidationResult { IsAllowed = true }); + + var result = sut.Perform(); + + displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny()), Times.Once); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Perform_MustFailIfDisplayConfigurationNotAllowed() + { + var messageShown = false; + + displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny())).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()), Times.Once); + + Assert.IsTrue(messageShown); + Assert.AreEqual(OperationResult.Failed, result); + } + + [TestMethod] + public void Repeat_MustSucceedIfDisplayConfigurationAllowed() + { + displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny())).Returns(new ValidationResult { IsAllowed = true }); + + var result = sut.Repeat(); + + displayMonitor.Verify(m => m.ValidateConfiguration(It.IsAny()), Times.Once); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Repeat_MustFailIfDisplayConfigurationNotAllowed() + { + var messageShown = false; + + displayMonitor.Setup(m => m.ValidateConfiguration(It.IsAny())).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()), 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); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/ProctoringWorkaroundOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/ProctoringWorkaroundOperationTests.cs new file mode 100644 index 00000000..c7f0d3c7 --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Operations/ProctoringWorkaroundOperationTests.cs @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using 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; + +namespace SafeExamBrowser.Runtime.UnitTests.Operations +{ + [TestClass] + public class ProctoringWorkaroundOperationTests + { + private SessionContext context; + private Mock logger; + private AppSettings settings; + private ProctoringWorkaroundOperation sut; + + [TestInitialize] + public void Initialize() + { + context = new SessionContext(); + logger = new Mock(); + settings = new AppSettings(); + + context.Next = new SessionConfiguration(); + context.Next.Settings = settings; + sut = new ProctoringWorkaroundOperation(logger.Object, context); + } + + [TestMethod] + public void Perform_MustSwitchToDisableExplorerShellIfProctoringActive() + { + settings.Proctoring.Enabled = true; + settings.Security.KioskMode = KioskMode.CreateNewDesktop; + + var result = sut.Perform(); + + Assert.AreEqual(KioskMode.DisableExplorerShell, settings.Security.KioskMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Perform_MustDoNothingIfProctoringNotActive() + { + settings.Proctoring.Enabled = false; + settings.Security.KioskMode = KioskMode.None; + + var result = sut.Perform(); + + Assert.AreEqual(KioskMode.None, settings.Security.KioskMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Repeat_MustSwitchToDisableExplorerShellIfProctoringActive() + { + settings.Proctoring.Enabled = true; + settings.Security.KioskMode = KioskMode.CreateNewDesktop; + + var result = sut.Repeat(); + + Assert.AreEqual(KioskMode.DisableExplorerShell, settings.Security.KioskMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Repeat_MustDoNothingIfProctoringNotActive() + { + settings.Proctoring.Enabled = false; + settings.Security.KioskMode = KioskMode.None; + + var result = sut.Repeat(); + + Assert.AreEqual(KioskMode.None, settings.Security.KioskMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Revert_MustDoNothing() + { + settings.Proctoring.Enabled = true; + settings.Security.KioskMode = KioskMode.None; + + var result = sut.Revert(); + + Assert.AreEqual(KioskMode.None, settings.Security.KioskMode); + Assert.AreEqual(OperationResult.Success, result); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/RemoteSessionOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/RemoteSessionOperationTests.cs new file mode 100644 index 00000000..f3824687 --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Operations/RemoteSessionOperationTests.cs @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using 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.SystemComponents.Contracts; + +namespace SafeExamBrowser.Runtime.UnitTests.Operations +{ + [TestClass] + public class RemoteSessionOperationTests + { + private SessionContext context; + private Mock detector; + private Mock logger; + private AppSettings settings; + + private RemoteSessionOperation sut; + + [TestInitialize] + public void Initialize() + { + context = new SessionContext(); + detector = new Mock(); + logger = new Mock(); + 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); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/ServerOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/ServerOperationTests.cs new file mode 100644 index 00000000..4408e3b3 --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Operations/ServerOperationTests.cs @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using 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.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 fileSystem; + private Mock logger; + private Mock server; + private AppSettings settings; + private Mock configuration; + + private ServerOperation sut; + + [TestInitialize] + public void Initialize() + { + configuration = new Mock(); + context = new SessionContext(); + fileSystem = new Mock(); + logger = new Mock(); + server = new Mock(); + settings = new AppSettings(); + + context.Current = new SessionConfiguration(); + context.Current.Settings = new AppSettings(); + context.Next = new SessionConfiguration(); + context.Next.AppConfig = new AppConfig(); + context.Next.Settings = settings; + 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 serverSettings = settings.Server; + + configuration + .Setup(c => c.TryLoadSettings(It.IsAny(), out examSettings, It.IsAny())) + .Returns(LoadStatus.Success); + fileSystem.Setup(f => f.Delete(It.IsAny())).Callback(() => delete = ++counter); + server.Setup(s => s.Connect()).Returns(new ServerResponse(true)).Callback(() => connect = ++counter); + server.Setup(s => s.Initialize(It.IsAny())).Callback(() => initialize = ++counter); + server.Setup(s => s.GetConnectionInfo()).Returns(connection).Callback(() => getConnection = ++counter); + server + .Setup(s => s.GetAvailableExams(It.IsAny())) + .Returns(new ServerResponse>(true, default(IEnumerable))) + .Callback(() => getExams = ++counter); + server + .Setup(s => s.GetConfigurationFor(It.IsAny())) + .Returns(new ServerResponse(true, new Uri("file:///configuration.seb"))) + .Callback(() => getConfiguration = ++counter); + settings.SessionMode = SessionMode.Server; + 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()), Times.Once); + server.Verify(s => s.Connect(), Times.Once); + server.Verify(s => s.Initialize(It.IsAny()), Times.Once); + server.Verify(s => s.GetAvailableExams(It.IsAny()), Times.Once); + server.Verify(s => s.GetConfigurationFor(It.Is(e => e == exam)), Times.Once); + server.Verify(s => s.GetConnectionInfo(), 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(settings, context.Next.Settings); + Assert.AreEqual(OperationResult.Success, result); + Assert.AreEqual(SessionMode.Server, 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(); + + configuration.Setup(c => c.TryLoadSettings(It.IsAny(), out examSettings, It.IsAny())).Returns(LoadStatus.UnexpectedError); + server.Setup(s => s.Connect()).Returns(new ServerResponse(true)); + server.Setup(s => s.Initialize(It.IsAny())); + server.Setup(s => s.GetConnectionInfo()).Returns(connection); + server.Setup(s => s.GetAvailableExams(It.IsAny())).Returns(new ServerResponse>(true, default(IEnumerable))); + server.Setup(s => s.GetConfigurationFor(It.IsAny())).Returns(new ServerResponse(true, new Uri("file:///configuration.seb"))); + settings.SessionMode = SessionMode.Server; + 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()), Times.Once); + server.Verify(s => s.Connect(), Times.Once); + server.Verify(s => s.Initialize(It.IsAny()), Times.Once); + server.Verify(s => s.GetAvailableExams(It.IsAny()), Times.Once); + server.Verify(s => s.GetConfigurationFor(It.Is(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(settings, 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(), out examSettings, It.IsAny())).Returns(LoadStatus.Success); + server.Setup(s => s.Connect()).Returns(new ServerResponse(true)); + server.Setup(s => s.Initialize(It.IsAny())); + server.Setup(s => s.GetConnectionInfo()).Returns(connection); + server.Setup(s => s.GetAvailableExams(It.IsAny())).Returns(new ServerResponse>(true, default(IEnumerable))); + server.Setup(s => s.GetConfigurationFor(It.IsAny())).Returns(new ServerResponse(false, default(Uri))); + settings.SessionMode = SessionMode.Server; + 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()), Times.Never); + server.Verify(s => s.Connect(), Times.Once); + server.Verify(s => s.Initialize(It.IsAny()), Times.Once); + server.Verify(s => s.GetAvailableExams(It.IsAny()), Times.Once); + server.Verify(s => s.GetConfigurationFor(It.Is(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(), out examSettings, It.IsAny())).Returns(LoadStatus.Success); + server.Setup(s => s.Connect()).Returns(new ServerResponse(true)); + server.Setup(s => s.Initialize(It.IsAny())); + server.Setup(s => s.GetConnectionInfo()).Returns(connection); + server.Setup(s => s.GetAvailableExams(It.IsAny())).Returns(new ServerResponse>(true, default(IEnumerable))); + server.Setup(s => s.GetConfigurationFor(It.IsAny())).Returns(new ServerResponse(false, default(Uri))); + settings.SessionMode = SessionMode.Server; + 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()), Times.Never); + server.Verify(s => s.Connect(), Times.Once); + server.Verify(s => s.Initialize(It.IsAny()), Times.Once); + server.Verify(s => s.GetAvailableExams(It.IsAny()), Times.Once); + server.Verify(s => s.GetConfigurationFor(It.Is(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_MustDoNothingIfNormalSession() + { + var eventFired = false; + + settings.SessionMode = SessionMode.Normal; + sut.ActionRequired += (_) => eventFired = true; + + var result = sut.Perform(); + + configuration.VerifyNoOtherCalls(); + fileSystem.VerifyNoOtherCalls(); + server.VerifyNoOtherCalls(); + + Assert.IsFalse(eventFired); + Assert.AreSame(settings, context.Next.Settings); + Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Repeat_MustDoNothingIfNormalSession() + { + var eventFired = false; + + context.Current.Settings.SessionMode = SessionMode.Normal; + settings.SessionMode = SessionMode.Normal; + sut.ActionRequired += (_) => eventFired = true; + + var result = sut.Repeat(); + + configuration.VerifyNoOtherCalls(); + fileSystem.VerifyNoOtherCalls(); + server.VerifyNoOtherCalls(); + + Assert.IsFalse(eventFired); + Assert.AreSame(settings, context.Next.Settings); + Assert.AreEqual(SessionMode.Normal, context.Next.Settings.SessionMode); + Assert.AreEqual(OperationResult.Success, result); + } + + [TestMethod] + public void Revert_MustDoNothingIfNormalSession() + { + var eventFired = false; + + context.Current.Settings.SessionMode = SessionMode.Normal; + sut.ActionRequired += (_) => eventFired = true; + + var result = sut.Revert(); + + configuration.VerifyNoOtherCalls(); + fileSystem.VerifyNoOtherCalls(); + server.VerifyNoOtherCalls(); + + Assert.IsFalse(eventFired); + Assert.AreEqual(OperationResult.Success, result); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj b/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj index a126aa86..dbf60010 100644 --- a/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj +++ b/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj @@ -85,7 +85,12 @@ + + + + + @@ -132,10 +137,18 @@ {64ea30fb-11d4-436a-9c2b-88566285363e} SafeExamBrowser.Logging.Contracts + + {6d563a30-366d-4c35-815b-2c9e6872278b} + SafeExamBrowser.Monitoring.Contracts + {e3aed2f8-b5df-45d1-ac19-48066923d6d8} SafeExamBrowser.Runtime + + {db701e6f-bddc-4cec-b662-335a9dc11809} + SafeExamBrowser.Server.Contracts + {30b2d907-5861-4f39-abad-c4abf1b3470e} SafeExamBrowser.Settings