Restore SEBPatch
This commit is contained in:
1367
SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs
Normal file
1367
SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Client.Communication;
|
||||
using SafeExamBrowser.Communication.Contracts;
|
||||
using SafeExamBrowser.Communication.Contracts.Data;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Communication
|
||||
{
|
||||
[TestClass]
|
||||
public class ClientHostTests
|
||||
{
|
||||
private const int PROCESS_ID = 1234;
|
||||
|
||||
private Mock<IConfigurationRepository> configuration;
|
||||
private Mock<IHostObject> hostObject;
|
||||
private Mock<IHostObjectFactory> hostObjectFactory;
|
||||
private Mock<ILogger> logger;
|
||||
private ClientHost sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
configuration = new Mock<IConfigurationRepository>();
|
||||
hostObject = new Mock<IHostObject>();
|
||||
hostObjectFactory = new Mock<IHostObjectFactory>();
|
||||
logger = new Mock<ILogger>();
|
||||
|
||||
hostObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>(), It.IsAny<ICommunication>())).Returns(hostObject.Object);
|
||||
|
||||
sut = new ClientHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, PROCESS_ID, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOnlyAllowConnectionIfTokenIsValid()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsTrue(response.ConnectionEstablished);
|
||||
Assert.IsTrue(sut.IsConnected);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void MustRejectConnectionIfTokenInvalid()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(Guid.NewGuid());
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsFalse(response.ConnectionEstablished);
|
||||
Assert.IsFalse(sut.IsConnected);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOnlyAllowOneConcurrentConnection()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response1 = sut.Connect(token);
|
||||
var response2 = sut.Connect(token);
|
||||
var response3 = sut.Connect(token);
|
||||
|
||||
Assert.IsNotNull(response1);
|
||||
Assert.IsNotNull(response2);
|
||||
Assert.IsNotNull(response3);
|
||||
Assert.IsNotNull(response1.CommunicationToken);
|
||||
Assert.IsNull(response2.CommunicationToken);
|
||||
Assert.IsNull(response3.CommunicationToken);
|
||||
Assert.IsTrue(response1.ConnectionEstablished);
|
||||
Assert.IsFalse(response2.ConnectionEstablished);
|
||||
Assert.IsFalse(response3.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyDisconnect()
|
||||
{
|
||||
var eventFired = false;
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.RuntimeDisconnected += () => eventFired = true;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var connectionResponse = sut.Connect(token);
|
||||
var message = new DisconnectionMessage
|
||||
{
|
||||
CommunicationToken = connectionResponse.CommunicationToken.Value,
|
||||
Interlocutor = Interlocutor.Runtime
|
||||
};
|
||||
var response = sut.Disconnect(message);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsTrue(response.ConnectionTerminated);
|
||||
Assert.IsTrue(eventFired);
|
||||
Assert.IsFalse(sut.IsConnected);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustNotAllowReconnectionAfterDisconnection()
|
||||
{
|
||||
var token = sut.AuthenticationToken = Guid.NewGuid();
|
||||
var response = sut.Connect(token);
|
||||
var message = new DisconnectionMessage
|
||||
{
|
||||
CommunicationToken = response.CommunicationToken.Value,
|
||||
Interlocutor = Interlocutor.Runtime
|
||||
};
|
||||
|
||||
sut.Disconnect(message);
|
||||
sut.AuthenticationToken = token = Guid.NewGuid();
|
||||
|
||||
response = sut.Connect(token);
|
||||
|
||||
Assert.IsFalse(response.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleAuthenticationRequestCorrectly()
|
||||
{
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.Authenticate) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(AuthenticationResponse));
|
||||
Assert.AreEqual(PROCESS_ID, (response as AuthenticationResponse)?.ProcessId);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleExamSelectionRequestCorrectly()
|
||||
{
|
||||
var examSelectionRequested = false;
|
||||
var requestId = Guid.NewGuid();
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
|
||||
sut.ExamSelectionRequested += (args) =>
|
||||
{
|
||||
examSelectionRequested = true;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var request = new ExamSelectionRequestMessage(Enumerable.Empty<(string id, string lms, string name, string url)>(), requestId) { CommunicationToken = token };
|
||||
var response = sut.Send(request);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(examSelectionRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleMessageBoxRequestCorrectly()
|
||||
{
|
||||
var action = (int) MessageBoxAction.YesNo;
|
||||
var icon = (int) MessageBoxIcon.Question;
|
||||
var message = "Qwert kndorz safie abcd?";
|
||||
var messageBoxRequested = false;
|
||||
var requestId = Guid.NewGuid();
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
var title = "Poiuztrewq!";
|
||||
|
||||
sut.MessageBoxRequested += (args) =>
|
||||
{
|
||||
messageBoxRequested = args.Action == action && args.Icon == icon && args.Message == message && args.RequestId == requestId && args.Title == title;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var request = new MessageBoxRequestMessage(action, icon, message, requestId, title) { CommunicationToken = token };
|
||||
var response = sut.Send(request);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(messageBoxRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandlePasswordRequestCorrectly()
|
||||
{
|
||||
var passwordRequested = false;
|
||||
var purpose = PasswordRequestPurpose.LocalAdministrator;
|
||||
var requestId = Guid.NewGuid();
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
|
||||
sut.PasswordRequested += (args) =>
|
||||
{
|
||||
passwordRequested = args.Purpose == purpose && args.RequestId == requestId;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new PasswordRequestMessage(purpose, requestId) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(passwordRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleReconfigurationAbortionCorrectly()
|
||||
{
|
||||
var reconfigurationAborted = false;
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
|
||||
sut.ReconfigurationAborted += () =>
|
||||
{
|
||||
reconfigurationAborted = true;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.ReconfigurationAborted) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(reconfigurationAborted);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleReconfigurationDenialCorrectly()
|
||||
{
|
||||
var filePath = @"C:\Some\Random\Path\To\A\File.seb";
|
||||
var reconfigurationDenied = false;
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
|
||||
sut.ReconfigurationDenied += (args) =>
|
||||
{
|
||||
reconfigurationDenied = new Uri(args.ConfigurationPath).Equals(new Uri(filePath));
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new ReconfigurationDeniedMessage(filePath) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(reconfigurationDenied);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleServerFailureCorrectly()
|
||||
{
|
||||
var serverFailureActionRequested = false;
|
||||
var requestId = Guid.NewGuid();
|
||||
var resetEvent = new AutoResetEvent(false);
|
||||
|
||||
sut.ServerFailureActionRequested += (args) =>
|
||||
{
|
||||
serverFailureActionRequested = true;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var request = new ServerFailureActionRequestMessage("", true, requestId) { CommunicationToken = token };
|
||||
var response = sut.Send(request);
|
||||
|
||||
resetEvent.WaitOne();
|
||||
|
||||
Assert.IsTrue(serverFailureActionRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleShutdownRequestCorrectly()
|
||||
{
|
||||
var shutdownRequested = false;
|
||||
|
||||
sut.Shutdown += () => shutdownRequested = true;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.Shutdown) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
Assert.IsTrue(shutdownRequested);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustReturnUnknownMessageAsDefault()
|
||||
{
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new TestMessage { CommunicationToken = token } as Message;
|
||||
var response = sut.Send(message);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.UnknownMessage, (response as SimpleResponse)?.Purport);
|
||||
|
||||
message = new SimpleMessage(default(SimpleMessagePurport)) { CommunicationToken = token };
|
||||
response = sut.Send(message);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.UnknownMessage, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustNotFailIfNoEventHandlersSubscribed()
|
||||
{
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
|
||||
sut.Send(new MessageBoxRequestMessage(default(int), default(int), "", Guid.Empty, "") { CommunicationToken = token });
|
||||
sut.Send(new PasswordRequestMessage(default(PasswordRequestPurpose), Guid.Empty) { CommunicationToken = token });
|
||||
sut.Send(new SimpleMessage(SimpleMessagePurport.ReconfigurationAborted));
|
||||
sut.Send(new ReconfigurationDeniedMessage("") { CommunicationToken = token });
|
||||
sut.Send(new SimpleMessage(SimpleMessagePurport.Shutdown) { CommunicationToken = token });
|
||||
sut.Disconnect(new DisconnectionMessage { CommunicationToken = token, Interlocutor = Interlocutor.Runtime });
|
||||
}
|
||||
|
||||
private class TestMessage : Message { };
|
||||
}
|
||||
}
|
118
SafeExamBrowser.Client.UnitTests/CoordinatorTests.cs
Normal file
118
SafeExamBrowser.Client.UnitTests/CoordinatorTests.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests
|
||||
{
|
||||
[TestClass]
|
||||
public class CoordinatorTests
|
||||
{
|
||||
private Coordinator sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
sut = new Coordinator();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReconfigurationLock_MustWorkCorrectly()
|
||||
{
|
||||
Assert.IsFalse(sut.IsReconfigurationLocked());
|
||||
|
||||
sut.RequestReconfigurationLock();
|
||||
|
||||
var result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
Assert.IsTrue(sut.IsReconfigurationLocked());
|
||||
Assert.IsFalse(sut.RequestReconfigurationLock());
|
||||
});
|
||||
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
|
||||
result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
sut.ReleaseReconfigurationLock();
|
||||
});
|
||||
|
||||
Assert.IsFalse(sut.IsReconfigurationLocked());
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RequestReconfigurationLock_MustOnlyAllowLockingOnce()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
Assert.IsFalse(sut.IsReconfigurationLocked());
|
||||
|
||||
var result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
var acquired = sut.RequestReconfigurationLock();
|
||||
|
||||
if (acquired)
|
||||
{
|
||||
Interlocked.Increment(ref count);
|
||||
}
|
||||
});
|
||||
|
||||
Assert.AreEqual(1, count);
|
||||
Assert.IsTrue(sut.IsReconfigurationLocked());
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RequestSessionLock_MustOnlyAllowLockingOnce()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
Assert.IsFalse(sut.IsSessionLocked());
|
||||
|
||||
var result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
var acquired = sut.RequestSessionLock();
|
||||
|
||||
if (acquired)
|
||||
{
|
||||
Interlocked.Increment(ref count);
|
||||
}
|
||||
});
|
||||
|
||||
Assert.AreEqual(1, count);
|
||||
Assert.IsTrue(sut.IsSessionLocked());
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SessionLock_MustWorkCorrectly()
|
||||
{
|
||||
Assert.IsFalse(sut.IsSessionLocked());
|
||||
|
||||
sut.RequestSessionLock();
|
||||
|
||||
var result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
Assert.IsTrue(sut.IsSessionLocked());
|
||||
Assert.IsFalse(sut.RequestSessionLock());
|
||||
});
|
||||
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
|
||||
result = Parallel.For(1, 1000, (_) =>
|
||||
{
|
||||
sut.ReleaseSessionLock();
|
||||
});
|
||||
|
||||
Assert.IsFalse(sut.IsSessionLocked());
|
||||
Assert.IsTrue(result.IsCompleted);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.IO.Packaging;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Client.Notifications;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Notifications
|
||||
{
|
||||
[TestClass]
|
||||
public class AboutNotificationControllerTests
|
||||
{
|
||||
private Mock<AppConfig> appConfig;
|
||||
private Mock<IText> text;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new Mock<AppConfig>();
|
||||
text = new Mock<IText>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
// Ensure that the pack scheme is known before executing the unit tests, see https://stackoverflow.com/a/6005606
|
||||
_ = PackUriHelper.UriSchemePack;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCloseWindowWhenTerminating()
|
||||
{
|
||||
var window = new Mock<IWindow>();
|
||||
var sut = new AboutNotification(appConfig.Object, text.Object, uiFactory.Object);
|
||||
|
||||
uiFactory.Setup(u => u.CreateAboutWindow(It.IsAny<AppConfig>())).Returns(window.Object);
|
||||
|
||||
sut.Activate();
|
||||
sut.Terminate();
|
||||
|
||||
window.Verify(w => w.Close());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOpenOnlyOneWindow()
|
||||
{
|
||||
var window = new Mock<IWindow>();
|
||||
var sut = new AboutNotification(appConfig.Object, text.Object, uiFactory.Object);
|
||||
|
||||
uiFactory.Setup(u => u.CreateAboutWindow(It.IsAny<AppConfig>())).Returns(window.Object);
|
||||
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
|
||||
uiFactory.Verify(u => u.CreateAboutWindow(It.IsAny<AppConfig>()), Times.Once);
|
||||
window.Verify(u => u.Show(), Times.Once);
|
||||
window.Verify(u => u.BringToForeground(), Times.Exactly(4));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustNotFailToTerminateIfNotStarted()
|
||||
{
|
||||
var sut = new AboutNotification(appConfig.Object, text.Object, uiFactory.Object);
|
||||
|
||||
sut.Terminate();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.IO.Packaging;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Client.Notifications;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Notifications
|
||||
{
|
||||
[TestClass]
|
||||
public class LogNotificationControllerTests
|
||||
{
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IText> text;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
logger = new Mock<ILogger>();
|
||||
text = new Mock<IText>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
// Ensure that the pack scheme is known before executing the unit tests, see https://stackoverflow.com/a/6005606
|
||||
_ = PackUriHelper.UriSchemePack;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCloseWindowWhenTerminating()
|
||||
{
|
||||
var window = new Mock<IWindow>();
|
||||
var sut = new LogNotification(logger.Object, text.Object, uiFactory.Object);
|
||||
|
||||
uiFactory.Setup(u => u.CreateLogWindow(It.IsAny<ILogger>())).Returns(window.Object);
|
||||
|
||||
sut.Activate();
|
||||
sut.Terminate();
|
||||
|
||||
window.Verify(w => w.Close());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOpenOnlyOneWindow()
|
||||
{
|
||||
var window = new Mock<IWindow>();
|
||||
var sut = new LogNotification(logger.Object, text.Object, uiFactory.Object);
|
||||
|
||||
uiFactory.Setup(u => u.CreateLogWindow(It.IsAny<ILogger>())).Returns(window.Object);
|
||||
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
sut.Activate();
|
||||
|
||||
uiFactory.Verify(u => u.CreateLogWindow(It.IsAny<ILogger>()), Times.Once);
|
||||
window.Verify(u => u.Show(), Times.Once);
|
||||
window.Verify(u => u.BringToForeground(), Times.Exactly(4));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustNotFailToTerminateIfNotStarted()
|
||||
{
|
||||
var sut = new LogNotification(logger.Object, text.Object, uiFactory.Object);
|
||||
|
||||
sut.Terminate();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* 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.Applications.Contracts;
|
||||
using SafeExamBrowser.Client.Operations;
|
||||
using SafeExamBrowser.Client.Operations.Events;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Applications;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Applications;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ApplicationOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<IApplicationFactory> factory;
|
||||
private Mock<IApplicationMonitor> monitor;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IText> text;
|
||||
|
||||
private ApplicationOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
factory = new Mock<IApplicationFactory>();
|
||||
monitor = new Mock<IApplicationMonitor>();
|
||||
logger = new Mock<ILogger>();
|
||||
text = new Mock<IText>();
|
||||
|
||||
context.Settings = new AppSettings();
|
||||
|
||||
sut = new ApplicationOperation(context, factory.Object, monitor.Object, logger.Object, text.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfUserDeniesAutoTermination()
|
||||
{
|
||||
var initialization = new InitializationResult();
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
initialization.RunningApplications.Add(new RunningApplication(default));
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(initialization);
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
|
||||
if (a is ApplicationTerminationEventArgs t)
|
||||
{
|
||||
t.TerminateProcesses = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Initialize(It.Is<ApplicationSettings>(s => s == context.Settings.Applications)), Times.Once);
|
||||
monitor.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationTerminationEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfUserCancelsApplicationLocationSelection()
|
||||
{
|
||||
var application = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var applicationSettings = new WhitelistApplication { AllowCustomPath = true };
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
context.Settings.Applications.Whitelist.Add(applicationSettings);
|
||||
factory.Setup(f => f.TryCreate(It.IsAny<WhitelistApplication>(), out application)).Returns(FactoryResult.NotFound);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
|
||||
if (a is ApplicationNotFoundEventArgs n)
|
||||
{
|
||||
n.Success = false;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == applicationSettings), out application), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationInitializationFailedEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAllowUserToChooseApplicationLocation()
|
||||
{
|
||||
var application = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var applicationSettings = new WhitelistApplication { AllowCustomPath = true };
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
var attempt = 0;
|
||||
var correct = new Random().Next(2, 50);
|
||||
var factoryResult = new Func<FactoryResult>(() => ++attempt == correct ? FactoryResult.Success : FactoryResult.NotFound);
|
||||
|
||||
context.Settings.Applications.Whitelist.Add(applicationSettings);
|
||||
factory.Setup(f => f.TryCreate(It.IsAny<WhitelistApplication>(), out application)).Returns(factoryResult);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
|
||||
if (a is ApplicationNotFoundEventArgs n)
|
||||
{
|
||||
n.Success = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == applicationSettings), out application), Times.Exactly(correct));
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationNotFoundEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDenyApplicationLocationSelection()
|
||||
{
|
||||
var application = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var applicationSettings = new WhitelistApplication { AllowCustomPath = false };
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
context.Settings.Applications.Whitelist.Add(applicationSettings);
|
||||
factory.Setup(f => f.TryCreate(It.IsAny<WhitelistApplication>(), out application)).Returns(FactoryResult.NotFound);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
|
||||
if (a is ApplicationNotFoundEventArgs)
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == applicationSettings), out application), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationInitializationFailedEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfAutoTerminationFails()
|
||||
{
|
||||
var initialization = new InitializationResult();
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
initialization.FailedAutoTerminations.Add(new RunningApplication(default));
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(initialization);
|
||||
sut.ActionRequired += (a) => args = a;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Initialize(It.Is<ApplicationSettings>(s => s == context.Settings.Applications)), Times.Once);
|
||||
monitor.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationTerminationFailedEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustFailIfTerminationFails()
|
||||
{
|
||||
var application = new RunningApplication(default);
|
||||
var initialization = new InitializationResult();
|
||||
var args = new List<ActionRequiredEventArgs>();
|
||||
|
||||
initialization.RunningApplications.Add(application);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(initialization);
|
||||
monitor.Setup(m => m.TryTerminate(It.IsAny<RunningApplication>())).Returns(false);
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args.Add(a);
|
||||
|
||||
if (a is ApplicationTerminationEventArgs t)
|
||||
{
|
||||
t.TerminateProcesses = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Initialize(It.Is<ApplicationSettings>(s => s == context.Settings.Applications)), Times.Once);
|
||||
monitor.Verify(m => m.TryTerminate(It.Is<RunningApplication>(a => a == application)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsInstanceOfType(args[0], typeof(ApplicationTerminationEventArgs));
|
||||
Assert.IsInstanceOfType(args[1], typeof(ApplicationTerminationFailedEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustIndicateApplicationInitializationFailure()
|
||||
{
|
||||
var application = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var applicationSettings = new WhitelistApplication();
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
context.Settings.Applications.Whitelist.Add(applicationSettings);
|
||||
factory.Setup(f => f.TryCreate(It.IsAny<WhitelistApplication>(), out application)).Returns(FactoryResult.Error);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
sut.ActionRequired += (a) => args = a;
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == applicationSettings), out application), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationInitializationFailedEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeApplications()
|
||||
{
|
||||
var application1 = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var application2 = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var application3 = new Mock<IApplication<IApplicationWindow>>().Object;
|
||||
var application1Settings = new WhitelistApplication();
|
||||
var application2Settings = new WhitelistApplication();
|
||||
var application3Settings = new WhitelistApplication();
|
||||
|
||||
context.Settings.Applications.Whitelist.Add(application1Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application2Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application3Settings);
|
||||
factory.Setup(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application1Settings), out application1)).Returns(FactoryResult.Success);
|
||||
factory.Setup(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application2Settings), out application2)).Returns(FactoryResult.Success);
|
||||
factory.Setup(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application3Settings), out application3)).Returns(FactoryResult.Success);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application1Settings), out application1), Times.Once);
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application1Settings), out application2), Times.Once);
|
||||
factory.Verify(f => f.TryCreate(It.Is<WhitelistApplication>(a => a == application1Settings), out application3), Times.Once);
|
||||
monitor.Verify(m => m.Initialize(It.Is<ApplicationSettings>(s => s == context.Settings.Applications)), Times.Once);
|
||||
monitor.Verify(m => m.TryTerminate(It.IsAny<RunningApplication>()), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotStartMonitorWithoutKioskMode()
|
||||
{
|
||||
context.Settings.Security.KioskMode = KioskMode.None;
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Start(), Times.Never);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustStartMonitorWithKioskMode()
|
||||
{
|
||||
context.Settings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Start(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Settings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
monitor.Reset();
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(new InitializationResult());
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Start(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustTerminateRunningApplications()
|
||||
{
|
||||
var application1 = new RunningApplication(default);
|
||||
var application2 = new RunningApplication(default);
|
||||
var application3 = new RunningApplication(default);
|
||||
var initialization = new InitializationResult();
|
||||
var args = default(ActionRequiredEventArgs);
|
||||
|
||||
initialization.RunningApplications.Add(application1);
|
||||
initialization.RunningApplications.Add(application2);
|
||||
initialization.RunningApplications.Add(application3);
|
||||
monitor.Setup(m => m.Initialize(It.IsAny<ApplicationSettings>())).Returns(initialization);
|
||||
monitor.Setup(m => m.TryTerminate(It.IsAny<RunningApplication>())).Returns(true);
|
||||
sut.ActionRequired += (a) =>
|
||||
{
|
||||
args = a;
|
||||
|
||||
if (a is ApplicationTerminationEventArgs t)
|
||||
{
|
||||
t.TerminateProcesses = true;
|
||||
}
|
||||
};
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
monitor.Verify(m => m.Initialize(It.Is<ApplicationSettings>(s => s == context.Settings.Applications)), Times.Once);
|
||||
monitor.Verify(m => m.TryTerminate(It.Is<RunningApplication>(a => a == application1)), Times.Once);
|
||||
monitor.Verify(m => m.TryTerminate(It.Is<RunningApplication>(a => a == application2)), Times.Once);
|
||||
monitor.Verify(m => m.TryTerminate(It.Is<RunningApplication>(a => a == application3)), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.IsInstanceOfType(args, typeof(ApplicationTerminationEventArgs));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotStopMonitorWithoutKioskMode()
|
||||
{
|
||||
context.Settings.Security.KioskMode = KioskMode.None;
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
monitor.Verify(m => m.Stop(), Times.Never);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustStopMonitorWithKioskMode()
|
||||
{
|
||||
context.Settings.Security.KioskMode = KioskMode.CreateNewDesktop;
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
monitor.Verify(m => m.Stop(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Settings.Security.KioskMode = KioskMode.DisableExplorerShell;
|
||||
monitor.Reset();
|
||||
|
||||
result = sut.Revert();
|
||||
|
||||
monitor.Verify(m => m.Stop(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustTerminateApplications()
|
||||
{
|
||||
var application1 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application2 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application3 = new Mock<IApplication<IApplicationWindow>>();
|
||||
|
||||
context.Applications.Add(application1.Object);
|
||||
context.Applications.Add(application2.Object);
|
||||
context.Applications.Add(application3.Object);
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
application1.Verify(a => a.Terminate(), Times.Once);
|
||||
application2.Verify(a => a.Terminate(), Times.Once);
|
||||
application3.Verify(a => a.Terminate(), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.Applications.Contracts;
|
||||
using SafeExamBrowser.Browser.Contracts;
|
||||
using SafeExamBrowser.Client.Operations;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class BrowserOperationTests
|
||||
{
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private Mock<IBrowserApplication> browser;
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private AppSettings settings;
|
||||
private Mock<ITaskbar> taskbar;
|
||||
private Mock<ITaskview> taskview;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
|
||||
private BrowserOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
browser = new Mock<IBrowserApplication>();
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
settings = new AppSettings();
|
||||
taskbar = new Mock<ITaskbar>();
|
||||
taskview = new Mock<ITaskview>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
context.Browser = browser.Object;
|
||||
context.Settings = settings;
|
||||
|
||||
sut = new BrowserOperation(actionCenter.Object, context, logger.Object, taskbar.Object, taskview.Object, uiFactory.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeBrowserAndTaskview()
|
||||
{
|
||||
settings.Browser.EnableBrowser = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
browser.Verify(c => c.Initialize(), Times.Once);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == context.Browser)), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeBrowserIfNotEnabled()
|
||||
{
|
||||
settings.Browser.EnableBrowser = false;
|
||||
settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Never);
|
||||
browser.Verify(c => c.Initialize(), Times.Never);
|
||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Never);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == context.Browser)), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeControls()
|
||||
{
|
||||
settings.Browser.EnableBrowser = true;
|
||||
settings.UserInterface.ActionCenter.EnableActionCenter = false;
|
||||
settings.UserInterface.Taskbar.EnableTaskbar = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Never);
|
||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Never);
|
||||
|
||||
settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Once);
|
||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>(), true), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustTerminateBrowser()
|
||||
{
|
||||
settings.Browser.EnableBrowser = true;
|
||||
sut.Revert();
|
||||
browser.Verify(c => c.Terminate(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustNotTerminateBrowserIfNotEnabled()
|
||||
{
|
||||
settings.Browser.EnableBrowser = false;
|
||||
sut.Revert();
|
||||
browser.Verify(c => c.Terminate(), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Communication.Contracts.Events;
|
||||
using SafeExamBrowser.Communication.Contracts.Hosts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ClientHostDisconnectionOperationTests
|
||||
{
|
||||
private Mock<IClientHost> clientHost;
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
|
||||
private ClientHostDisconnectionOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
clientHost = new Mock<IClientHost>();
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
|
||||
context.ClientHost = clientHost.Object;
|
||||
|
||||
sut = new ClientHostDisconnectionOperation(context, logger.Object, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustWaitForDisconnectionIfConnectionIsActive()
|
||||
{
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
var timeout_ms = 200;
|
||||
|
||||
sut = new ClientHostDisconnectionOperation(context, logger.Object, timeout_ms);
|
||||
|
||||
clientHost.SetupGet(h => h.IsConnected).Returns(true).Callback(() => Task.Delay(10).ContinueWith((_) =>
|
||||
{
|
||||
clientHost.Raise(h => h.RuntimeDisconnected += null);
|
||||
}));
|
||||
|
||||
before = DateTime.Now;
|
||||
sut.Revert();
|
||||
after = DateTime.Now;
|
||||
|
||||
clientHost.VerifyGet(h => h.IsConnected);
|
||||
clientHost.VerifyAdd(h => h.RuntimeDisconnected += It.IsAny<CommunicationEventHandler>());
|
||||
clientHost.VerifyRemove(h => h.RuntimeDisconnected -= It.IsAny<CommunicationEventHandler>());
|
||||
clientHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.IsTrue(after - before < new TimeSpan(0, 0, 0, 0, timeout_ms));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustRespectTimeoutIfWaitingForDisconnection()
|
||||
{
|
||||
var after = default(DateTime);
|
||||
var before = default(DateTime);
|
||||
var timeout_ms = 200;
|
||||
|
||||
sut = new ClientHostDisconnectionOperation(context, logger.Object, timeout_ms);
|
||||
|
||||
clientHost.SetupGet(h => h.IsConnected).Returns(true);
|
||||
|
||||
before = DateTime.Now;
|
||||
sut.Revert();
|
||||
after = DateTime.Now;
|
||||
|
||||
clientHost.VerifyGet(h => h.IsConnected);
|
||||
clientHost.VerifyAdd(h => h.RuntimeDisconnected += It.IsAny<CommunicationEventHandler>());
|
||||
clientHost.VerifyRemove(h => h.RuntimeDisconnected -= It.IsAny<CommunicationEventHandler>());
|
||||
clientHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, timeout_ms));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingIfNoConnectionIsActive()
|
||||
{
|
||||
clientHost.SetupGet(h => h.IsConnected).Returns(false);
|
||||
|
||||
sut.Revert();
|
||||
|
||||
clientHost.VerifyGet(h => h.IsConnected);
|
||||
clientHost.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnPerform()
|
||||
{
|
||||
var result = sut.Perform();
|
||||
|
||||
clientHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ClipboardOperationTests
|
||||
{
|
||||
private Mock<IClipboard> clipboard;
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> loggerMock;
|
||||
|
||||
private ClipboardOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
clipboard = new Mock<IClipboard>();
|
||||
context = new ClientContext();
|
||||
context.Settings = new AppSettings();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
|
||||
sut = new ClipboardOperation(context, clipboard.Object, loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustPerformCorrectly()
|
||||
{
|
||||
sut.Perform();
|
||||
clipboard.Verify(n => n.Initialize(It.IsAny<ClipboardPolicy>()), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustRevertCorrectly()
|
||||
{
|
||||
sut.Revert();
|
||||
clipboard.Verify(n => n.Terminate(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Communication.Contracts.Data;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ConfigurationOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeProxy> runtime;
|
||||
private ConfigurationOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
runtime = new Mock<IRuntimeProxy>();
|
||||
|
||||
sut = new ConfigurationOperation(context, logger.Object, runtime.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySetConfiguration()
|
||||
{
|
||||
var response = new ConfigurationResponse
|
||||
{
|
||||
Configuration = new ClientConfiguration
|
||||
{
|
||||
AppConfig = new AppConfig(),
|
||||
SessionId = Guid.NewGuid(),
|
||||
Settings = new AppSettings()
|
||||
}
|
||||
};
|
||||
|
||||
runtime.Setup(r => r.GetConfiguration()).Returns(new CommunicationResult<ConfigurationResponse>(true, response));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
Assert.AreSame(context.AppConfig, response.Configuration.AppConfig);
|
||||
Assert.AreEqual(context.SessionId, response.Configuration.SessionId);
|
||||
Assert.AreSame(context.Settings, response.Configuration.Settings);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnRevert()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
logger.VerifyNoOtherCalls();
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Client.Operations;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Display;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class DisplayMonitorOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<IDisplayMonitor> displayMonitor;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<ITaskbar> taskbar;
|
||||
|
||||
private DisplayMonitorOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
displayMonitor = new Mock<IDisplayMonitor>();
|
||||
logger = new Mock<ILogger>();
|
||||
taskbar = new Mock<ITaskbar>();
|
||||
|
||||
sut = new DisplayMonitorOperation(context, displayMonitor.Object, logger.Object, taskbar.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustExecuteInCorrectOrder()
|
||||
{
|
||||
var order = 0;
|
||||
|
||||
context.Settings = new AppSettings();
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
|
||||
displayMonitor.Setup(d => d.InitializePrimaryDisplay(It.IsAny<int>())).Callback(() => Assert.AreEqual(++order, 1));
|
||||
displayMonitor.Setup(d => d.StartMonitoringDisplayChanges()).Callback(() => Assert.AreEqual(++order, 2));
|
||||
|
||||
sut.Perform();
|
||||
|
||||
displayMonitor.Verify(d => d.InitializePrimaryDisplay(It.IsAny<int>()), Times.Once);
|
||||
displayMonitor.Verify(d => d.StartMonitoringDisplayChanges(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeDisplayWithTaskbar()
|
||||
{
|
||||
var height = 25;
|
||||
|
||||
context.Settings = new AppSettings();
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
taskbar.Setup(t => t.GetAbsoluteHeight()).Returns(height);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
displayMonitor.Verify(d => d.InitializePrimaryDisplay(It.Is<int>(h => h == height)), Times.Once);
|
||||
displayMonitor.Verify(d => d.InitializePrimaryDisplay(It.Is<int>(h => h == 0)), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustCorrectlyInitializeDisplayWithoutTaskbar()
|
||||
{
|
||||
var height = 25;
|
||||
|
||||
context.Settings = new AppSettings();
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = false;
|
||||
taskbar.Setup(t => t.GetAbsoluteHeight()).Returns(height);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
displayMonitor.Verify(d => d.InitializePrimaryDisplay(It.Is<int>(h => h == height)), Times.Never);
|
||||
displayMonitor.Verify(d => d.InitializePrimaryDisplay(It.Is<int>(h => h == 0)), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustExecuteInCorrectOrder()
|
||||
{
|
||||
var order = 0;
|
||||
|
||||
displayMonitor.Setup(d => d.StopMonitoringDisplayChanges()).Callback(() => Assert.AreEqual(++order, 1));
|
||||
displayMonitor.Setup(d => d.ResetPrimaryDisplay()).Callback(() => Assert.AreEqual(++order, 2));
|
||||
|
||||
sut.Revert();
|
||||
|
||||
displayMonitor.Verify(d => d.StopMonitoringDisplayChanges(), Times.Once);
|
||||
displayMonitor.Verify(d => d.ResetPrimaryDisplay(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Keyboard;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class KeyboardInterceptorOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<IKeyboardInterceptor> keyboardInterceptorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
|
||||
private KeyboardInterceptorOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
keyboardInterceptorMock = new Mock<IKeyboardInterceptor>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
|
||||
sut = new KeyboardInterceptorOperation(context, keyboardInterceptorMock.Object, loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustPerformCorrectly()
|
||||
{
|
||||
sut.Perform();
|
||||
|
||||
keyboardInterceptorMock.Verify(i => i.Start(), Times.Once);
|
||||
keyboardInterceptorMock.Verify(i => i.Stop(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustRevertCorrectly()
|
||||
{
|
||||
sut.Revert();
|
||||
|
||||
keyboardInterceptorMock.Verify(i => i.Start(), Times.Never);
|
||||
keyboardInterceptorMock.Verify(i => i.Stop(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Mouse;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class MouseInterceptorOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<IMouseInterceptor> mouseInterceptorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
|
||||
private MouseInterceptorOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
mouseInterceptorMock = new Mock<IMouseInterceptor>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
|
||||
sut = new MouseInterceptorOperation(context, loggerMock.Object, mouseInterceptorMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustPerformCorrectly()
|
||||
{
|
||||
sut.Perform();
|
||||
|
||||
mouseInterceptorMock.Verify(i => i.Start(), Times.Once);
|
||||
mouseInterceptorMock.Verify(i => i.Stop(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustRevertCorrectly()
|
||||
{
|
||||
sut.Revert();
|
||||
|
||||
mouseInterceptorMock.Verify(i => i.Start(), Times.Never);
|
||||
mouseInterceptorMock.Verify(i => i.Stop(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Core.Contracts.Notifications;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Proctoring.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Proctoring;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ProctoringOperationTests
|
||||
{
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private ClientContext context;
|
||||
private Mock<IProctoringController> controller;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<INotification> notification1;
|
||||
private Mock<INotification> notification2;
|
||||
private AppSettings settings;
|
||||
private Mock<ITaskbar> taskbar;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
|
||||
private ProctoringOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
context = new ClientContext();
|
||||
controller = new Mock<IProctoringController>();
|
||||
logger = new Mock<ILogger>();
|
||||
notification1 = new Mock<INotification>();
|
||||
notification2 = new Mock<INotification>();
|
||||
settings = new AppSettings();
|
||||
taskbar = new Mock<ITaskbar>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
context.Settings = settings;
|
||||
controller.SetupGet(c => c.Notifications).Returns(new[] { notification1.Object, notification2.Object });
|
||||
sut = new ProctoringOperation(actionCenter.Object, context, controller.Object, logger.Object, taskbar.Object, uiFactory.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeProctoringCorrectly()
|
||||
{
|
||||
settings.Proctoring.Enabled = true;
|
||||
settings.Proctoring.ShowTaskbarNotification = true;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Perform());
|
||||
|
||||
actionCenter.Verify(a => a.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
|
||||
controller.Verify(c => c.Initialize(It.Is<ProctoringSettings>(s => s == settings.Proctoring)));
|
||||
notification1.VerifyNoOtherCalls();
|
||||
notification2.VerifyNoOtherCalls();
|
||||
taskbar.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
|
||||
uiFactory.Verify(u => u.CreateNotificationControl(It.IsAny<INotification>(), Location.ActionCenter), Times.Exactly(2));
|
||||
uiFactory.Verify(u => u.CreateNotificationControl(It.IsAny<INotification>(), Location.Taskbar), Times.Exactly(2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDoNothingIfNotEnabled()
|
||||
{
|
||||
settings.Proctoring.Enabled = false;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Perform());
|
||||
|
||||
actionCenter.VerifyNoOtherCalls();
|
||||
controller.VerifyNoOtherCalls();
|
||||
notification1.VerifyNoOtherCalls();
|
||||
notification2.VerifyNoOtherCalls();
|
||||
taskbar.VerifyNoOtherCalls();
|
||||
uiFactory.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustFinalizeProctoringCorrectly()
|
||||
{
|
||||
settings.Proctoring.Enabled = true;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Revert());
|
||||
|
||||
actionCenter.VerifyNoOtherCalls();
|
||||
controller.Verify(c => c.Terminate(), Times.Once);
|
||||
notification1.Verify(n => n.Terminate(), Times.Once);
|
||||
notification2.Verify(n => n.Terminate(), Times.Once);
|
||||
taskbar.VerifyNoOtherCalls();
|
||||
uiFactory.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothingIfNotEnabled()
|
||||
{
|
||||
settings.Proctoring.Enabled = false;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Revert());
|
||||
|
||||
actionCenter.VerifyNoOtherCalls();
|
||||
controller.VerifyNoOtherCalls();
|
||||
notification1.VerifyNoOtherCalls();
|
||||
notification2.VerifyNoOtherCalls();
|
||||
taskbar.VerifyNoOtherCalls();
|
||||
uiFactory.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class RuntimeConnectionOperationTests
|
||||
{
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeProxy> runtime;
|
||||
private Guid token;
|
||||
private RuntimeConnectionOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
runtime = new Mock<IRuntimeProxy>();
|
||||
token = Guid.NewGuid();
|
||||
|
||||
sut = new RuntimeConnectionOperation(context, logger.Object, runtime.Object, token);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustConnectOnPerform()
|
||||
{
|
||||
runtime.Setup(r => r.Connect(It.Is<Guid>(t => t == token), true)).Returns(true);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
runtime.Verify(r => r.Connect(It.Is<Guid>(t => t == token), true), Times.Once);
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyFailOnPerform()
|
||||
{
|
||||
runtime.Setup(r => r.Connect(It.Is<Guid>(t => t == token), true)).Returns(false);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
runtime.Verify(r => r.Connect(It.Is<Guid>(t => t == token), true), Times.Once);
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDisconnectOnRevert()
|
||||
{
|
||||
runtime.Setup(r => r.Connect(It.IsAny<Guid>(), It.IsAny<bool>())).Returns(true);
|
||||
runtime.Setup(r => r.Disconnect()).Returns(true);
|
||||
runtime.SetupGet(r => r.IsConnected).Returns(true);
|
||||
sut.Perform();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
runtime.Verify(r => r.Connect(It.IsAny<Guid>(), It.IsAny<bool>()), Times.Once);
|
||||
runtime.Verify(r => r.Disconnect(), Times.Once);
|
||||
runtime.VerifyGet(r => r.IsConnected, Times.Once);
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyFailOnRevert()
|
||||
{
|
||||
runtime.Setup(r => r.Connect(It.IsAny<Guid>(), It.IsAny<bool>())).Returns(true);
|
||||
runtime.Setup(r => r.Disconnect()).Returns(false);
|
||||
runtime.SetupGet(r => r.IsConnected).Returns(true);
|
||||
sut.Perform();
|
||||
|
||||
var result = sut.Revert();
|
||||
|
||||
runtime.Verify(r => r.Connect(It.IsAny<Guid>(), It.IsAny<bool>()), Times.Once);
|
||||
runtime.Verify(r => r.Disconnect(), Times.Once);
|
||||
runtime.VerifyGet(r => r.IsConnected, Times.Once);
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustDoNothingOnRevertIfNotConnected()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
runtime.VerifyGet(r => r.IsConnected, Times.Once);
|
||||
runtime.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.Client.Operations;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Server.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Server;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ServerOperationTests
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IServerProxy> server;
|
||||
private AppSettings settings;
|
||||
|
||||
private ServerOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
appConfig = new AppConfig();
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
server = new Mock<IServerProxy>();
|
||||
settings = new AppSettings();
|
||||
|
||||
context.AppConfig = appConfig;
|
||||
context.Settings = settings;
|
||||
|
||||
sut = new ServerOperation(context, logger.Object, server.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeCorrectly()
|
||||
{
|
||||
settings.SessionMode = SessionMode.Server;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Perform());
|
||||
|
||||
server.Verify(s => s.Initialize(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<ServerSettings>()), Times.Once);
|
||||
server.Verify(s => s.StartConnectivity(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustDoNothingIfNotActive()
|
||||
{
|
||||
settings.SessionMode = SessionMode.Normal;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Perform());
|
||||
|
||||
server.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustFinalizeCorrectly()
|
||||
{
|
||||
settings.SessionMode = SessionMode.Server;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Revert());
|
||||
|
||||
server.Verify(s => s.StopConnectivity(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothingIfNotActive()
|
||||
{
|
||||
settings.SessionMode = SessionMode.Normal;
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, sut.Revert());
|
||||
|
||||
server.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* 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.Applications.Contracts;
|
||||
using SafeExamBrowser.Client.Operations;
|
||||
using SafeExamBrowser.Core.Contracts.Notifications;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Applications;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class ShellOperationTests
|
||||
{
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private Mock<IAudio> audio;
|
||||
private ClientContext context;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<INotification> aboutNotification;
|
||||
private Mock<IKeyboard> keyboard;
|
||||
private Mock<INotification> logNotification;
|
||||
private Mock<INativeMethods> nativeMethods;
|
||||
private Mock<IPowerSupply> powerSupply;
|
||||
private Mock<ISystemInfo> systemInfo;
|
||||
private Mock<ITaskbar> taskbar;
|
||||
private Mock<ITaskview> taskview;
|
||||
private Mock<IText> text;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
private Mock<INetworkAdapter> networkAdapter;
|
||||
|
||||
private ShellOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
audio = new Mock<IAudio>();
|
||||
context = new ClientContext();
|
||||
logger = new Mock<ILogger>();
|
||||
aboutNotification = new Mock<INotification>();
|
||||
keyboard = new Mock<IKeyboard>();
|
||||
logNotification = new Mock<INotification>();
|
||||
nativeMethods = new Mock<INativeMethods>();
|
||||
networkAdapter = new Mock<INetworkAdapter>();
|
||||
powerSupply = new Mock<IPowerSupply>();
|
||||
systemInfo = new Mock<ISystemInfo>();
|
||||
taskbar = new Mock<ITaskbar>();
|
||||
taskview = new Mock<ITaskview>();
|
||||
text = new Mock<IText>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
context.Settings = new AppSettings();
|
||||
|
||||
uiFactory
|
||||
.Setup(u => u.CreateNotificationControl(It.IsAny<INotification>(), It.IsAny<Location>()))
|
||||
.Returns(new Mock<INotificationControl>().Object);
|
||||
|
||||
sut = new ShellOperation(
|
||||
actionCenter.Object,
|
||||
audio.Object,
|
||||
aboutNotification.Object,
|
||||
context,
|
||||
keyboard.Object,
|
||||
logger.Object,
|
||||
logNotification.Object,
|
||||
nativeMethods.Object,
|
||||
networkAdapter.Object,
|
||||
powerSupply.Object,
|
||||
systemInfo.Object,
|
||||
taskbar.Object,
|
||||
taskview.Object,
|
||||
text.Object,
|
||||
uiFactory.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeActivators()
|
||||
{
|
||||
var actionCenterActivator = new Mock<IActionCenterActivator>();
|
||||
var taskviewActivator = new Mock<ITaskviewActivator>();
|
||||
var terminationActivator = new Mock<ITerminationActivator>();
|
||||
|
||||
context.Activators.Add(actionCenterActivator.Object);
|
||||
context.Activators.Add(taskviewActivator.Object);
|
||||
context.Activators.Add(terminationActivator.Object);
|
||||
context.Settings.Keyboard.AllowAltTab = true;
|
||||
context.Settings.Security.AllowTermination = true;
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.Register(It.Is<IActionCenterActivator>(a2 => a2 == actionCenterActivator.Object)), Times.Once);
|
||||
actionCenterActivator.Verify(a => a.Start(), Times.Once);
|
||||
taskview.Verify(t => t.Register(It.Is<ITaskviewActivator>(a => a == taskviewActivator.Object)), Times.Once);
|
||||
taskviewActivator.Verify(a => a.Start(), Times.Once);
|
||||
terminationActivator.Verify(a => a.Start(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeApplications()
|
||||
{
|
||||
var application1 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application1Settings = new WhitelistApplication { ShowInShell = true };
|
||||
var application2 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application2Settings = new WhitelistApplication { ShowInShell = false };
|
||||
var application3 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application3Settings = new WhitelistApplication { ShowInShell = true };
|
||||
|
||||
application1.SetupGet(a => a.Id).Returns(application1Settings.Id);
|
||||
application2.SetupGet(a => a.Id).Returns(application2Settings.Id);
|
||||
application3.SetupGet(a => a.Id).Returns(application3Settings.Id);
|
||||
|
||||
context.Applications.Add(application1.Object);
|
||||
context.Applications.Add(application2.Object);
|
||||
context.Applications.Add(application3.Object);
|
||||
context.Settings.Applications.Whitelist.Add(application1Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application2Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application3Settings);
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>(), false), Times.Exactly(2));
|
||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>(), false), Times.Exactly(2));
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object)), Times.Once);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object)), Times.Once);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object)), Times.Once);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object), Location.ActionCenter), Times.Once);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object), Location.Taskbar), Times.Once);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object), Location.ActionCenter), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object), Location.Taskbar), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object), Location.ActionCenter), Times.Once);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object), Location.Taskbar), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotAddApplicationsToShellIfNotEnabled()
|
||||
{
|
||||
var application1 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application1Settings = new WhitelistApplication { ShowInShell = true };
|
||||
var application2 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application2Settings = new WhitelistApplication { ShowInShell = true };
|
||||
var application3 = new Mock<IApplication<IApplicationWindow>>();
|
||||
var application3Settings = new WhitelistApplication { ShowInShell = true };
|
||||
|
||||
application1.SetupGet(a => a.Id).Returns(application1Settings.Id);
|
||||
application2.SetupGet(a => a.Id).Returns(application2Settings.Id);
|
||||
application3.SetupGet(a => a.Id).Returns(application3Settings.Id);
|
||||
|
||||
context.Applications.Add(application1.Object);
|
||||
context.Applications.Add(application2.Object);
|
||||
context.Applications.Add(application3.Object);
|
||||
context.Settings.Applications.Whitelist.Add(application1Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application2Settings);
|
||||
context.Settings.Applications.Whitelist.Add(application3Settings);
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = false;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>(), false), Times.Never);
|
||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>(), false), Times.Never);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object)), Times.Once);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object)), Times.Once);
|
||||
taskview.Verify(t => t.Add(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object)), Times.Once);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object), Location.ActionCenter), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application1.Object), Location.Taskbar), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object), Location.ActionCenter), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application2.Object), Location.Taskbar), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object), Location.ActionCenter), Times.Never);
|
||||
uiFactory.Verify(f => f.CreateApplicationControl(It.Is<IApplication<IApplicationWindow>>(a => a == application3.Object), Location.Taskbar), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeAlwaysOnState()
|
||||
{
|
||||
context.Settings.Display.AlwaysOn = true;
|
||||
context.Settings.System.AlwaysOn = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
nativeMethods.Verify(n => n.SetAlwaysOnState(true, false), Times.Once);
|
||||
nativeMethods.Reset();
|
||||
|
||||
context.Settings.Display.AlwaysOn = false;
|
||||
context.Settings.System.AlwaysOn = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
nativeMethods.Verify(n => n.SetAlwaysOnState(false, true), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeClock()
|
||||
{
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowClock = true;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowClock = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.VerifySet(a => a.ShowClock = true, Times.Once);
|
||||
taskbar.VerifySet(t => t.ShowClock = true, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeClock()
|
||||
{
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowClock = false;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowClock = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.VerifySet(a => a.ShowClock = false, Times.Once);
|
||||
taskbar.VerifySet(t => t.ShowClock = false, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeQuitButton()
|
||||
{
|
||||
context.Settings.Security.AllowTermination = false;
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.VerifySet(a => a.ShowQuitButton = false, Times.Once);
|
||||
taskbar.VerifySet(t => t.ShowQuitButton = false, Times.Once);
|
||||
actionCenter.VerifySet(a => a.ShowQuitButton = true, Times.Never);
|
||||
taskbar.VerifySet(t => t.ShowQuitButton = true, Times.Never);
|
||||
|
||||
actionCenter.Reset();
|
||||
taskbar.Reset();
|
||||
context.Settings.Security.AllowTermination = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.VerifySet(a => a.ShowQuitButton = false, Times.Never);
|
||||
taskbar.VerifySet(t => t.ShowQuitButton = false, Times.Never);
|
||||
actionCenter.VerifySet(a => a.ShowQuitButton = true, Times.Once);
|
||||
taskbar.VerifySet(t => t.ShowQuitButton = true, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeNotifications()
|
||||
{
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowApplicationInfo = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowApplicationLog = true;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowApplicationInfo = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowApplicationLog = true;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddNotificationControl(It.IsAny<INotificationControl>()), Times.AtLeast(2));
|
||||
taskbar.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.AtLeast(2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeNotifications()
|
||||
{
|
||||
var logControl = new Mock<INotificationControl>();
|
||||
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowApplicationLog = false;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowApplicationLog = false;
|
||||
|
||||
uiFactory
|
||||
.Setup(f => f.CreateNotificationControl(It.IsAny<INotification>(), It.IsAny<Location>()))
|
||||
.Returns(logControl.Object);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.Verify(a => a.AddNotificationControl(It.Is<INotificationControl>(i => i == logControl.Object)), Times.Never);
|
||||
taskbar.Verify(t => t.AddNotificationControl(It.Is<INotificationControl>(i => i == logControl.Object)), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustInitializeSystemComponents()
|
||||
{
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowAudio = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowKeyboardLayout = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowNetwork = true;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowAudio = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowKeyboardLayout = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowNetwork = true;
|
||||
|
||||
systemInfo.SetupGet(s => s.HasBattery).Returns(true);
|
||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreateNetworkControl(It.IsAny<INetworkAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
audio.Verify(a => a.Initialize(), Times.Once);
|
||||
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
||||
networkAdapter.Verify(w => w.Initialize(), Times.Once);
|
||||
keyboard.Verify(k => k.Initialize(), Times.Once);
|
||||
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
||||
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeSystemComponents()
|
||||
{
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = true;
|
||||
context.Settings.UserInterface.ActionCenter.ShowAudio = false;
|
||||
context.Settings.UserInterface.ActionCenter.ShowKeyboardLayout = false;
|
||||
context.Settings.UserInterface.ActionCenter.ShowNetwork = false;
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = true;
|
||||
context.Settings.UserInterface.Taskbar.ShowAudio = false;
|
||||
context.Settings.UserInterface.Taskbar.ShowKeyboardLayout = false;
|
||||
context.Settings.UserInterface.Taskbar.ShowNetwork = false;
|
||||
|
||||
systemInfo.SetupGet(s => s.HasBattery).Returns(false);
|
||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
uiFactory.Setup(f => f.CreateNetworkControl(It.IsAny<INetworkAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
audio.Verify(a => a.Initialize(), Times.Once);
|
||||
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
||||
networkAdapter.Verify(w => w.Initialize(), Times.Once);
|
||||
keyboard.Verify(k => k.Initialize(), Times.Once);
|
||||
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
||||
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeActionCenterIfNotEnabled()
|
||||
{
|
||||
var actionCenterActivator = new Mock<IActionCenterActivator>();
|
||||
|
||||
context.Activators.Add(actionCenterActivator.Object);
|
||||
context.Settings.UserInterface.ActionCenter.EnableActionCenter = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
actionCenter.VerifyNoOtherCalls();
|
||||
actionCenterActivator.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeTaskviewActivatorIfNotEnabled()
|
||||
{
|
||||
var taskviewActivator = new Mock<ITaskviewActivator>();
|
||||
|
||||
context.Activators.Add(taskviewActivator.Object);
|
||||
context.Settings.Keyboard.AllowAltTab = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
taskview.Verify(t => t.Register(It.IsAny<ITaskviewActivator>()), Times.Never);
|
||||
taskviewActivator.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeTaskbarIfNotEnabled()
|
||||
{
|
||||
context.Settings.UserInterface.Taskbar.EnableTaskbar = false;
|
||||
sut.Perform();
|
||||
taskbar.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustNotInitializeTerminationActivatorIfNotEnabled()
|
||||
{
|
||||
var terminationActivator = new Mock<ITerminationActivator>();
|
||||
|
||||
context.Activators.Add(terminationActivator.Object);
|
||||
context.Settings.Security.AllowTermination = false;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
terminationActivator.Verify(a => a.Start(), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustTerminateActivators()
|
||||
{
|
||||
var actionCenterActivator = new Mock<IActionCenterActivator>();
|
||||
var taskviewActivator = new Mock<ITaskviewActivator>();
|
||||
var terminationActivator = new Mock<ITerminationActivator>();
|
||||
|
||||
context.Activators.Add(actionCenterActivator.Object);
|
||||
context.Activators.Add(taskviewActivator.Object);
|
||||
context.Activators.Add(terminationActivator.Object);
|
||||
|
||||
sut.Revert();
|
||||
|
||||
actionCenterActivator.Verify(a => a.Stop(), Times.Once);
|
||||
taskviewActivator.Verify(a => a.Stop(), Times.Once);
|
||||
terminationActivator.Verify(a => a.Stop(), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustTerminateControllers()
|
||||
{
|
||||
sut.Revert();
|
||||
|
||||
aboutNotification.Verify(c => c.Terminate(), Times.Once);
|
||||
audio.Verify(a => a.Terminate(), Times.Once);
|
||||
logNotification.Verify(c => c.Terminate(), Times.Once);
|
||||
powerSupply.Verify(p => p.Terminate(), Times.Once);
|
||||
keyboard.Verify(k => k.Terminate(), Times.Once);
|
||||
networkAdapter.Verify(w => w.Terminate(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
17
SafeExamBrowser.Client.UnitTests/Properties/AssemblyInfo.cs
Normal file
17
SafeExamBrowser.Client.UnitTests/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("SafeExamBrowser.Client.UnitTests")]
|
||||
[assembly: AssemblyDescription("Safe Exam Browser")]
|
||||
[assembly: AssemblyCompany("ETH Zürich")]
|
||||
[assembly: AssemblyProduct("SafeExamBrowser.Client.UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024 ETH Zürich, IT Services")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("15684416-fadf-4c51-85de-4f343bfab752")]
|
||||
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("1.0.0.0")]
|
@@ -0,0 +1,260 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.props')" />
|
||||
<Import Project="..\packages\Microsoft.Testing.Extensions.Telemetry.1.0.2\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props" Condition="Exists('..\packages\Microsoft.Testing.Extensions.Telemetry.1.0.2\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props')" />
|
||||
<Import Project="..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.props" Condition="Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{15684416-FADF-4C51-85DE-4F343BFAB752}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SafeExamBrowser.Client.UnitTests</RootNamespace>
|
||||
<AssemblyName>SafeExamBrowser.Client.UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.ApplicationInsights, Version=2.22.0.997, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Testing.Extensions.Telemetry, Version=1.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.Telemetry.1.0.2\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.TrxReport.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.0.2\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.VSTestBridge, Version=1.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.0.2\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Platform, Version=1.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\lib\netstandard2.0\Microsoft.Testing.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Platform.MSBuild, Version=1.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\lib\netstandard2.0\Microsoft.Testing.Platform.MSBuild.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TestPlatform.CoreUtilities, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.9.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TestPlatform.PlatformAbstractions, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.9.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.ObjectModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.9.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.3.2.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.3.2.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.20.70.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.20.70\lib\net462\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NuGet.Frameworks, Version=6.9.1.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NuGet.Frameworks.6.9.1\lib\net472\NuGet.Frameworks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.8.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Packaging, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Packaging.8.0.0\lib\net462\System.IO.Packaging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Metadata, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Reflection.Metadata.8.0.0\lib\net462\System.Reflection.Metadata.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Operations\ApplicationOperationTests.cs" />
|
||||
<Compile Include="Operations\BrowserOperationTests.cs" />
|
||||
<Compile Include="Operations\ClientHostDisconnectionOperationTests.cs" />
|
||||
<Compile Include="Operations\ClipboardOperationTests.cs" />
|
||||
<Compile Include="Operations\ConfigurationOperationTests.cs" />
|
||||
<Compile Include="Operations\DisplayMonitorOperationTests.cs" />
|
||||
<Compile Include="Operations\KeyboardInterceptorOperationTests.cs" />
|
||||
<Compile Include="Operations\MouseInterceptorOperationTests.cs" />
|
||||
<Compile Include="Operations\ProctoringOperationTests.cs" />
|
||||
<Compile Include="Operations\RuntimeConnectionOperationTests.cs" />
|
||||
<Compile Include="Operations\ServerOperationTests.cs" />
|
||||
<Compile Include="Operations\ShellOperationTests.cs" />
|
||||
<Compile Include="Communication\ClientHostTests.cs" />
|
||||
<Compile Include="Notifications\AboutNotificationControllerTests.cs" />
|
||||
<Compile Include="Notifications\LogNotificationControllerTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ClientControllerTests.cs" />
|
||||
<Compile Include="CoordinatorTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Applications.Contracts\SafeExamBrowser.Applications.Contracts.csproj">
|
||||
<Project>{ac77745d-3b41-43e2-8e84-d40e5a4ee77f}</Project>
|
||||
<Name>SafeExamBrowser.Applications.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Browser.Contracts\SafeExamBrowser.Browser.Contracts.csproj">
|
||||
<Project>{5fb5273d-277c-41dd-8593-a25ce1aff2e9}</Project>
|
||||
<Name>SafeExamBrowser.Browser.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Client\SafeExamBrowser.Client.csproj">
|
||||
<Project>{7CC5A895-E0D3-4E43-9B39-CCEC05A5A6A7}</Project>
|
||||
<Name>SafeExamBrowser.Client</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Communication.Contracts\SafeExamBrowser.Communication.Contracts.csproj">
|
||||
<Project>{0cd2c5fe-711a-4c32-afe0-bb804fe8b220}</Project>
|
||||
<Name>SafeExamBrowser.Communication.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Communication\SafeExamBrowser.Communication.csproj">
|
||||
<Project>{c9416a62-0623-4d38-96aa-92516b32f02f}</Project>
|
||||
<Name>SafeExamBrowser.Communication</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Configuration.Contracts\SafeExamBrowser.Configuration.Contracts.csproj">
|
||||
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
|
||||
<Name>SafeExamBrowser.Configuration.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Core.Contracts\SafeExamBrowser.Core.Contracts.csproj">
|
||||
<Project>{fe0e1224-b447-4b14-81e7-ed7d84822aa0}</Project>
|
||||
<Name>SafeExamBrowser.Core.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Core\SafeExamBrowser.Core.csproj">
|
||||
<Project>{3D6FDBB6-A4AF-4626-BB2B-BF329D44F9CC}</Project>
|
||||
<Name>SafeExamBrowser.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.I18n.Contracts\SafeExamBrowser.I18n.Contracts.csproj">
|
||||
<Project>{1858ddf3-bc2a-4bff-b663-4ce2ffeb8b7d}</Project>
|
||||
<Name>SafeExamBrowser.I18n.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
||||
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
|
||||
<Name>SafeExamBrowser.Logging.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Monitoring.Contracts\SafeExamBrowser.Monitoring.Contracts.csproj">
|
||||
<Project>{6d563a30-366d-4c35-815b-2c9e6872278b}</Project>
|
||||
<Name>SafeExamBrowser.Monitoring.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Proctoring.Contracts\SafeExamBrowser.Proctoring.Contracts.csproj">
|
||||
<Project>{8e52bd1c-0540-4f16-b181-6665d43f7a7b}</Project>
|
||||
<Name>SafeExamBrowser.Proctoring.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Server.Contracts\SafeExamBrowser.Server.Contracts.csproj">
|
||||
<Project>{db701e6f-bddc-4cec-b662-335a9dc11809}</Project>
|
||||
<Name>SafeExamBrowser.Server.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
|
||||
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
|
||||
<Name>SafeExamBrowser.Settings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.SystemComponents.Contracts\SafeExamBrowser.SystemComponents.Contracts.csproj">
|
||||
<Project>{903129c6-e236-493b-9ad6-c6a57f647a3a}</Project>
|
||||
<Name>SafeExamBrowser.SystemComponents.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.UserInterface.Contracts\SafeExamBrowser.UserInterface.Contracts.csproj">
|
||||
<Project>{c7889e97-6ff6-4a58-b7cb-521ed276b316}</Project>
|
||||
<Name>SafeExamBrowser.UserInterface.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.WindowsApi.Contracts\SafeExamBrowser.WindowsApi.Contracts.csproj">
|
||||
<Project>{7016f080-9aa5-41b2-a225-385ad877c171}</Project>
|
||||
<Name>SafeExamBrowser.WindowsApi.Contracts</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Extensions.Telemetry.1.0.2\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Extensions.Telemetry.1.0.2\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props'))" />
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.props'))" />
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.targets" Condition="Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.0.2\build\netstandard2.0\Microsoft.Testing.Platform.MSBuild.targets')" />
|
||||
<Import Project="..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.3.2.2\build\net462\MSTest.TestAdapter.targets')" />
|
||||
</Project>
|
51
SafeExamBrowser.Client.UnitTests/app.config
Normal file
51
SafeExamBrowser.Client.UnitTests/app.config
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NuGet.Frameworks" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.11.3.1" newVersion="5.11.3.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.22.0.997" newVersion="2.22.0.997" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup></configuration>
|
26
SafeExamBrowser.Client.UnitTests/packages.config
Normal file
26
SafeExamBrowser.Client.UnitTests/packages.config
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Castle.Core" version="5.1.1" targetFramework="net48" />
|
||||
<package id="Microsoft.ApplicationInsights" version="2.22.0" targetFramework="net48" />
|
||||
<package id="Microsoft.Testing.Extensions.Telemetry" version="1.0.2" targetFramework="net48" />
|
||||
<package id="Microsoft.Testing.Extensions.TrxReport.Abstractions" version="1.0.2" targetFramework="net48" />
|
||||
<package id="Microsoft.Testing.Extensions.VSTestBridge" version="1.0.2" targetFramework="net48" />
|
||||
<package id="Microsoft.Testing.Platform" version="1.0.2" targetFramework="net48" />
|
||||
<package id="Microsoft.Testing.Platform.MSBuild" version="1.0.2" targetFramework="net48" />
|
||||
<package id="Microsoft.TestPlatform.ObjectModel" version="17.9.0" targetFramework="net48" />
|
||||
<package id="Moq" version="4.20.70" targetFramework="net48" />
|
||||
<package id="MSTest.TestAdapter" version="3.2.2" targetFramework="net48" />
|
||||
<package id="MSTest.TestFramework" version="3.2.2" targetFramework="net48" />
|
||||
<package id="NuGet.Frameworks" version="6.9.1" targetFramework="net48" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||
<package id="System.Collections.Immutable" version="8.0.0" targetFramework="net48" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="8.0.0" targetFramework="net48" />
|
||||
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net48" />
|
||||
<package id="System.IO.Packaging" version="8.0.0" targetFramework="net48" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
||||
<package id="System.Reflection.Metadata" version="8.0.0" targetFramework="net48" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
|
||||
</packages>
|
Reference in New Issue
Block a user