From 11b10e8e4524c1fe65b6c3db7d12e172facf322c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20B=C3=BCchel?= Date: Fri, 2 Jun 2023 15:51:45 +0200 Subject: [PATCH] SEBWIN-674: Extended unit tests for third-party application logic. --- .../ExternalApplicationInstanceTests.cs | 62 +++++++++++++++++++ .../ExternalApplicationTests.cs | 18 +++++- .../ExternalApplicationWindowTests.cs | 4 ++ ...eExamBrowser.Applications.UnitTests.csproj | 1 + .../ExternalApplicationInstance.cs | 7 ++- 5 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 SafeExamBrowser.Applications.UnitTests/ExternalApplicationInstanceTests.cs diff --git a/SafeExamBrowser.Applications.UnitTests/ExternalApplicationInstanceTests.cs b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationInstanceTests.cs new file mode 100644 index 00000000..7e87b35f --- /dev/null +++ b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationInstanceTests.cs @@ -0,0 +1,62 @@ +/* + * 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 Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using SafeExamBrowser.Core.Contracts.Resources.Icons; +using SafeExamBrowser.Logging.Contracts; +using SafeExamBrowser.WindowsApi.Contracts; + +namespace SafeExamBrowser.Applications.UnitTests +{ + [TestClass] + public class ExternalApplicationInstanceTests + { + private NativeIconResource icon; + private Mock logger; + private Mock nativeMethods; + private Mock process; + private ExternalApplicationInstance sut; + + [TestInitialize] + public void Initialize() + { + icon = new NativeIconResource(); + logger = new Mock(); + nativeMethods = new Mock(); + process = new Mock(); + + sut = new ExternalApplicationInstance(icon, logger.Object, nativeMethods.Object, process.Object, 1); + } + + [TestMethod] + public void Terminate_MustDoNothingIfAlreadyTerminated() + { + process.SetupGet(p => p.HasTerminated).Returns(true); + + sut.Terminate(); + + process.Verify(p => p.TryClose(It.IsAny()), Times.Never()); + process.Verify(p => p.TryKill(It.IsAny()), Times.Never()); + } + + [TestMethod] + public void Terminate_MustLogIfTerminationFailed() + { + process.Setup(p => p.TryClose(It.IsAny())).Returns(false); + process.Setup(p => p.TryKill(It.IsAny())).Returns(false); + process.SetupGet(p => p.HasTerminated).Returns(false); + + sut.Terminate(); + + logger.Verify(l => l.Warn(It.IsAny()), Times.AtLeastOnce); + process.Verify(p => p.TryClose(It.IsAny()), Times.AtLeastOnce()); + process.Verify(p => p.TryKill(It.IsAny()), Times.AtLeastOnce()); + } + } +} diff --git a/SafeExamBrowser.Applications.UnitTests/ExternalApplicationTests.cs b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationTests.cs index 25655679..377bad56 100644 --- a/SafeExamBrowser.Applications.UnitTests/ExternalApplicationTests.cs +++ b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationTests.cs @@ -82,6 +82,18 @@ namespace SafeExamBrowser.Applications.UnitTests Assert.IsTrue(windows.Any(w => w.Handle == new IntPtr(234))); Assert.IsTrue(windows.Any(w => w.Handle == new IntPtr(345))); Assert.IsTrue(windows.Any(w => w.Handle == new IntPtr(567))); + + nativeMethods.Setup(n => n.GetOpenWindows()).Returns(openWindows.Take(4)); + process2.Raise(p => p.Terminated += null, default(int)); + + sync.WaitOne(); + + windows = sut.GetWindows(); + + Assert.AreEqual(2, windows.Count()); + Assert.IsTrue(windows.Any(w => w.Handle == new IntPtr(234))); + Assert.IsTrue(windows.Any(w => w.Handle == new IntPtr(345))); + Assert.IsTrue(windows.All(w => w.Handle != new IntPtr(567))); } [TestMethod] @@ -127,7 +139,7 @@ namespace SafeExamBrowser.Applications.UnitTests [TestMethod] public void Start_MustRemoveInstanceCorrectlyWhenTerminated() { - var eventRaised = false; + var eventCount = 0; var openWindows = new List { new IntPtr(123), new IntPtr(234), new IntPtr(456), new IntPtr(345), new IntPtr(567), new IntPtr(789), }; var process = new Mock(); var sync = new AutoResetEvent(false); @@ -141,7 +153,7 @@ namespace SafeExamBrowser.Applications.UnitTests sut.WindowsChanged += () => { - eventRaised = true; + eventCount++; sync.Set(); }; @@ -154,7 +166,7 @@ namespace SafeExamBrowser.Applications.UnitTests process.Raise(p => p.Terminated += null, default(int)); - Assert.IsTrue(eventRaised); + Assert.AreEqual(2, eventCount); Assert.AreEqual(0, sut.GetWindows().Count()); } diff --git a/SafeExamBrowser.Applications.UnitTests/ExternalApplicationWindowTests.cs b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationWindowTests.cs index 5f903364..625aa112 100644 --- a/SafeExamBrowser.Applications.UnitTests/ExternalApplicationWindowTests.cs +++ b/SafeExamBrowser.Applications.UnitTests/ExternalApplicationWindowTests.cs @@ -47,12 +47,16 @@ namespace SafeExamBrowser.Applications.UnitTests var titleChanged = false; nativeMethods.Setup(m => m.GetWindowIcon(It.IsAny())).Returns(new IntPtr(456)); + nativeMethods.Setup(m => m.GetWindowTitle((It.IsAny()))).Returns("Some New Window Title"); sut.IconChanged += (_) => iconChanged = true; sut.TitleChanged += (_) => titleChanged = true; sut.Update(); + nativeMethods.Verify(m => m.GetWindowIcon(handle), Times.Once); + nativeMethods.Verify(m => m.GetWindowTitle(handle), Times.Once); + Assert.IsTrue(iconChanged); Assert.IsTrue(titleChanged); } diff --git a/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj b/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj index 9b91d040..b6188691 100644 --- a/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj +++ b/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj @@ -85,6 +85,7 @@ + diff --git a/SafeExamBrowser.Applications/ExternalApplicationInstance.cs b/SafeExamBrowser.Applications/ExternalApplicationInstance.cs index a83288a7..12ad0869 100644 --- a/SafeExamBrowser.Applications/ExternalApplicationInstance.cs +++ b/SafeExamBrowser.Applications/ExternalApplicationInstance.cs @@ -162,8 +162,11 @@ namespace SafeExamBrowser.Applications private void FinalizeEvents() { - timer.Elapsed -= Timer_Elapsed; - timer.Stop(); + if (timer != default) + { + timer.Elapsed -= Timer_Elapsed; + timer.Stop(); + } process.Terminated -= Process_Terminated; }