seb-win-refactoring/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs

293 lines
8.2 KiB
C#

/*
* Copyright (c) 2023 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.ServiceModel;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Communication.Contracts;
using SafeExamBrowser.Communication.Contracts.Data;
using SafeExamBrowser.Communication.Contracts.Hosts;
using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Communication.UnitTests.Hosts
{
[TestClass]
public class BaseHostTests
{
private Mock<IHostObject> hostObject;
private Mock<IHostObjectFactory> hostObjectFactory;
private Mock<ILogger> logger;
private BaseHostStub sut;
[TestInitialize]
public void Initialize()
{
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 BaseHostStub("net.pipe://some/address/here", hostObjectFactory.Object, logger.Object, 10);
}
[TestMethod]
public void MustCorrectlyStartHost()
{
var threadId = Thread.CurrentThread.ManagedThreadId;
hostObject.Setup(h => h.Open()).Callback(() => threadId = Thread.CurrentThread.ManagedThreadId);
sut.Start();
hostObjectFactory.Verify(f => f.CreateObject(It.IsAny<string>(), sut), Times.Once);
Assert.AreNotEqual(Thread.CurrentThread.ManagedThreadId, threadId);
}
[TestMethod]
[ExpectedException(typeof(CommunicationException))]
public void MustCorrectlyHandleStartupException()
{
hostObject.Setup(h => h.Open()).Throws<Exception>();
sut.Start();
}
[TestMethod]
public void MustCorrectlyStopHost()
{
sut.Start();
sut.Stop();
hostObject.Verify(h => h.Close(), Times.Once);
}
[TestMethod]
[ExpectedException(typeof(CommunicationException))]
public void MustCorrectlyHandleShutdownException()
{
hostObject.Setup(h => h.Close()).Throws<Exception>();
sut.Start();
sut.Stop();
}
[TestMethod]
public void MustNotFailToStopIfNotRunning()
{
sut.Stop();
sut.Stop();
sut.Stop();
}
[TestMethod]
public void MustNotFailToEvaluateIsRunningIfNotRunning()
{
var running = sut.IsRunning;
Assert.IsFalse(running);
}
[TestMethod]
public void MustCorrectlyIndicateWhetherHostIsRunning()
{
hostObject.SetupGet(h => h.State).Returns(CommunicationState.Faulted);
sut.Start();
Assert.IsFalse(sut.IsRunning);
hostObject.SetupGet(h => h.State).Returns(CommunicationState.Opened);
Assert.IsTrue(sut.IsRunning);
}
[TestMethod]
public void MustCorrectlyHandleConnectionRequest()
{
var token = Guid.NewGuid();
var receivedToken = default(Guid?);
sut.OnConnectStub = (t) =>
{
receivedToken = t;
return true;
};
var response = sut.Connect(token);
Assert.IsTrue(response.ConnectionEstablished);
Assert.AreEqual(token, receivedToken);
Assert.AreEqual(sut.GetCommunicationToken(), response.CommunicationToken);
}
[TestMethod]
public void MustCorrectlyHandleDeniedConnectionRequest()
{
var token = Guid.NewGuid();
var receivedToken = default(Guid?);
sut.OnConnectStub = (t) =>
{
receivedToken = t;
return false;
};
var response = sut.Connect(token);
Assert.IsFalse(response.ConnectionEstablished);
Assert.AreEqual(token, receivedToken);
Assert.IsNull(sut.GetCommunicationToken());
Assert.IsNull(response.CommunicationToken);
}
[TestMethod]
public void MustCorrectlyHandleDisconnectionRequest()
{
var message = new DisconnectionMessage { Interlocutor = Interlocutor.Runtime };
var disconnected = false;
var interlocutor = Interlocutor.Unknown;
sut.OnConnectStub = (t) => { return true; };
sut.OnDisconnectStub = (i) => { disconnected = true; interlocutor = i; };
sut.Connect();
message.CommunicationToken = sut.GetCommunicationToken().Value;
var response = sut.Disconnect(message);
Assert.AreEqual(message.Interlocutor, interlocutor);
Assert.IsTrue(disconnected);
Assert.IsTrue(response.ConnectionTerminated);
Assert.IsNull(sut.GetCommunicationToken());
}
[TestMethod]
public void MustCorrectlyHandleUnauthorizedDisconnectionRequest()
{
var disconnected = false;
sut.OnConnectStub = (t) => { return true; };
sut.OnDisconnectStub = (i) => disconnected = true;
sut.Connect();
var response = sut.Disconnect(new DisconnectionMessage());
Assert.IsFalse(disconnected);
Assert.IsFalse(response.ConnectionTerminated);
Assert.IsNotNull(sut.GetCommunicationToken());
}
[TestMethod]
public void MustCorrectlyHandleUnauthorizedTransmission()
{
var received = false;
var simpleReceived = false;
sut.OnReceiveStub = (m) => { received = true; return null; };
sut.OnReceiveSimpleMessageStub = (m) => { simpleReceived = true; return null; };
var response = sut.Send(new DisconnectionMessage());
Assert.IsFalse(received);
Assert.IsFalse(simpleReceived);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(SimpleResponsePurport.Unauthorized, (response as SimpleResponse)?.Purport);
}
[TestMethod]
public void MustCorrectlyHandlePingMessage()
{
var received = false;
var simpleReceived = false;
var message = new SimpleMessage(SimpleMessagePurport.Ping);
sut.OnReceiveStub = (m) => { received = true; return null; };
sut.OnReceiveSimpleMessageStub = (m) => { simpleReceived = true; return null; };
sut.OnConnectStub = (t) => { return true; };
sut.Connect();
message.CommunicationToken = sut.GetCommunicationToken().Value;
var response = sut.Send(message);
Assert.IsFalse(received);
Assert.IsFalse(simpleReceived);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
}
[TestMethod]
public void MustCorrectlyReceiveSimpleMessage()
{
var received = false;
var simpleReceived = false;
var purport = default(SimpleMessagePurport);
var message = new SimpleMessage(SimpleMessagePurport.ConfigurationNeeded);
var simpleResponse = new SimpleResponse(SimpleResponsePurport.UnknownMessage);
sut.OnReceiveStub = (m) => { received = true; return null; };
sut.OnReceiveSimpleMessageStub = (m) => { simpleReceived = true; purport = m; return simpleResponse; };
sut.OnConnectStub = (t) => { return true; };
sut.Connect();
message.CommunicationToken = sut.GetCommunicationToken().Value;
var response = sut.Send(message);
Assert.IsFalse(received);
Assert.IsTrue(simpleReceived);
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
Assert.AreEqual(SimpleMessagePurport.ConfigurationNeeded, purport);
Assert.AreSame(simpleResponse, response);
}
[TestMethod]
public void MustCorrectlyReceiveMessage()
{
var received = false;
var simpleReceived = false;
var message = new ReconfigurationMessage(null, null);
var configurationResponse = new ConfigurationResponse();
sut.OnReceiveStub = (m) => { received = true; return configurationResponse; };
sut.OnReceiveSimpleMessageStub = (m) => { simpleReceived = true; return null; };
sut.OnConnectStub = (t) => { return true; };
sut.Connect();
message.CommunicationToken = sut.GetCommunicationToken().Value;
var response = sut.Send(message);
Assert.IsTrue(received);
Assert.IsFalse(simpleReceived);
Assert.IsInstanceOfType(response, typeof(ConfigurationResponse));
Assert.AreSame(configurationResponse, response);
}
[TestMethod]
public void MustLogStatusChangesOfHost()
{
sut.Start();
hostObject.Raise(h => h.Closed += null, It.IsAny<EventArgs>());
hostObject.Raise(h => h.Closing += null, It.IsAny<EventArgs>());
hostObject.Raise(h => h.Faulted += null, It.IsAny<EventArgs>());
hostObject.Raise(h => h.Opened += null, It.IsAny<EventArgs>());
hostObject.Raise(h => h.Opening += null, It.IsAny<EventArgs>());
logger.Verify(l => l.Debug(It.IsAny<string>()), Times.AtLeast(4));
logger.Verify(l => l.Error(It.IsAny<string>()), Times.Once);
}
}
}