From da2c7093602ea18798510d03f42fd340655b83e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20B=C3=BCchel?= <damian.buechel@let.ethz.ch> Date: Mon, 19 Jul 2021 14:59:57 +0200 Subject: [PATCH] Extended unit tests for browser handlers. --- .../Handlers/DisplayHandlerTests.cs | 3 + .../Handlers/KeyboardHandlerTests.cs | 42 ++++++- .../Handlers/RequestHandlerTests.cs | 58 ++++++++++ .../Handlers/ResourceHandlerTests.cs | 107 ++++++++++++++++++ 4 files changed, 208 insertions(+), 2 deletions(-) diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/DisplayHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/DisplayHandlerTests.cs index cb724139..443d6d81 100644 --- a/SafeExamBrowser.Browser.UnitTests/Handlers/DisplayHandlerTests.cs +++ b/SafeExamBrowser.Browser.UnitTests/Handlers/DisplayHandlerTests.cs @@ -6,8 +6,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using System; using System.Collections.Generic; using CefSharp; +using CefSharp.Enums; using CefSharp.Structs; using Microsoft.VisualStudio.TestTools.UnitTesting; using SafeExamBrowser.Browser.Handlers; @@ -32,6 +34,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers Assert.IsFalse(sut.OnAutoResize(default(IWebBrowser), default(IBrowser), default(Size))); Assert.IsFalse(sut.OnConsoleMessage(default(IWebBrowser), default(ConsoleMessageEventArgs))); + Assert.IsFalse(sut.OnCursorChange(default(IWebBrowser), default(IBrowser), default(IntPtr), default(CursorType), default(CursorInfo))); Assert.IsFalse(sut.OnTooltipChanged(default(IWebBrowser), ref text)); } diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/KeyboardHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/KeyboardHandlerTests.cs index df4cfcc1..d0e2430d 100644 --- a/SafeExamBrowser.Browser.UnitTests/Handlers/KeyboardHandlerTests.cs +++ b/SafeExamBrowser.Browser.UnitTests/Handlers/KeyboardHandlerTests.cs @@ -25,14 +25,52 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers } [TestMethod] - public void MustDetectReload() + public void MustDetectFindCommand() + { + var findRequested = false; + + sut.FindRequested += () => findRequested = true; + + var handled = sut.OnKeyEvent(default(IWebBrowser), default(IBrowser), KeyType.KeyUp, (int) Keys.F, default(int), CefEventFlags.ControlDown, default(bool)); + + Assert.IsTrue(findRequested); + Assert.IsFalse(handled); + + findRequested = false; + handled = sut.OnKeyEvent(default(IWebBrowser), default(IBrowser), default(KeyType), default(int), default(int), CefEventFlags.ControlDown, default(bool)); + + Assert.IsFalse(findRequested); + Assert.IsFalse(handled); + } + + [TestMethod] + public void MustDetectHomeNavigationCommand() + { + var homeRequested = false; + + sut.HomeNavigationRequested += () => homeRequested = true; + + var handled = sut.OnKeyEvent(default(IWebBrowser), default(IBrowser), KeyType.KeyUp, (int) Keys.Home, default(int), default(CefEventFlags), default(bool)); + + Assert.IsTrue(homeRequested); + Assert.IsFalse(handled); + + homeRequested = false; + handled = sut.OnKeyEvent(default(IWebBrowser), default(IBrowser), default(KeyType), default(int), default(int), default(CefEventFlags), default(bool)); + + Assert.IsFalse(homeRequested); + Assert.IsFalse(handled); + } + + [TestMethod] + public void MustDetectReloadCommand() { var isShortcut = default(bool); var reloadRequested = false; sut.ReloadRequested += () => reloadRequested = true; - var handled = sut.OnPreKeyEvent(default(IWebBrowser), default(IBrowser), KeyType.KeyUp, (int)Keys.F5, default(int), default(CefEventFlags), default(bool), ref isShortcut); + var handled = sut.OnPreKeyEvent(default(IWebBrowser), default(IBrowser), KeyType.KeyUp, (int) Keys.F5, default(int), default(CefEventFlags), default(bool), ref isShortcut); Assert.IsTrue(reloadRequested); Assert.IsTrue(handled); diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs index 45c9eae8..1b528c93 100644 --- a/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs +++ b/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using System; using CefSharp; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -49,6 +50,15 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers sut = new TestableRequestHandler(appConfig, filter.Object, logger.Object, resourceHandler, settings, windowSettings, text.Object); } + [TestMethod] + public void MustBlockSpecialWindowDispositions() + { + Assert.IsTrue(sut.OnOpenUrlFromTab(default(IWebBrowser), default(IBrowser), default(IFrame), default(string), WindowOpenDisposition.NewBackgroundTab, default(bool))); + Assert.IsTrue(sut.OnOpenUrlFromTab(default(IWebBrowser), default(IBrowser), default(IFrame), default(string), WindowOpenDisposition.NewPopup, default(bool))); + Assert.IsTrue(sut.OnOpenUrlFromTab(default(IWebBrowser), default(IBrowser), default(IFrame), default(string), WindowOpenDisposition.NewWindow, default(bool))); + Assert.IsTrue(sut.OnOpenUrlFromTab(default(IWebBrowser), default(IBrowser), default(IFrame), default(string), WindowOpenDisposition.SaveToDisk, default(bool))); + } + [TestMethod] public void MustDetectQuitUrl() { @@ -168,6 +178,44 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers Assert.IsFalse(eventFired); } + [TestMethod] + public void MustInitiateConfigurationFileDownload() + { + var browser = new Mock<IBrowser>(); + var host = new Mock<IBrowserHost>(); + var request = new Mock<IRequest>(); + + appConfig.ConfigurationFileExtension = ".xyz"; + appConfig.SebUriScheme = "abc"; + appConfig.SebUriSchemeSecure = "abcd"; + browser.Setup(b => b.GetHost()).Returns(host.Object); + request.SetupGet(r => r.Url).Returns($"{appConfig.SebUriScheme}://host.com/path/file{appConfig.ConfigurationFileExtension}"); + + var handled = sut.OnBeforeBrowse(Mock.Of<IWebBrowser>(), browser.Object, Mock.Of<IFrame>(), request.Object, false, false); + + host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttp}://host.com/path/file{appConfig.ConfigurationFileExtension}"))); + Assert.IsTrue(handled); + + handled = false; + host.Reset(); + request.Reset(); + request.SetupGet(r => r.Url).Returns($"{appConfig.SebUriSchemeSecure}://host.com/path/file{appConfig.ConfigurationFileExtension}"); + + handled = sut.OnBeforeBrowse(Mock.Of<IWebBrowser>(), browser.Object, Mock.Of<IFrame>(), request.Object, false, false); + + host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttps}://host.com/path/file{appConfig.ConfigurationFileExtension}"))); + Assert.IsTrue(handled); + } + + [TestMethod] + public void MustReturnResourceHandler() + { + var disableDefaultHandling = default(bool); + var handler = sut.GetResourceRequestHandler(default(IWebBrowser), default(IBrowser), default(IFrame), default(IRequest), default(bool), default(bool), default(string), ref disableDefaultHandling); + + Assert.AreSame(resourceHandler, handler); + } + [TestMethod] public void MustUseProxyCredentials() { @@ -216,10 +264,20 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers return base.GetAuthCredentials(webBrowser, browser, originUrl, isProxy, host, port, realm, scheme, callback); } + public new IResourceRequestHandler GetResourceRequestHandler(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) + { + return base.GetResourceRequestHandler(webBrowser, browser, frame, request, isNavigation, isDownload, requestInitiator, ref disableDefaultHandling); + } + public new bool OnBeforeBrowse(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect) { return base.OnBeforeBrowse(webBrowser, browser, frame, request, userGesture, isRedirect); } + + public new bool OnOpenUrlFromTab(IWebBrowser webBrowser, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) + { + return base.OnOpenUrlFromTab(webBrowser, browser, frame, targetUrl, targetDisposition, userGesture); + } } } } diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs index 5057e882..1665bee0 100644 --- a/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs +++ b/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Specialized; using System.Net.Mime; +using System.Threading; using CefSharp; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -128,6 +129,12 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers Assert.IsNotNull(resourceHandler); } + [TestMethod] + public void MustLetOperatingSystemHandleUnknownProtocols() + { + Assert.IsTrue(sut.OnProtocolExecution(default(IWebBrowser), default(IBrowser), default(IFrame), default(IRequest))); + } + [TestMethod] public void MustRedirectToDisablePdfToolbar() { @@ -183,6 +190,96 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers Assert.AreEqual("https://www.host.org/", url); } + [TestMethod] + public void MustSearchGenericLmsSessionIdentifier() + { + var @event = new AutoResetEvent(false); + var headers = new NameValueCollection(); + var newUrl = default(string); + var request = new Mock<IRequest>(); + var response = new Mock<IResponse>(); + var sessionId = default(string); + + headers.Add("X-LMS-USER-ID", "some-session-id-123"); + request.SetupGet(r => r.Url).Returns("https://www.somelms.org"); + response.SetupGet(r => r.Headers).Returns(headers); + sut.SessionIdentifierDetected += (id) => + { + sessionId = id; + @event.Set(); + }; + + sut.OnResourceRedirect(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), Mock.Of<IRequest>(), response.Object, ref newUrl); + @event.WaitOne(); + Assert.AreEqual("some-session-id-123", sessionId); + + sessionId = default(string); + + sut.OnResourceResponse(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), request.Object, response.Object); + @event.WaitOne(); + Assert.AreEqual("some-session-id-123", sessionId); + } + + [TestMethod] + public void MustSearchEdxSessionIdentifier() + { + var @event = new AutoResetEvent(false); + var headers = new NameValueCollection(); + var newUrl = default(string); + var request = new Mock<IRequest>(); + var response = new Mock<IResponse>(); + var sessionId = default(string); + + headers.Add("Set-Cookie", "edx-user-info=\"{\\\"username\\\": \\\"edx-123\\\"}\"; expires"); + request.SetupGet(r => r.Url).Returns("https://www.somelms.org"); + response.SetupGet(r => r.Headers).Returns(headers); + sut.SessionIdentifierDetected += (id) => + { + sessionId = id; + @event.Set(); + }; + + sut.OnResourceRedirect(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), Mock.Of<IRequest>(), response.Object, ref newUrl); + @event.WaitOne(); + Assert.AreEqual("edx-123", sessionId); + + sessionId = default(string); + + sut.OnResourceResponse(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), request.Object, response.Object); + @event.WaitOne(); + Assert.AreEqual("edx-123", sessionId); + } + + [TestMethod] + public void MustSearchMoodleSessionIdentifier() + { + var @event = new AutoResetEvent(false); + var headers = new NameValueCollection(); + var newUrl = default(string); + var request = new Mock<IRequest>(); + var response = new Mock<IResponse>(); + var sessionId = default(string); + + headers.Add("Location", "https://www.some-moodle-instance.org/moodle/login/index.php?testsession=123"); + request.SetupGet(r => r.Url).Returns("https://www.some-moodle-instance.org"); + response.SetupGet(r => r.Headers).Returns(headers); + sut.SessionIdentifierDetected += (id) => + { + sessionId = id; + @event.Set(); + }; + + sut.OnResourceRedirect(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), Mock.Of<IRequest>(), response.Object, ref newUrl); + @event.WaitOne(); + Assert.AreEqual("123", sessionId); + + sessionId = default(string); + + sut.OnResourceResponse(Mock.Of<IWebBrowser>(), Mock.Of<IBrowser>(), Mock.Of<IFrame>(), request.Object, response.Object); + @event.WaitOne(); + Assert.AreEqual("123", sessionId); + } + private class TestableResourceHandler : ResourceHandler { internal TestableResourceHandler( @@ -205,6 +302,16 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback); } + public new bool OnProtocolExecution(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request) + { + return base.OnProtocolExecution(webBrowser, browser, frame, request); + } + + public new void OnResourceRedirect(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) + { + base.OnResourceRedirect(webBrowser, browser, frame, request, response, ref newUrl); + } + public new bool OnResourceResponse(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return base.OnResourceResponse(webBrowser, browser, frame, request, response);