seb-win-refactoring/SafeExamBrowser.Client.UnitTests/Communication/ClientHostTests.cs

259 lines
8.2 KiB
C#

/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Client.Communication;
using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.UserInterface.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.StartupToken = token;
var response = sut.Connect(Guid.Empty);
Assert.IsNotNull(response);
Assert.IsFalse(response.ConnectionEstablished);
Assert.IsFalse(sut.IsConnected);
response = sut.Connect(token);
Assert.IsNotNull(response);
Assert.IsTrue(response.ConnectionEstablished);
Assert.IsTrue(sut.IsConnected);
}
[TestMethod]
public void MustOnlyAllowOneConcurrentConnection()
{
var token = Guid.NewGuid();
sut.StartupToken = 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.StartupToken = token;
var connectionResponse = sut.Connect(token);
var response = sut.Disconnect(new DisconnectionMessage { CommunicationToken = connectionResponse.CommunicationToken.Value });
Assert.IsNotNull(response);
Assert.IsTrue(response.ConnectionTerminated);
Assert.IsTrue(eventFired);
Assert.IsFalse(sut.IsConnected);
}
[TestMethod]
public void MustNotAllowReconnectionAfterDisconnection()
{
var token = sut.StartupToken = Guid.NewGuid();
var response = sut.Connect(token);
sut.Disconnect(new DisconnectionMessage { CommunicationToken = response.CommunicationToken.Value });
sut.StartupToken = token = Guid.NewGuid();
response = sut.Connect(token);
Assert.IsFalse(response.ConnectionEstablished);
}
[TestMethod]
public void MustHandleAuthenticationRequestCorrectly()
{
sut.StartupToken = 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 MustHandleMessageBoxRequestCorrectly()
{
var action = MessageBoxAction.YesNo;
var icon = 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.StartupToken = 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.StartupToken = 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 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.StartupToken = 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 MustHandleShutdownRequestCorrectly()
{
var shutdownRequested = false;
sut.Shutdown += () => shutdownRequested = true;
sut.StartupToken = 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.StartupToken = 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);
}
private class TestMessage : Message { };
}
}