Fixed issue with splash screen not being closed on client side if reconfiguration was aborted.

This commit is contained in:
dbuechel 2020-02-10 16:47:50 +01:00
parent 5ce5c78641
commit 2cde60b1e7
12 changed files with 127 additions and 5 deletions

View file

@ -297,6 +297,19 @@ namespace SafeExamBrowser.Client.UnitTests
It.Is<string>(s => s == result.Password)), Times.Once);
}
[TestMethod]
public void Communication_MustCorrectlyHandleAbortedReconfiguration()
{
var splashScreen = new Mock<ISplashScreen>();
uiFactory.Setup(f => f.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(splashScreen.Object);
sut.TryStart();
clientHost.Raise(c => c.ReconfigurationAborted += null);
splashScreen.Verify(s => s.Close(), Times.AtLeastOnce);
}
[TestMethod]
public void Communication_MustInformUserAboutDeniedReconfiguration()
{

View file

@ -208,6 +208,31 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
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()
{
@ -282,6 +307,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
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 });

View file

@ -178,6 +178,7 @@ namespace SafeExamBrowser.Client
Browser.TerminationRequested += Browser_TerminationRequested;
ClientHost.MessageBoxRequested += ClientHost_MessageBoxRequested;
ClientHost.PasswordRequested += ClientHost_PasswordRequested;
ClientHost.ReconfigurationAborted += ClientHost_ReconfigurationAborted;
ClientHost.ReconfigurationDenied += ClientHost_ReconfigurationDenied;
ClientHost.Shutdown += ClientHost_Shutdown;
displayMonitor.DisplayChanged += DisplayMonitor_DisplaySettingsChanged;
@ -208,6 +209,7 @@ namespace SafeExamBrowser.Client
{
ClientHost.MessageBoxRequested -= ClientHost_MessageBoxRequested;
ClientHost.PasswordRequested -= ClientHost_PasswordRequested;
ClientHost.ReconfigurationAborted -= ClientHost_ReconfigurationAborted;
ClientHost.ReconfigurationDenied -= ClientHost_ReconfigurationDenied;
ClientHost.Shutdown -= ClientHost_Shutdown;
}
@ -421,11 +423,12 @@ namespace SafeExamBrowser.Client
runtime.SubmitPassword(args.RequestId, result.Success, result.Password);
logger.Info($"Password request with id '{args.RequestId}' was {(result.Success ? "successful" : "aborted by the user")}.");
}
if (!result.Success)
{
splashScreen?.Close();
}
private void ClientHost_ReconfigurationAborted()
{
logger.Info("The reconfiguration was aborted by the runtime.");
splashScreen?.Close();
}
private void ClientHost_ReconfigurationDenied(ReconfigurationEventArgs args)

View file

@ -26,6 +26,7 @@ namespace SafeExamBrowser.Client.Communication
public event CommunicationEventHandler<MessageBoxRequestEventArgs> MessageBoxRequested;
public event CommunicationEventHandler<PasswordRequestEventArgs> PasswordRequested;
public event CommunicationEventHandler ReconfigurationAborted;
public event CommunicationEventHandler<ReconfigurationEventArgs> ReconfigurationDenied;
public event CommunicationEventHandler RuntimeDisconnected;
public event CommunicationEventHandler Shutdown;
@ -88,6 +89,9 @@ namespace SafeExamBrowser.Client.Communication
{
case SimpleMessagePurport.Authenticate:
return new AuthenticationResponse { ProcessId = processId };
case SimpleMessagePurport.ReconfigurationAborted:
ReconfigurationAborted?.InvokeAsync();
return new SimpleResponse(SimpleResponsePurport.Acknowledged);
case SimpleMessagePurport.Shutdown:
Shutdown?.Invoke();
return new SimpleResponse(SimpleResponsePurport.Acknowledged);

View file

@ -36,6 +36,11 @@ namespace SafeExamBrowser.Communication.Contracts.Data
/// </summary>
Ping,
/// <summary>
/// Sent from the runtime to the client to inform the latter that a reconfiguration was aborted.
/// </summary>
ReconfigurationAborted,
/// <summary>
/// Sent from the client to the runtime to request shutting down the application.
/// </summary>

View file

@ -36,6 +36,11 @@ namespace SafeExamBrowser.Communication.Contracts.Hosts
/// </summary>
event CommunicationEventHandler<PasswordRequestEventArgs> PasswordRequested;
/// <summary>
/// Event fired when the runtime aborted a reconfiguration.
/// </summary>
event CommunicationEventHandler ReconfigurationAborted;
/// <summary>
/// Event fired when the runtime denied a reconfiguration request.
/// </summary>

View file

@ -16,6 +16,11 @@ namespace SafeExamBrowser.Communication.Contracts.Proxies
/// </summary>
public interface IClientProxy : ICommunicationProxy
{
/// <summary>
/// Informs the client that a reconfiguration was aborted.
/// </summary>
CommunicationResult InformReconfigurationAborted();
/// <summary>
/// Informs the client that the reconfiguration request for the specified file was denied.
/// </summary>

View file

@ -93,6 +93,27 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies
Assert.IsFalse(communication.Success);
}
[TestMethod]
public void MustCorrectlyInformAboutReconfigurationAbortion()
{
proxy.Setup(p => p.Send(It.Is<SimpleMessage>(m => m.Purport == SimpleMessagePurport.ReconfigurationAborted))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
var communication = sut.InformReconfigurationAborted();
proxy.Verify(p => p.Send(It.Is<SimpleMessage>(m => m.Purport == SimpleMessagePurport.ReconfigurationAborted)), Times.Once);
Assert.IsTrue(communication.Success);
}
[TestMethod]
public void MustFailIfReconfigurationAbortionNotAcknowledged()
{
proxy.Setup(p => p.Send(It.IsAny<SimpleMessage>())).Returns<Response>(null);
var communication = sut.InformReconfigurationAborted();
Assert.IsFalse(communication.Success);
}
[TestMethod]
public void MustCorrectlyInformAboutReconfigurationDenial()
{

View file

@ -23,6 +23,32 @@ namespace SafeExamBrowser.Communication.Proxies
{
}
public CommunicationResult InformReconfigurationAborted()
{
try
{
var response = Send(new SimpleMessage(SimpleMessagePurport.ReconfigurationAborted));
var success = IsAcknowledged(response);
if (success)
{
Logger.Debug("Client acknowledged reconfiguration abortion.");
}
else
{
Logger.Error($"Client did not acknowledge reconfiguration abortion! Received: {ToString(response)}.");
}
return new CommunicationResult(success);
}
catch (Exception e)
{
Logger.Error($"Failed to perform '{nameof(InformReconfigurationAborted)}'", e);
return new CommunicationResult(false);
}
}
public CommunicationResult InformReconfigurationDenied(string filePath)
{
try

View file

@ -271,7 +271,7 @@
Configuration Error
</Entry>
<Entry key="MessageBox_VirtualMachineNotAllowed">
This computer appears to be a virtual machine. The currently active configuration does not allow SEB to be run in a virtual machine.
This computer appears to be a virtual machine. The selected configuration does not allow SEB to be run in a virtual machine.
</Entry>
<Entry key="MessageBox_VirtualMachineNotAllowedTitle">
Virtual Machine Detected

View file

@ -171,6 +171,18 @@ namespace SafeExamBrowser.Runtime.UnitTests
Assert.AreEqual(sessionContext.ReconfigurationFilePath, args.ConfigurationPath);
}
[TestMethod]
public void Communication_MustInformClientAboutAbortedReconfiguration()
{
StartSession();
sessionSequence.Reset();
sessionSequence.Setup(s => s.TryRepeat()).Returns(OperationResult.Aborted);
runtimeHost.Raise(r => r.ReconfigurationRequested += null, new ReconfigurationEventArgs());
clientProxy.Verify(c => c.InformReconfigurationAborted(), Times.Once);
}
[TestMethod]
public void Communication_MustInformClientAboutDeniedReconfiguration()
{

View file

@ -233,6 +233,8 @@ namespace SafeExamBrowser.Runtime
{
runtimeWindow.Hide();
}
sessionContext.ClientProxy.InformReconfigurationAborted();
}
}