SEBWIN-219: Completed provisional implementation of unit test for communication hosts.
This commit is contained in:
parent
3a4f189916
commit
e750f870c0
6 changed files with 398 additions and 6 deletions
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOnlyAllowConnectionIfTokenIsValid()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsTrue(response.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[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 token = Guid.NewGuid();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
[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 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 { };
|
||||
}
|
||||
}
|
|
@ -86,6 +86,7 @@
|
|||
<Compile Include="Behaviour\Operations\ProcessMonitorOperationTests.cs" />
|
||||
<Compile Include="Behaviour\Operations\TaskbarOperationTests.cs" />
|
||||
<Compile Include="Behaviour\Operations\WindowMonitorOperationTests.cs" />
|
||||
<Compile Include="Communication\ClientHostTests.cs" />
|
||||
<Compile Include="Notifications\AboutNotificationControllerTests.cs" />
|
||||
<Compile Include="Notifications\LogNotificationControllerTests.cs" />
|
||||
<Compile Include="Notifications\NotificationButtonMock.cs" />
|
||||
|
@ -105,6 +106,10 @@
|
|||
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
|
||||
<Name>SafeExamBrowser.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Core\SafeExamBrowser.Core.csproj">
|
||||
<Project>{3D6FDBB6-A4AF-4626-BB2B-BF329D44F9CC}</Project>
|
||||
<Name>SafeExamBrowser.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
|
|
@ -206,22 +206,71 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Hosts
|
|||
[TestMethod]
|
||||
public void MustCorrectlyHandlePingMessage()
|
||||
{
|
||||
// TODO
|
||||
Assert.Fail();
|
||||
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()
|
||||
{
|
||||
// TODO
|
||||
Assert.Fail();
|
||||
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()
|
||||
{
|
||||
// TODO
|
||||
Assert.Fail();
|
||||
var received = false;
|
||||
var simpleReceived = false;
|
||||
var message = new ReconfigurationMessage(null);
|
||||
var reconfigurationResponse = new ReconfigurationResponse();
|
||||
|
||||
sut.OnReceiveStub = (m) => { received = true; return reconfigurationResponse; };
|
||||
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(ReconfigurationResponse));
|
||||
Assert.AreSame(reconfigurationResponse, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
using SafeExamBrowser.Contracts.Communication.Data;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Runtime.Communication;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
||||
{
|
||||
[TestClass]
|
||||
public class RuntimeHostTests
|
||||
{
|
||||
private Mock<IConfigurationRepository> configuration;
|
||||
private Mock<IHostObject> hostObject;
|
||||
private Mock<IHostObjectFactory> hostObjectFactory;
|
||||
private Mock<ILogger> logger;
|
||||
private RuntimeHost 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 RuntimeHost("net:pipe://some/address", configuration.Object, hostObjectFactory.Object, logger.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOnlyAllowConnectionIfTokenIsValid()
|
||||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsTrue(response.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[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 disconnected = false;
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
sut.ClientDisconnected += () => disconnected = true;
|
||||
|
||||
var connectionResponse = sut.Connect(token);
|
||||
var response = sut.Disconnect(new DisconnectionMessage { CommunicationToken = connectionResponse.CommunicationToken.Value });
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsTrue(disconnected);
|
||||
Assert.IsTrue(response.ConnectionTerminated);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustAllowReconnectionAfterDisconnection()
|
||||
{
|
||||
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.IsTrue(response.ConnectionEstablished);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleClientReadyCorrectly()
|
||||
{
|
||||
var clientReady = false;
|
||||
|
||||
sut.ClientReady += () => clientReady = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.ClientIsReady) { CommunicationToken = token };
|
||||
var response = sut.Send(message);
|
||||
|
||||
Assert.IsTrue(clientReady);
|
||||
Assert.IsNotNull(response);
|
||||
Assert.IsInstanceOfType(response, typeof(SimpleResponse));
|
||||
Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleShutdownRequestCorrectly()
|
||||
{
|
||||
var shutdownRequested = false;
|
||||
|
||||
sut.ShutdownRequested += () => shutdownRequested = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.RequestShutdown) { 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 { };
|
||||
}
|
||||
}
|
|
@ -85,6 +85,7 @@
|
|||
<Compile Include="Behaviour\Operations\ServiceConnectionOperationTests.cs" />
|
||||
<Compile Include="Behaviour\Operations\SessionSequenceOperationTests.cs" />
|
||||
<Compile Include="Behaviour\RuntimeControllerTests.cs" />
|
||||
<Compile Include="Communication\RuntimeHostTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -96,6 +97,10 @@
|
|||
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
|
||||
<Name>SafeExamBrowser.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.Runtime\SafeExamBrowser.Runtime.csproj">
|
||||
<Project>{e3aed2f8-b5df-45d1-ac19-48066923d6d8}</Project>
|
||||
<Name>SafeExamBrowser.Runtime</Name>
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
switch (message)
|
||||
{
|
||||
case ReconfigurationMessage reconfigurationMessage:
|
||||
// TODO: Not the job of the host, fire event or alike!
|
||||
return Handle(reconfigurationMessage);
|
||||
}
|
||||
|
||||
|
@ -79,6 +80,7 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
ClientReady?.Invoke();
|
||||
return new SimpleResponse(SimpleResponsePurport.Acknowledged);
|
||||
case SimpleMessagePurport.ConfigurationNeeded:
|
||||
// TODO: Not the job of the host, fire event or alike!
|
||||
return new ConfigurationResponse { Configuration = configuration.BuildClientConfiguration() };
|
||||
case SimpleMessagePurport.RequestShutdown:
|
||||
ShutdownRequested?.Invoke();
|
||||
|
|
Loading…
Reference in a new issue