seb-win-refactoring/SafeExamBrowser.Service.UnitTests/Operations/LockdownOperationTests.cs
2021-02-03 00:45:33 +01:00

258 lines
12 KiB
C#

/*
* Copyright (c) 2021 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.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Lockdown.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Service.Operations;
using SafeExamBrowser.Settings;
namespace SafeExamBrowser.Service.UnitTests.Operations
{
[TestClass]
public class LockdownOperationTests
{
private Mock<IFeatureConfigurationBackup> backup;
private Mock<IFeatureConfigurationFactory> factory;
private Mock<IFeatureConfigurationMonitor> monitor;
private Mock<ILogger> logger;
private AppSettings settings;
private SessionContext sessionContext;
private LockdownOperation sut;
[TestInitialize]
public void Initialize()
{
backup = new Mock<IFeatureConfigurationBackup>();
factory = new Mock<IFeatureConfigurationFactory>();
monitor = new Mock<IFeatureConfigurationMonitor>();
logger = new Mock<ILogger>();
settings = new AppSettings();
sessionContext = new SessionContext
{
Configuration = new ServiceConfiguration { Settings = settings, UserName = "TestName", UserSid = "S-1-234-TEST" }
};
sut = new LockdownOperation(backup.Object, factory.Object, monitor.Object, logger.Object, sessionContext);
}
[TestMethod]
public void Perform_MustSetConfigurationsCorrectly()
{
var configuration = new Mock<IFeatureConfiguration>();
var count = typeof(IFeatureConfigurationFactory).GetMethods().Where(m => m.Name.StartsWith("Create") && m.Name != nameof(IFeatureConfigurationFactory.CreateAll)).Count();
configuration.SetReturnsDefault(true);
factory.SetReturnsDefault(configuration.Object);
settings.Service.DisableChromeNotifications = true;
settings.Service.DisableEaseOfAccessOptions = true;
settings.Service.DisableSignout = true;
settings.Service.SetVmwareConfiguration = true;
var result = sut.Perform();
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(c => c == configuration.Object)), Times.Exactly(count));
configuration.Verify(c => c.Initialize(), Times.Exactly(count));
configuration.Verify(c => c.DisableFeature(), Times.Exactly(3));
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - 3));
monitor.Verify(m => m.Observe(It.Is<IFeatureConfiguration>(c => c == configuration.Object), It.Is<FeatureConfigurationStatus>(s => s == FeatureConfigurationStatus.Disabled)), Times.Exactly(3));
monitor.Verify(m => m.Observe(It.Is<IFeatureConfiguration>(c => c == configuration.Object), It.Is<FeatureConfigurationStatus>(s => s == FeatureConfigurationStatus.Enabled)), Times.Exactly(count - 3));
monitor.Verify(m => m.Start(), Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void Perform_MustOnlySetVmwareConfigurationIfEnabled()
{
var configuration = new Mock<IFeatureConfiguration>();
configuration.SetReturnsDefault(true);
factory.SetReturnsDefault(configuration.Object);
settings.Service.SetVmwareConfiguration = true;
sut.Perform();
factory.Verify(f => f.CreateVmwareOverlayConfiguration(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Reset();
factory.SetReturnsDefault(configuration.Object);
settings.Service.SetVmwareConfiguration = false;
sut.Perform();
factory.Verify(f => f.CreateVmwareOverlayConfiguration(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
[TestMethod]
public void Perform_MustUseSameGroupForAllConfigurations()
{
var configuration = new Mock<IFeatureConfiguration>();
var groupId = default(Guid);
configuration.SetReturnsDefault(true);
factory
.Setup(f => f.CreateChromeNotificationConfiguration(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(configuration.Object)
.Callback<Guid, string, string>((id, name, sid) => groupId = id);
factory.SetReturnsDefault(configuration.Object);
settings.Service.SetVmwareConfiguration = true;
sut.Perform();
factory.Verify(f => f.CreateChangePasswordConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateChromeNotificationConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateEaseOfAccessConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateLockWorkstationConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateMachinePowerOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateNetworkOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateRemoteConnectionConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateSignoutConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateSwitchUserConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateTaskManagerConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateUserPowerOptionsConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateVmwareOverlayConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateWindowsUpdateConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
}
[TestMethod]
public void Perform_MustImmediatelyAbortOnFailure()
{
var configuration = new Mock<IFeatureConfiguration>();
var count = typeof(IFeatureConfigurationFactory).GetMethods().Where(m => m.Name.StartsWith("Create") && m.Name != nameof(IFeatureConfigurationFactory.CreateAll)).Count();
var counter = 0;
var offset = 3;
configuration.Setup(c => c.EnableFeature()).Returns(() => ++counter < count - offset);
factory.SetReturnsDefault(configuration.Object);
var result = sut.Perform();
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(c => c == configuration.Object)), Times.Exactly(count - offset));
configuration.Verify(c => c.Initialize(), Times.Exactly(count - offset));
configuration.Verify(c => c.DisableFeature(), Times.Never);
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - offset));
monitor.Verify(m => m.Observe(It.Is<IFeatureConfiguration>(c => c == configuration.Object), It.Is<FeatureConfigurationStatus>(s => s == FeatureConfigurationStatus.Enabled)), Times.Exactly(count - offset - 1));
monitor.Verify(m => m.Start(), Times.Never);
Assert.AreEqual(OperationResult.Failed, result);
}
[TestMethod]
public void Revert_MustRestoreConfigurationsCorrectly()
{
var configuration1 = new Mock<IFeatureConfiguration>();
var configuration2 = new Mock<IFeatureConfiguration>();
var configuration3 = new Mock<IFeatureConfiguration>();
var configuration4 = new Mock<IFeatureConfiguration>();
var configurations = new List<IFeatureConfiguration>
{
configuration1.Object,
configuration2.Object,
configuration3.Object,
configuration4.Object
};
backup.Setup(b => b.GetBy(It.IsAny<Guid>())).Returns(configurations);
configuration1.Setup(c => c.Restore()).Returns(true);
configuration2.Setup(c => c.Restore()).Returns(true);
configuration3.Setup(c => c.Restore()).Returns(true);
configuration4.Setup(c => c.Restore()).Returns(true);
var result = sut.Revert();
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration1.Object)), Times.Once);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration2.Object)), Times.Once);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration3.Object)), Times.Once);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration4.Object)), Times.Once);
configuration1.Verify(c => c.DisableFeature(), Times.Never);
configuration1.Verify(c => c.EnableFeature(), Times.Never);
configuration1.Verify(c => c.Initialize(), Times.Never);
configuration1.Verify(c => c.Restore(), Times.Once);
configuration2.Verify(c => c.DisableFeature(), Times.Never);
configuration2.Verify(c => c.EnableFeature(), Times.Never);
configuration2.Verify(c => c.Initialize(), Times.Never);
configuration2.Verify(c => c.Restore(), Times.Once);
configuration3.Verify(c => c.DisableFeature(), Times.Never);
configuration3.Verify(c => c.EnableFeature(), Times.Never);
configuration3.Verify(c => c.Initialize(), Times.Never);
configuration3.Verify(c => c.Restore(), Times.Once);
configuration4.Verify(c => c.DisableFeature(), Times.Never);
configuration4.Verify(c => c.EnableFeature(), Times.Never);
configuration4.Verify(c => c.Initialize(), Times.Never);
configuration4.Verify(c => c.Restore(), Times.Once);
monitor.Verify(m => m.Reset(), Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void Revert_MustContinueToRevertOnFailure()
{
var configuration1 = new Mock<IFeatureConfiguration>();
var configuration2 = new Mock<IFeatureConfiguration>();
var configuration3 = new Mock<IFeatureConfiguration>();
var configuration4 = new Mock<IFeatureConfiguration>();
var configurations = new List<IFeatureConfiguration>
{
configuration1.Object,
configuration2.Object,
configuration3.Object,
configuration4.Object
};
backup.Setup(b => b.GetBy(It.IsAny<Guid>())).Returns(configurations);
configuration1.Setup(c => c.Restore()).Returns(true);
configuration2.Setup(c => c.Restore()).Returns(false);
configuration3.Setup(c => c.Restore()).Returns(false);
configuration4.Setup(c => c.Restore()).Returns(true);
var result = sut.Revert();
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration1.Object)), Times.Once);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration2.Object)), Times.Never);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration3.Object)), Times.Never);
backup.Verify(b => b.Delete(It.Is<IFeatureConfiguration>(c => c == configuration4.Object)), Times.Once);
configuration1.Verify(c => c.DisableFeature(), Times.Never);
configuration1.Verify(c => c.EnableFeature(), Times.Never);
configuration1.Verify(c => c.Initialize(), Times.Never);
configuration1.Verify(c => c.Restore(), Times.Once);
configuration2.Verify(c => c.DisableFeature(), Times.Never);
configuration2.Verify(c => c.EnableFeature(), Times.Never);
configuration2.Verify(c => c.Initialize(), Times.Never);
configuration2.Verify(c => c.Restore(), Times.Once);
configuration3.Verify(c => c.DisableFeature(), Times.Never);
configuration3.Verify(c => c.EnableFeature(), Times.Never);
configuration3.Verify(c => c.Initialize(), Times.Never);
configuration3.Verify(c => c.Restore(), Times.Once);
configuration4.Verify(c => c.DisableFeature(), Times.Never);
configuration4.Verify(c => c.EnableFeature(), Times.Never);
configuration4.Verify(c => c.Initialize(), Times.Never);
configuration4.Verify(c => c.Restore(), Times.Once);
monitor.Verify(m => m.Reset(), Times.Once);
Assert.AreEqual(OperationResult.Failed, result);
}
}
}