/* * Copyright (c) 2019 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.Collections.Generic; using System.IO; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using SafeExamBrowser.Configuration.ConfigurationData; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration.Cryptography; using SafeExamBrowser.Contracts.Configuration.DataFormats; using SafeExamBrowser.Contracts.Configuration.DataResources; using SafeExamBrowser.Contracts.Logging; namespace SafeExamBrowser.Configuration.UnitTests { [TestClass] public class ConfigurationRepositoryTests { private ConfigurationRepository sut; private Mock binaryParser; private Mock binarySerializer; private Mock certificateStore; private Mock fileLoader; private Mock fileSaver; private Mock hashAlgorithm; private Mock logger; private Mock networkLoader; private Mock xmlParser; private Mock xmlSerializer; [TestInitialize] public void Initialize() { var executablePath = Assembly.GetExecutingAssembly().Location; binaryParser = new Mock(); binarySerializer = new Mock(); certificateStore = new Mock(); fileLoader = new Mock(); fileSaver = new Mock(); hashAlgorithm = new Mock(); logger = new Mock(); networkLoader = new Mock(); xmlParser = new Mock(); xmlSerializer = new Mock(); fileLoader.Setup(f => f.CanLoad(It.IsAny())).Returns(u => u.IsFile); fileSaver.Setup(f => f.CanSave(It.IsAny())).Returns(u => u.IsFile); networkLoader.Setup(n => n.CanLoad(It.IsAny())).Returns(u => u.Scheme.Equals("http") || u.Scheme.Equals("seb")); sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object, executablePath, string.Empty, string.Empty, string.Empty); sut.InitializeAppConfig(); } [TestMethod] public void ConfigureClient_MustWorkAsExpected() { var stream = new MemoryStream() as Stream; var password = new PasswordParameters { Password = "test123" }; var parseResult = new ParseResult { Format = FormatType.Binary, RawData = new Dictionary(), Status = LoadStatus.Success }; var serializeResult = new SerializeResult { Data = new MemoryStream(), Status = SaveStatus.Success }; RegisterModules(); fileLoader.Setup(n => n.TryLoad(It.IsAny(), out stream)).Returns(LoadStatus.Success); binaryParser.Setup(b => b.CanParse(It.IsAny())).Returns(true); binaryParser.Setup(b => b.TryParse(It.IsAny(), It.IsAny())).Returns(parseResult); binarySerializer.Setup(b => b.CanSerialize(FormatType.Binary)).Returns(true); binarySerializer.Setup(b => b.TrySerialize(It.IsAny>(), It.IsAny())).Returns(serializeResult); fileSaver.Setup(f => f.TrySave(It.IsAny(), It.IsAny())).Returns(SaveStatus.Success); var status = sut.ConfigureClientWith(new Uri("C:\\TEMP\\Some\\file.seb"), password); fileLoader.Verify(n => n.TryLoad(It.IsAny(), out stream), Times.Once); binaryParser.Verify(b => b.TryParse(It.IsAny(), It.IsAny()), Times.Once); certificateStore.Verify(c => c.ExtractAndImportIdentities(It.IsAny>()), Times.Once); binarySerializer.Verify(b => b.TrySerialize( It.IsAny>(), It.Is(p => p.IsHash == true && p.Password == string.Empty)), Times.Once); fileSaver.Verify(f => f.TrySave(It.IsAny(), It.IsAny()), Times.Once); Assert.AreEqual(SaveStatus.Success, status); } [TestMethod] public void ConfigureClient_MustKeepSameEncryptionAccordingToConfiguration() { var stream = new MemoryStream() as Stream; var password = new PasswordParameters { Password = "test123" }; var parseResult = new ParseResult { Encryption = new PublicKeyParameters { InnerEncryption = password, SymmetricEncryption = true }, Format = FormatType.Binary, RawData = new Dictionary { { Keys.ConfigurationFile.KeepClientConfigEncryption, true } }, Status = LoadStatus.Success }; var serializeResult = new SerializeResult { Data = new MemoryStream(), Status = SaveStatus.Success }; RegisterModules(); fileLoader.Setup(n => n.TryLoad(It.IsAny(), out stream)).Returns(LoadStatus.Success); binaryParser.Setup(b => b.CanParse(It.IsAny())).Returns(true); binaryParser.Setup(b => b.TryParse(It.IsAny(), It.IsAny())).Returns(parseResult); binarySerializer.Setup(b => b.CanSerialize(FormatType.Binary)).Returns(true); binarySerializer.Setup(b => b.TrySerialize(It.IsAny>(), It.IsAny())).Returns(serializeResult); fileSaver.Setup(f => f.TrySave(It.IsAny(), It.IsAny())).Returns(SaveStatus.Success); var status = sut.ConfigureClientWith(new Uri("C:\\TEMP\\Some\\file.seb"), password); binarySerializer.Verify(b => b.TrySerialize( It.IsAny>(), It.Is(p => p.InnerEncryption == password && p.SymmetricEncryption)), Times.Once); Assert.AreEqual(SaveStatus.Success, status); } [TestMethod] public void ConfigureClient_MustAbortProcessOnError() { var stream = new MemoryStream() as Stream; var password = new PasswordParameters { Password = "test123" }; var parseResult = new ParseResult { Format = FormatType.Binary, RawData = new Dictionary(), Status = LoadStatus.Success }; var serializeResult = new SerializeResult { Data = new MemoryStream(), Status = SaveStatus.Success }; RegisterModules(); fileLoader.Setup(n => n.TryLoad(It.IsAny(), out stream)).Returns(LoadStatus.Success); binaryParser.Setup(b => b.CanParse(It.IsAny())).Throws(); var status = sut.ConfigureClientWith(new Uri("C:\\TEMP\\Some\\file.seb"), password); fileLoader.Verify(n => n.TryLoad(It.IsAny(), out stream), Times.Once); binaryParser.Verify(b => b.TryParse(It.IsAny(), It.IsAny()), Times.Never); certificateStore.Verify(c => c.ExtractAndImportIdentities(It.IsAny>()), Times.Never); binarySerializer.Verify(b => b.TrySerialize(It.IsAny>(), It.IsAny()), Times.Never); fileSaver.Verify(f => f.TrySave(It.IsAny(), It.IsAny()), Times.Never); Assert.AreEqual(SaveStatus.UnexpectedError, status); } [TestMethod] public void TryLoad_MustWorkAsExpected() { var stream = new MemoryStream() as Stream; var parseResult = new ParseResult { RawData = new Dictionary(), Status = LoadStatus.Success }; RegisterModules(); networkLoader.Setup(n => n.TryLoad(It.IsAny(), out stream)).Returns(LoadStatus.Success); binaryParser.Setup(b => b.CanParse(It.IsAny())).Returns(true); binaryParser.Setup(b => b.TryParse(It.IsAny(), It.IsAny())).Returns(parseResult); var result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); fileLoader.Verify(f => f.CanLoad(It.IsAny()), Times.Once); fileLoader.Verify(f => f.TryLoad(It.IsAny(), out stream), Times.Never); networkLoader.Verify(n => n.CanLoad(It.IsAny()), Times.Once); networkLoader.Verify(n => n.TryLoad(It.IsAny(), out stream), Times.Once); binaryParser.Verify(b => b.CanParse(It.IsAny()), Times.Once); binaryParser.Verify(b => b.TryParse(It.IsAny(), It.IsAny()), Times.Once); xmlParser.Verify(x => x.CanParse(It.IsAny()), Times.AtMostOnce); xmlParser.Verify(x => x.TryParse(It.IsAny(), It.IsAny()), Times.Never); Assert.AreEqual(LoadStatus.Success, result); } [TestMethod] public void TryLoad_MustReportPasswordNeed() { var stream = new MemoryStream() as Stream; var parseResult = new ParseResult { Status = LoadStatus.PasswordNeeded }; RegisterModules(); networkLoader.Setup(n => n.TryLoad(It.IsAny(), out stream)).Returns(LoadStatus.Success); binaryParser.Setup(b => b.CanParse(It.IsAny())).Returns(true); binaryParser.Setup(b => b.TryParse(It.IsAny(), It.IsAny())).Returns(parseResult); var result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); Assert.AreEqual(LoadStatus.PasswordNeeded, result); } [TestMethod] public void TryLoad_MustNotFailToIfNoLoaderRegistered() { var result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); Assert.AreEqual(LoadStatus.NotSupported, result); sut.Register(fileLoader.Object); sut.Register(networkLoader.Object); result = sut.TryLoadSettings(new Uri("ftp://www.blubb.org"), out _); fileLoader.Verify(f => f.CanLoad(It.IsAny()), Times.Once); networkLoader.Verify(n => n.CanLoad(It.IsAny()), Times.Once); Assert.AreEqual(LoadStatus.NotSupported, result); } [TestMethod] public void TryLoad_MustNotFailIfNoParserRegistered() { var data = default(Stream); networkLoader.Setup(l => l.TryLoad(It.IsAny(), out data)).Returns(LoadStatus.Success); sut.Register(networkLoader.Object); var result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); networkLoader.Verify(n => n.TryLoad(It.IsAny(), out data), Times.Once); Assert.AreEqual(LoadStatus.NotSupported, result); } [TestMethod] public void TryLoad_MustNotFailInCaseOfUnexpectedError() { var data = default(Stream); networkLoader.Setup(l => l.TryLoad(It.IsAny(), out data)).Throws(); sut.Register(networkLoader.Object); var result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); Assert.AreEqual(LoadStatus.UnexpectedError, result); binaryParser.Setup(b => b.CanParse(It.IsAny())).Throws(); networkLoader.Setup(l => l.TryLoad(It.IsAny(), out data)).Returns(LoadStatus.Success); sut.Register(binaryParser.Object); result = sut.TryLoadSettings(new Uri("http://www.blubb.org"), out _); Assert.AreEqual(LoadStatus.UnexpectedError, result); } [TestMethod] public void MustInitializeSessionConfiguration() { var appConfig = sut.InitializeAppConfig(); var configuration = sut.InitializeSessionConfiguration(); Assert.IsInstanceOfType(configuration.AppConfig, typeof(AppConfig)); Assert.IsInstanceOfType(configuration.Id, typeof(Guid)); Assert.IsNull(configuration.Settings); Assert.IsInstanceOfType(configuration.StartupToken, typeof(Guid)); } [TestMethod] public void MustUpdateAppConfig() { var appConfig = sut.InitializeAppConfig(); var clientAddress = appConfig.ClientAddress; var clientId = appConfig.ClientId; var clientLogFilePath = appConfig.ClientLogFilePath; var runtimeAddress = appConfig.RuntimeAddress; var runtimeId = appConfig.RuntimeId; var runtimeLogFilePath = appConfig.RuntimeLogFilePath; var configuration = sut.InitializeSessionConfiguration(); Assert.AreNotEqual(configuration.AppConfig.ClientAddress, clientAddress); Assert.AreNotEqual(configuration.AppConfig.ClientId, clientId); Assert.AreEqual(configuration.AppConfig.ClientLogFilePath, clientLogFilePath); Assert.AreEqual(configuration.AppConfig.RuntimeAddress, runtimeAddress); Assert.AreEqual(configuration.AppConfig.RuntimeId, runtimeId); Assert.AreEqual(configuration.AppConfig.RuntimeLogFilePath, runtimeLogFilePath); } [TestMethod] public void MustUpdateSessionConfiguration() { var appConfig = sut.InitializeAppConfig(); var firstSession = sut.InitializeSessionConfiguration(); var secondSession = sut.InitializeSessionConfiguration(); var thirdSession = sut.InitializeSessionConfiguration(); Assert.AreNotEqual(firstSession.Id, secondSession.Id); Assert.AreNotEqual(firstSession.StartupToken, secondSession.StartupToken); Assert.AreNotEqual(secondSession.Id, thirdSession.Id); Assert.AreNotEqual(secondSession.StartupToken, thirdSession.StartupToken); } private void RegisterModules() { sut.Register(binaryParser.Object); sut.Register(binarySerializer.Object); sut.Register(fileLoader.Object); sut.Register(fileSaver.Object); sut.Register(networkLoader.Object); sut.Register(xmlParser.Object); sut.Register(xmlSerializer.Object); } } }