Add unit tests.

This commit is contained in:
Jared Goodwin 2023-06-22 13:40:05 -07:00
parent 3bb5098910
commit 0b8123ad1e
19 changed files with 761 additions and 169 deletions

View File

@ -30,11 +30,11 @@ namespace Remotely.Server.API
private readonly ILogger<AgentUpdateController> _logger;
private readonly IApplicationConfig _appConfig;
private readonly IWebHostEnvironment _hostEnv;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _serviceSessionCache;
public AgentUpdateController(IWebHostEnvironment hostingEnv,
IApplicationConfig appConfig,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache serviceSessionCache,
IHubContext<AgentHub> agentHubContext,
ILogger<AgentUpdateController> logger)
{

View File

@ -28,7 +28,7 @@ namespace Remotely.Server.API
{
private readonly IHubContext<AgentHub> _serviceHub;
private readonly IDesktopHubSessionCache _desktopSessionCache;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _serviceSessionCache;
private readonly IApplicationConfig _appConfig;
private readonly IOtpProvider _otpProvider;
private readonly IHubEventHandler _hubEvents;
@ -41,7 +41,7 @@ namespace Remotely.Server.API
IDataService dataService,
IDesktopHubSessionCache desktopSessionCache,
IHubContext<AgentHub> serviceHub,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache serviceSessionCache,
IOtpProvider otpProvider,
IHubEventHandler hubEvents,
IApplicationConfig appConfig,

View File

@ -25,14 +25,14 @@ namespace Remotely.Server.API
private readonly IHubContext<AgentHub> _agentHubContext;
private readonly IDataService _dataService;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _serviceSessionCache;
private readonly IExpiringTokenService _expiringTokenService;
private readonly UserManager<RemotelyUser> _userManager;
public ScriptingController(UserManager<RemotelyUser> userManager,
IDataService dataService,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache serviceSessionCache,
IExpiringTokenService expiringTokenService,
IHubContext<AgentHub> agentHub)
{

View File

@ -59,7 +59,7 @@ namespace Remotely.Server.Components.Devices
private IModalService ModalService { get; set; }
[Inject]
private IServiceHubSessionCache ServiceSessionCache { get; init; }
private IAgentHubSessionCache ServiceSessionCache { get; init; }
[Inject]
private IToastService ToastService { get; set; }

View File

@ -43,7 +43,7 @@ namespace Remotely.Server.Components.Scripts
private IToastService ToastService { get; set; }
[Inject]
private IServiceHubSessionCache ServiceSessionCache { get; init; }
private IAgentHubSessionCache ServiceSessionCache { get; init; }
[Inject]
private ICircuitConnection CircuitConnection { get; set; }

View File

@ -24,12 +24,12 @@ namespace Remotely.Server.Hubs
private readonly IDataService _dataService;
private readonly IExpiringTokenService _expiringTokenService;
private readonly ILogger<AgentHub> _logger;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _serviceSessionCache;
private readonly IHubContext<ViewerHub> _viewerHubContext;
public AgentHub(IDataService dataService,
IApplicationConfig appConfig,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache serviceSessionCache,
IHubContext<ViewerHub> viewerHubContext,
ICircuitManager circuitManager,
IExpiringTokenService expiringTokenService,

View File

@ -83,7 +83,7 @@ namespace Remotely.Server.Hubs
private readonly ConcurrentQueue<CircuitEvent> _eventQueue = new();
private readonly IExpiringTokenService _expiringTokenService;
private readonly ILogger<CircuitConnection> _logger;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _agentSessionCache;
private readonly IToastService _toastService;
public CircuitConnection(
IAuthService authService,
@ -95,7 +95,7 @@ namespace Remotely.Server.Hubs
IToastService toastService,
IExpiringTokenService expiringTokenService,
IDesktopHubSessionCache desktopSessionCache,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache agentSessionCache,
ILogger<CircuitConnection> logger)
{
_dataService = dataService;
@ -107,7 +107,7 @@ namespace Remotely.Server.Hubs
_toastService = toastService;
_expiringTokenService = expiringTokenService;
_desktopSessionCache = desktopSessionCache;
_serviceSessionCache = serviceSessionCache;
_agentSessionCache = agentSessionCache;
_logger = logger;
}
@ -115,7 +115,7 @@ namespace Remotely.Server.Hubs
public event EventHandler<CircuitEvent> MessageReceived;
public string ConnectionId { get; set; }
public RemotelyUser User { get; set; }
public RemotelyUser User { get; internal set; }
public Task DeleteRemoteLogs(string deviceId)
@ -223,7 +223,7 @@ namespace Remotely.Server.Hubs
public async Task<Result<RemoteControlSessionEx>> RemoteControl(string deviceId, bool viewOnly)
{
if (!_serviceSessionCache.TryGetByDeviceId(deviceId, out var targetDevice))
if (!_agentSessionCache.TryGetByDeviceId(deviceId, out var targetDevice))
{
MessageReceived?.Invoke(this, new CircuitEvent(CircuitEventName.DisplayMessage,
"The selected device is not online.",
@ -257,7 +257,7 @@ namespace Remotely.Server.Hubs
return Result.Fail<RemoteControlSessionEx>("Max number of concurrent sessions reached.");
}
if (!_serviceSessionCache.TryGetConnectionId(targetDevice.ID, out var serviceConnectionId))
if (!_agentSessionCache.TryGetConnectionId(targetDevice.ID, out var serviceConnectionId))
{
MessageReceived?.Invoke(this, new CircuitEvent(CircuitEventName.DisplayMessage,
"Service connection not found.",
@ -317,7 +317,7 @@ namespace Remotely.Server.Hubs
var authToken = _expiringTokenService.GetToken(Time.Now.AddMinutes(AppConstants.ScriptRunExpirationMinutes));
var connectionIds = _serviceSessionCache.GetConnectionIdsByDeviceIds(deviceIds).ToArray();
var connectionIds = _agentSessionCache.GetConnectionIdsByDeviceIds(deviceIds).ToArray();
if (connectionIds.Any())
{
@ -333,8 +333,8 @@ namespace Remotely.Server.Hubs
return Task.CompletedTask;
}
if (!_serviceSessionCache.TryGetByDeviceId(deviceId, out var device) ||
!_serviceSessionCache.TryGetConnectionId(deviceId, out var connectionId))
if (!_agentSessionCache.TryGetByDeviceId(deviceId, out var device) ||
!_agentSessionCache.TryGetConnectionId(deviceId, out var connectionId))
{
_toastService.ShowToast("Device not found.");
return Task.CompletedTask;
@ -359,7 +359,7 @@ namespace Remotely.Server.Hubs
public async Task<bool> TransferFileFromBrowserToAgent(string deviceId, string transferId, string[] fileIds)
{
if (!_serviceSessionCache.TryGetConnectionId(deviceId, out var connectionId))
if (!_agentSessionCache.TryGetConnectionId(deviceId, out var connectionId))
{
return false;
}
@ -454,11 +454,11 @@ namespace Remotely.Server.Hubs
return Result.Fail("Unauthorized.") ;
}
var availableDevices = _serviceSessionCache
var availableDevices = _agentSessionCache
.GetAllDevices()
.Where(x =>
x.OrganizationID == User.OrganizationID &&
(x.DeviceGroup == device.DeviceGroup || x.PublicIP == device.PublicIP))
(x.DeviceGroupID == device.DeviceGroupID || x.PublicIP == device.PublicIP))
.ToArray();
await SendWakeCommand(device, availableDevices);
@ -480,22 +480,21 @@ namespace Remotely.Server.Hubs
var filteredIds = _dataService.FilterDeviceIDsByUserPermission(deviceIds, User);
var filteredDevices = devices.Where(x => filteredIds.Contains(x.ID)).ToArray();
var availableDevices = _serviceSessionCache
var availableDevices = _agentSessionCache
.GetAllDevices()
.Where(x => x.OrganizationID == User.OrganizationID);
var devicesById = new ConcurrentDictionary<string, Device>();
var devicesByGroupId = new ConcurrentDictionary<string, List<Device>>();
var devicesByPublicIp = new ConcurrentDictionary<string, List<Device>>();
foreach (var device in availableDevices)
{
devicesById.AddOrUpdate(device.ID, device, (k, v) => device);
if (!string.IsNullOrWhiteSpace(device.DeviceGroupID))
{
var group = devicesByGroupId.GetOrAdd(device.DeviceGroupID, key => new());
group.Add(device);
// We only need the device in one group.
break;
}
if (!string.IsNullOrWhiteSpace(device.PublicIP))
@ -536,9 +535,9 @@ namespace Remotely.Server.Hubs
return (false, string.Empty);
}
if (!_serviceSessionCache.TryGetByDeviceId(deviceId, out var device) ||
if (!_agentSessionCache.TryGetByDeviceId(deviceId, out var device) ||
!_dataService.DoesUserHaveAccessToDevice(device.ID, User) ||
!_serviceSessionCache.TryGetConnectionId(device.ID, out var connectionId))
!_agentSessionCache.TryGetConnectionId(device.ID, out var connectionId))
{
return (false, string.Empty);
}
@ -552,7 +551,7 @@ namespace Remotely.Server.Hubs
foreach (var deviceId in deviceIds)
{
if (!_serviceSessionCache.TryGetByDeviceId(deviceId, out var device))
if (!_agentSessionCache.TryGetByDeviceId(deviceId, out var device))
{
continue;
}
@ -562,7 +561,7 @@ namespace Remotely.Server.Hubs
continue;
}
if (_serviceSessionCache.TryGetConnectionId(device.ID, out var connectionId))
if (_agentSessionCache.TryGetConnectionId(device.ID, out var connectionId))
{
yield return connectionId;
}
@ -593,7 +592,7 @@ namespace Remotely.Server.Hubs
{
foreach (var mac in deviceToWake.MacAddresses ?? Array.Empty<string>())
{
if (_serviceSessionCache.TryGetConnectionId(peerDevice.ID, out var connectionId))
if (_agentSessionCache.TryGetConnectionId(peerDevice.ID, out var connectionId))
{
_logger.LogInformation(
"Sending wake command for device {deviceName} ({deviceId}) to " +

View File

@ -162,7 +162,7 @@ namespace Remotely.Server.Pages
private ILogger<ServerConfig> Logger { get; set; }
[Inject]
private IServiceHubSessionCache ServiceSessionCache { get; init; }
private IAgentHubSessionCache ServiceSessionCache { get; init; }
private AppSettingsModel Input { get; } = new();

View File

@ -228,7 +228,7 @@ services.AddRemoteControlServer(config =>
config.AddViewerPageDataProvider<ViewerPageDataProvider>();
});
services.AddSingleton<IServiceHubSessionCache, ServiceHubSessionCache>();
services.AddSingleton<IAgentHubSessionCache, AgentHubSessionCache>();
var app = builder.Build();
var appConfig = app.Services.GetRequiredService<IApplicationConfig>();

View File

@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Remotely.Server.Tests")]

View File

@ -6,7 +6,7 @@ using System.Linq;
namespace Remotely.Server.Services
{
public interface IServiceHubSessionCache
public interface IAgentHubSessionCache
{
void AddOrUpdateByConnectionId(string connectionId, Device device);
ICollection<Device> GetAllDevices();
@ -16,7 +16,7 @@ namespace Remotely.Server.Services
bool TryRemoveByConnectionId(string connectionId, out Device device);
}
public class ServiceHubSessionCache : IServiceHubSessionCache
public class AgentHubSessionCache : IAgentHubSessionCache
{
private readonly ConcurrentDictionary<string, Device> _connectionIdToDeviceLookup = new();

View File

@ -124,7 +124,11 @@ namespace Remotely.Server.Services
int GetDeviceCount(RemotelyUser user);
Task<DeviceGroup> GetDeviceGroup(string deviceGroupID);
Task<DeviceGroup> GetDeviceGroup(
string deviceGroupID,
bool includeDevices = false,
bool includeUsers = false);
DeviceGroup[] GetDeviceGroups(string username);
DeviceGroup[] GetDeviceGroupsForOrganization(string organizationId);
@ -348,6 +352,7 @@ namespace Remotely.Server.Services
resultDevice.TotalStorage = device.TotalStorage;
resultDevice.AgentVersion = device.AgentVersion;
resultDevice.MacAddresses = device.MacAddresses ?? Array.Empty<string>();
resultDevice.DeviceGroupID = device.DeviceGroupID;
resultDevice.LastOnline = DateTimeOffset.Now;
}
else
@ -922,7 +927,6 @@ namespace Remotely.Server.Services
device.ID == deviceID &&
(
remotelyUser.IsAdministrator ||
string.IsNullOrWhiteSpace(device.DeviceGroupID) ||
device.DeviceGroup.Users.Any(user => user.Id == remotelyUser.Id
)));
}
@ -948,7 +952,6 @@ namespace Remotely.Server.Services
deviceIDs.Contains(device.ID) &&
(
remotelyUser.IsAdministrator ||
string.IsNullOrWhiteSpace(device.DeviceGroupID) ||
device.DeviceGroup.Users.Any(user => user.Id == remotelyUser.Id
)))
.Select(x => x.ID)
@ -1168,10 +1171,25 @@ namespace Remotely.Server.Services
));
}
public async Task<DeviceGroup> GetDeviceGroup(string deviceGroupID)
public async Task<DeviceGroup> GetDeviceGroup(
string deviceGroupID,
bool includeDevices = false,
bool includeUsers = false)
{
using var dbContext = _appDbFactory.GetContext();
return await dbContext.DeviceGroups.FindAsync(deviceGroupID);
var query = dbContext.DeviceGroups.AsQueryable();
if (includeDevices)
{
query = query.Include(x => x.Devices);
}
if (includeUsers)
{
query = query.Include(x => x.Users);
}
return await query.FirstOrDefaultAsync(x => x.ID == deviceGroupID);
}
public DeviceGroup[] GetDeviceGroups(string username)

View File

@ -19,12 +19,12 @@ namespace Remotely.Server.Services
public class ScriptScheduleDispatcher : IScriptScheduleDispatcher
{
private readonly IDataService _dataService;
private readonly IServiceHubSessionCache _serviceSessionCache;
private readonly IAgentHubSessionCache _serviceSessionCache;
private readonly ICircuitConnection _circuitConnection;
private readonly ILogger<ScriptScheduleDispatcher> _logger;
public ScriptScheduleDispatcher(IDataService dataService,
IServiceHubSessionCache serviceSessionCache,
IAgentHubSessionCache serviceSessionCache,
ICircuitConnection circuitConnection,
ILogger<ScriptScheduleDispatcher> logger)
{

View File

@ -34,14 +34,14 @@ namespace Remotely.Tests
var circuitManager = new Mock<ICircuitManager>();
var circuitConnection = new Mock<ICircuitConnection>();
circuitManager.Setup(x => x.Connections).Returns(new[] { circuitConnection.Object });
circuitConnection.Setup(x => x.User).Returns(_testData.Admin1);
circuitConnection.Setup(x => x.User).Returns(_testData.Org1Admin1);
var appConfig = new Mock<IApplicationConfig>();
var viewerHub = new Mock<IHubContext<ViewerHub>>();
var expiringTokenService = new Mock<IExpiringTokenService>();
var serviceSessionCache = new Mock<IServiceHubSessionCache>();
var serviceSessionCache = new Mock<IAgentHubSessionCache>();
var logger = new Mock<ILogger<AgentHub>>();
appConfig.Setup(x => x.BannedDevices).Returns(new string[] { _testData.Device1.DeviceName });
appConfig.Setup(x => x.BannedDevices).Returns(new string[] { _testData.Org1Device1.DeviceName });
var hub = new AgentHub(
DataService,
@ -57,7 +57,7 @@ namespace Remotely.Tests
hubClients.Setup(x => x.Caller).Returns(caller.Object);
hub.Clients = hubClients.Object;
Assert.IsFalse(await hub.DeviceCameOnline(_testData.Device1));
Assert.IsFalse(await hub.DeviceCameOnline(_testData.Org1Device1));
hubClients.Verify(x => x.Caller, Times.Once);
caller.Verify(x => x.SendCoreAsync("UninstallAgent", It.IsAny<object[]>(), It.IsAny<CancellationToken>()), Times.Once);
}
@ -71,14 +71,14 @@ namespace Remotely.Tests
var circuitManager = new Mock<ICircuitManager>();
var circuitConnection = new Mock<ICircuitConnection>();
circuitManager.Setup(x => x.Connections).Returns(new[] { circuitConnection.Object });
circuitConnection.Setup(x => x.User).Returns(_testData.Admin1);
circuitConnection.Setup(x => x.User).Returns(_testData.Org1Admin1);
var appConfig = new Mock<IApplicationConfig>();
var viewerHub = new Mock<IHubContext<ViewerHub>>();
var expiringTokenService = new Mock<IExpiringTokenService>();
var serviceSessionCache = new Mock<IServiceHubSessionCache>();
var serviceSessionCache = new Mock<IAgentHubSessionCache>();
var logger = new Mock<ILogger<AgentHub>>();
appConfig.Setup(x => x.BannedDevices).Returns(new string[] { _testData.Device1.ID });
appConfig.Setup(x => x.BannedDevices).Returns(new string[] { _testData.Org1Device1.ID });
var hub = new AgentHub(
DataService,
@ -94,7 +94,7 @@ namespace Remotely.Tests
hubClients.Setup(x => x.Caller).Returns(caller.Object);
hub.Clients = hubClients.Object;
Assert.IsFalse(await hub.DeviceCameOnline(_testData.Device1));
Assert.IsFalse(await hub.DeviceCameOnline(_testData.Org1Device1));
hubClients.Verify(x => x.Caller, Times.Once);
caller.Verify(x => x.SendCoreAsync("UninstallAgent", It.IsAny<object[]>(), It.IsAny<CancellationToken>()), Times.Once);
}
@ -106,9 +106,10 @@ namespace Remotely.Tests
}
[TestInitialize]
public void TestInit()
public async Task TestInit()
{
_testData = new TestData();
await _testData.Init();
DataService = IoCActivator.ServiceProvider.GetRequiredService<IDataService>();
}

View File

@ -0,0 +1,442 @@
#nullable enable
using Castle.Core.Logging;
using Immense.RemoteControl.Server.Services;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Remotely.Server.Hubs;
using Remotely.Server.Services;
using Remotely.Server.Tests.Mocks;
using Remotely.Shared.Models;
using Remotely.Tests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Remotely.Server.Tests
{
[TestClass]
public class CircuitConnectionTests
{
#nullable disable
private TestData _testData;
private IDataService _dataService;
private Mock<IAuthService> _authService;
private Mock<IClientAppState> _clientAppState;
private HubContextFixture<AgentHub> _agentHubContextFixture;
private Mock<IApplicationConfig> _appConfig;
private Mock<ICircuitManager> _circuitManager;
private Mock<IToastService> _toastService;
private Mock<IExpiringTokenService> _expiringTokenService;
private Mock<IDesktopHubSessionCache> _desktopSessionCache;
private Mock<IAgentHubSessionCache> _agentSessionCache;
private Mock<ILogger<CircuitConnection>> _logger;
private CircuitConnection _circuitConnection;
#nullable enable
[TestInitialize]
public async Task Init()
{
_testData = new TestData();
await _testData.Init();
_dataService = IoCActivator.ServiceProvider.GetRequiredService<IDataService>();
_authService = new Mock<IAuthService>();
_clientAppState = new Mock<IClientAppState>();
_agentHubContextFixture = new HubContextFixture<AgentHub>();
_appConfig = new Mock<IApplicationConfig>();
_circuitManager = new Mock<ICircuitManager>();
_toastService = new Mock<IToastService>();
_expiringTokenService = new Mock<IExpiringTokenService>();
_desktopSessionCache = new Mock<IDesktopHubSessionCache>();
_agentSessionCache = new Mock<IAgentHubSessionCache>();
_logger = new Mock<ILogger<CircuitConnection>>();
_circuitConnection = new CircuitConnection(
_authService.Object,
_dataService,
_clientAppState.Object,
_agentHubContextFixture.HubContextMock.Object,
_appConfig.Object,
_circuitManager.Object,
_toastService.Object,
_expiringTokenService.Object,
_desktopSessionCache.Object,
_agentSessionCache.Object,
_logger.Object);
}
[TestMethod]
public async Task WakeDevice_GivenUserIsUnauthorized_Fails()
{
// A standard user won't have access if they aren't in the same
// group as the device.
_circuitConnection.User = _testData.Org1User1;
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { "78E3B5A1E45B" };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device.
_testData.Org1Device2.PublicIP = "142.251.33.110";
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.PublicIP = "142.251.33.110";
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
var wakeResult = await _circuitConnection.WakeDevice(_testData.Org1Device1);
Assert.IsFalse(wakeResult.IsSuccess);
_agentSessionCache.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
}
[TestMethod]
public async Task WakeDevice_GivenMatchingPeerByIp_UsesCorrectPeer()
{
_circuitConnection.User = _testData.Org1User1;
var macAddress = "78E3B5A1E45B";
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { macAddress };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device.
_testData.Org1Device2.PublicIP = "142.251.33.110";
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.PublicIP = "142.251.33.110";
var addToGroupResult = _dataService.AddUserToDeviceGroup(
_testData.Org1Id,
_testData.Org1Group1.ID,
_testData.Org1User1.UserName,
out _);
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
_agentSessionCache
.Setup(x => x.GetAllDevices())
.Returns(new[]
{
_testData.Org1Device2,
_testData.Org2Device1
});
var connectionId = "HQUSIBxiOwNokVH_mYgGyg";
_agentSessionCache
.Setup(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId))
.Returns(true);
var wakeResult = await _circuitConnection.WakeDevice(_testData.Org1Device1);
Assert.IsTrue(addToGroupResult);
Assert.IsTrue(wakeResult.IsSuccess);
_agentSessionCache
.Verify(x => x.GetAllDevices(), Times.Once);
_agentSessionCache
.Verify(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId), Times.Once);
_agentHubContextFixture.HubClientsMock
.Verify(x => x.Client(connectionId), Times.Once);
_agentHubContextFixture.SingleClientProxyMock
.Verify(x =>
x.SendCoreAsync(
"WakeDevice",
new object[] { macAddress },
default),
Times.Once);
_agentHubContextFixture.SingleClientProxyMock.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
_agentSessionCache.VerifyNoOtherCalls();
}
[TestMethod]
public async Task WakeDevice_GivenMatchingPeerByGroupId_UsesCorrectPeer()
{
_circuitConnection.User = _testData.Org1User1;
var macAddress = "78E3B5A1E45B";
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { macAddress };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device.
_testData.Org1Device2.DeviceGroupID = _testData.Org1Group1.ID;
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.DeviceGroupID = _testData.Org2Group1.ID;
var addToGroupResult = _dataService.AddUserToDeviceGroup(
_testData.Org1Id,
_testData.Org1Group1.ID,
_testData.Org1User1.UserName,
out _);
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
_agentSessionCache
.Setup(x => x.GetAllDevices())
.Returns(new[]
{
_testData.Org1Device2,
_testData.Org2Device1
});
var connectionId = "HQUSIBxiOwNokVH_mYgGyg";
_agentSessionCache
.Setup(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId))
.Returns(true);
var wakeResult = await _circuitConnection.WakeDevice(_testData.Org1Device1);
Assert.IsTrue(addToGroupResult);
Assert.IsTrue(wakeResult.IsSuccess);
_agentSessionCache
.Verify(x => x.GetAllDevices(), Times.Once);
_agentSessionCache
.Verify(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId), Times.Once);
_agentHubContextFixture.HubClientsMock
.Verify(x => x.Client(connectionId), Times.Once);
_agentHubContextFixture.SingleClientProxyMock
.Verify(x =>
x.SendCoreAsync(
"WakeDevice",
new object[] { macAddress },
default),
Times.Once);
_agentHubContextFixture.SingleClientProxyMock.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
_agentSessionCache.VerifyNoOtherCalls();
}
[TestMethod]
public async Task WakeDevice_GivenNoMatchingGroupOrIp_DoesNotSend()
{
_circuitConnection.User = _testData.Org1User1;
var macAddress = "78E3B5A1E45B";
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { macAddress };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device, but in a different group.
_testData.Org1Device2.DeviceGroupID = _testData.Org1Group2.ID;
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.DeviceGroupID = _testData.Org2Group1.ID;
var addToGroupResult = _dataService.AddUserToDeviceGroup(
_testData.Org1Id,
_testData.Org1Group1.ID,
_testData.Org1User1.UserName,
out _);
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
_agentSessionCache
.Setup(x => x.GetAllDevices())
.Returns(new[]
{
_testData.Org1Device2,
_testData.Org2Device1
});
var wakeResult = await _circuitConnection.WakeDevice(_testData.Org1Device1);
Assert.IsTrue(addToGroupResult);
Assert.IsTrue(wakeResult.IsSuccess);
_agentSessionCache
.Verify(x => x.GetAllDevices(), Times.Once);
_agentHubContextFixture.SingleClientProxyMock.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
_agentSessionCache.VerifyNoOtherCalls();
}
[TestMethod]
public async Task WakeDevices_GivenPeerIpMatches_UsesCorrectPeer()
{
_circuitConnection.User = _testData.Org1User1;
var macAddress = "78E3B5A1E45B";
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { macAddress };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device.
_testData.Org1Device2.PublicIP = "142.251.33.110";
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.PublicIP = "142.251.33.110";
var addToGroupResult = _dataService.AddUserToDeviceGroup(
_testData.Org1Id,
_testData.Org1Group1.ID,
_testData.Org1User1.UserName,
out _);
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
_agentSessionCache
.Setup(x => x.GetAllDevices())
.Returns(new[]
{
_testData.Org1Device2,
_testData.Org2Device1
});
var connectionId = "HQUSIBxiOwNokVH_mYgGyg";
_agentSessionCache
.Setup(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId))
.Returns(true);
var wakeResult = await _circuitConnection.WakeDevices(new[] { _testData.Org1Device1 });
Assert.IsTrue(addToGroupResult);
Assert.IsTrue(wakeResult.IsSuccess);
_agentSessionCache
.Verify(x => x.GetAllDevices(), Times.Once);
_agentSessionCache
.Verify(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId), Times.Once);
_agentHubContextFixture.HubClientsMock
.Verify(x => x.Client(connectionId), Times.Once);
_agentHubContextFixture.SingleClientProxyMock
.Verify(x =>
x.SendCoreAsync(
"WakeDevice",
new object[] { macAddress },
default),
Times.Once);
_agentHubContextFixture.SingleClientProxyMock.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
_agentSessionCache.VerifyNoOtherCalls();
}
[TestMethod]
public async Task WakeDevices_GivenMatchingPeerByGroupId_UsesCorrectPeer()
{
_circuitConnection.User = _testData.Org1User1;
var macAddress = "78E3B5A1E45B";
// Offline device.
_testData.Org1Device1.PublicIP = "142.251.33.110";
_testData.Org1Device1.MacAddresses = new[] { macAddress };
_testData.Org1Device1.DeviceGroupID = _testData.Org1Group1.ID;
// Online device.
_testData.Org1Device2.DeviceGroupID = _testData.Org1Group1.ID;
// Device in another org that shouldn't receive the command.
_testData.Org2Device1.DeviceGroupID = _testData.Org2Group1.ID;
var addToGroupResult = _dataService.AddUserToDeviceGroup(
_testData.Org1Id,
_testData.Org1Group1.ID,
_testData.Org1User1.UserName,
out _);
var updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device1);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org1Device2);
Assert.IsTrue(updateResult.IsSuccess);
updateResult = await _dataService.AddOrUpdateDevice(_testData.Org2Device1);
Assert.IsTrue(updateResult.IsSuccess);
_agentSessionCache
.Setup(x => x.GetAllDevices())
.Returns(new[]
{
_testData.Org1Device2,
_testData.Org2Device1
});
var connectionId = "HQUSIBxiOwNokVH_mYgGyg";
_agentSessionCache
.Setup(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId))
.Returns(true);
var wakeResult = await _circuitConnection.WakeDevices(new[] { _testData.Org1Device1 });
Assert.IsTrue(addToGroupResult);
Assert.IsTrue(wakeResult.IsSuccess);
_agentSessionCache
.Verify(x => x.GetAllDevices(), Times.Once);
_agentSessionCache
.Verify(x => x.TryGetConnectionId(_testData.Org1Device2.ID, out connectionId), Times.Once);
_agentHubContextFixture.HubClientsMock
.Verify(x => x.Client(connectionId), Times.Once);
_agentHubContextFixture.SingleClientProxyMock
.Verify(x =>
x.SendCoreAsync(
"WakeDevice",
new object[] { macAddress },
default),
Times.Once);
_agentHubContextFixture.SingleClientProxyMock.VerifyNoOtherCalls();
_agentHubContextFixture.HubContextMock.VerifyNoOtherCalls();
_agentSessionCache.VerifyNoOtherCalls();
}
}
}

View File

@ -21,9 +21,9 @@ namespace Remotely.Tests
[TestMethod]
public async Task AddAlert()
{
await _dataService.AddAlert(_testData.Device1.ID, _testData.OrganizationID, "Test Message");
await _dataService.AddAlert(_testData.Org1Device1.ID, _testData.Org1Id, "Test Message");
var alerts = _dataService.GetAlerts(_testData.Admin1.Id);
var alerts = _dataService.GetAlerts(_testData.Org1Admin1.Id);
Assert.AreEqual("Test Message", alerts.First().Message);
}
@ -38,7 +38,7 @@ namespace Remotely.Tests
var newDevice = new Device()
{
ID = _newDeviceID,
OrganizationID = _testData.OrganizationID,
OrganizationID = _testData.Org1Id,
DeviceName = Environment.MachineName,
Is64Bit = Environment.Is64BitOperatingSystem
};
@ -60,7 +60,7 @@ namespace Remotely.Tests
{
DeviceID = Guid.NewGuid().ToString(),
DeviceAlias = "Spare Laptop",
OrganizationID = _testData.OrganizationID
OrganizationID = _testData.Org1Id
};
// First call should create and return device.
@ -75,32 +75,32 @@ namespace Remotely.Tests
[TestMethod]
public void DeviceGroupPermissions()
{
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Admin1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Admin2.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.User1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.User2.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1Admin1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1Admin2.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1User1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1User2.UserName).Count() == 2);
var groupID = _dataService.GetDeviceGroups(_testData.Admin1.UserName).First().ID;
var groupID = _dataService.GetDeviceGroups(_testData.Org1Admin1.UserName).First().ID;
_dataService.UpdateDevice(_testData.Device1.ID, "", "", groupID, "");
_dataService.AddUserToDeviceGroup(_testData.OrganizationID, groupID, _testData.User1.UserName, out _);
_dataService.UpdateDevice(_testData.Org1Device1.ID, "", "", groupID, "");
_dataService.AddUserToDeviceGroup(_testData.Org1Id, groupID, _testData.Org1User1.UserName, out _);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Admin1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Admin2.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.User1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.User2.UserName).Count() == 1);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1Admin1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1Admin2.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1User1.UserName).Count() == 2);
Assert.IsTrue(_dataService.GetDevicesForUser(_testData.Org1User2.UserName).Count() == 1);
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Device1.ID, _testData.Admin1));
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Device1.ID, _testData.Admin2));
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Device1.ID, _testData.User1));
Assert.IsFalse(_dataService.DoesUserHaveAccessToDevice(_testData.Device1.ID, _testData.User2));
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Org1Device1.ID, _testData.Org1Admin1));
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Org1Device1.ID, _testData.Org1Admin2));
Assert.IsTrue(_dataService.DoesUserHaveAccessToDevice(_testData.Org1Device1.ID, _testData.Org1User1));
Assert.IsFalse(_dataService.DoesUserHaveAccessToDevice(_testData.Org1Device1.ID, _testData.Org1User2));
var allDevices = _dataService.GetAllDevices(_testData.OrganizationID).Select(x => x.ID).ToArray();
var allDevices = _dataService.GetAllDevices(_testData.Org1Id).Select(x => x.ID).ToArray();
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Admin1).Length);
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Admin2).Length);
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.User1).Length);
Assert.AreEqual(1, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.User2).Length);
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Org1Admin1).Length);
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Org1Admin2).Length);
Assert.AreEqual(2, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Org1User1).Length);
Assert.AreEqual(1, _dataService.FilterDeviceIDsByUserPermission(allDevices, _testData.Org1User2).Length);
}
[TestMethod]
@ -111,25 +111,25 @@ namespace Remotely.Tests
var savedScript = new SavedScript()
{
Content = "Get-ChildItem",
Creator = _testData.Admin1,
CreatorId = _testData.Admin1.Id,
Creator = _testData.Org1Admin1,
CreatorId = _testData.Org1Admin1.Id,
Name = "GCI",
Organization = _testData.Admin1.Organization,
OrganizationID = _testData.OrganizationID,
Organization = _testData.Org1Admin1.Organization,
OrganizationID = _testData.Org1Id,
Shell = Shared.Enums.ScriptingShell.PSCore
};
await _dataService.AddOrUpdateSavedScript(savedScript, _testData.Admin1.Id);
await _dataService.AddOrUpdateSavedScript(savedScript, _testData.Org1Admin1.Id);
var scriptRun = new ScriptRun()
{
Devices = new() { _testData.Device1 },
Devices = new() { _testData.Org1Device1 },
InputType = Shared.Enums.ScriptInputType.ScheduledScript,
SavedScriptId = savedScript.Id,
Initiator = _testData.Admin1.UserName,
Initiator = _testData.Org1Admin1.UserName,
RunAt = now,
OrganizationID = _testData.OrganizationID,
Organization = _testData.Admin1.Organization,
OrganizationID = _testData.Org1Id,
Organization = _testData.Org1Admin1.Organization,
RunOnNextConnect = true
};
@ -142,16 +142,16 @@ namespace Remotely.Tests
Time.Adjust(TimeSpan.FromMinutes(2));
var pendingRuns = await _dataService.GetPendingScriptRuns(_testData.Device1.ID);
var pendingRuns = await _dataService.GetPendingScriptRuns(_testData.Org1Device1.ID);
Assert.AreEqual(1, pendingRuns.Count);
Assert.AreEqual(2, pendingRuns[0].Id);
var scriptResult = new ScriptResult()
{
DeviceID = _testData.Device1.ID,
DeviceID = _testData.Org1Device1.ID,
InputType = Shared.Enums.ScriptInputType.ScheduledScript,
OrganizationID = _testData.OrganizationID,
OrganizationID = _testData.Org1Id,
SavedScriptId = savedScript.Id,
ScriptRunId = scriptRun.Id,
Shell = Shared.Enums.ScriptingShell.PSCore
@ -161,7 +161,7 @@ namespace Remotely.Tests
await _dataService.AddScriptResultToScriptRun(scriptResult.ID, scriptRun.Id);
pendingRuns = await _dataService.GetPendingScriptRuns(_testData.Device1.ID);
pendingRuns = await _dataService.GetPendingScriptRuns(_testData.Org1Device1.ID);
Assert.AreEqual(0, pendingRuns.Count);
}
@ -174,9 +174,10 @@ namespace Remotely.Tests
}
[TestInitialize]
public void TestInit()
public async Task TestInit()
{
_testData = new TestData();
await _testData.Init();
_dataService = IoCActivator.ServiceProvider.GetRequiredService<IDataService>();
var newDevice = new Device()
@ -184,16 +185,16 @@ namespace Remotely.Tests
ID = _newDeviceID,
DeviceName = Environment.MachineName,
Is64Bit = Environment.Is64BitOperatingSystem,
OrganizationID = _testData.OrganizationID
OrganizationID = _testData.Org1Id
};
}
[TestMethod]
public void UpdateOrganizationName()
{
Assert.IsTrue(string.IsNullOrWhiteSpace(_testData.Admin1.Organization.OrganizationName));
_dataService.UpdateOrganizationName(_testData.OrganizationID, "Test Org");
var updatedOrg = _dataService.GetOrganizationById(_testData.OrganizationID);
Assert.IsTrue(string.IsNullOrWhiteSpace(_testData.Org1Admin1.Organization.OrganizationName));
_dataService.UpdateOrganizationName(_testData.Org1Id, "Test Org");
var updatedOrg = _dataService.GetOrganizationById(_testData.Org1Id);
Assert.AreEqual("Test Org", updatedOrg.OrganizationName);
}
@ -204,57 +205,75 @@ namespace Remotely.Tests
Assert.AreEqual(1, currentAdmins.Count);
await _dataService.SetIsServerAdmin(_testData.Admin2.Id, true, _testData.Admin1.Id);
await _dataService.SetIsServerAdmin(_testData.Org1Admin2.Id, true, _testData.Org1Admin1.Id);
currentAdmins = _dataService.GetServerAdmins();
Assert.AreEqual(2, currentAdmins.Count);
Assert.IsTrue(currentAdmins.Contains(_testData.Admin1.UserName));
Assert.IsTrue(currentAdmins.Contains(_testData.Admin2.UserName));
Assert.IsTrue(currentAdmins.Contains(_testData.Org1Admin1.UserName));
Assert.IsTrue(currentAdmins.Contains(_testData.Org1Admin2.UserName));
// Shouldn't be able to change themselves.
await _dataService.SetIsServerAdmin(_testData.Admin2.Id, false, _testData.Admin2.Id);
await _dataService.SetIsServerAdmin(_testData.Org1Admin2.Id, false, _testData.Org1Admin2.Id);
currentAdmins = _dataService.GetServerAdmins();
Assert.AreEqual(2, currentAdmins.Count);
// Non-admins shouldn't be able to change admins.
await _dataService.SetIsServerAdmin(_testData.User1.Id, false, _testData.Admin2.Id);
await _dataService.SetIsServerAdmin(_testData.Org1User1.Id, false, _testData.Org1Admin2.Id);
currentAdmins = _dataService.GetServerAdmins();
Assert.AreEqual(2, currentAdmins.Count);
await _dataService.SetIsServerAdmin(_testData.Admin2.Id, false, _testData.Admin1.Id);
await _dataService.SetIsServerAdmin(_testData.Org1Admin2.Id, false, _testData.Org1Admin1.Id);
currentAdmins = _dataService.GetServerAdmins();
Assert.AreEqual(1, currentAdmins.Count);
Assert.AreEqual(_testData.Admin1.UserName, currentAdmins[0]);
Assert.AreEqual(_testData.Org1Admin1.UserName, currentAdmins[0]);
}
[TestMethod]
public void VerifyInitialData()
{
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Admin1.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Admin2.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.User1.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.User2.UserName));
Assert.AreEqual(1, _dataService.GetOrganizationCount());
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Org1Admin1.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Org1Admin2.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Org1User1.UserName));
Assert.IsNotNull(_dataService.GetUserByNameWithOrg(_testData.Org1User2.UserName));
Assert.AreEqual(2, _dataService.GetOrganizationCount());
var devices = _dataService.GetAllDevices(_testData.OrganizationID);
var devices1 = _dataService.GetAllDevices(_testData.Org1Id);
Assert.AreEqual(2, devices1.Length);
Assert.IsTrue(devices1.Any(x => x.ID == "Org1Device1"));
Assert.IsTrue(devices1.Any(x => x.ID == "Org1Device2"));
Assert.AreEqual(2, devices.Count());
Assert.IsTrue(devices.Any(x => x.ID == "Device1"));
Assert.IsTrue(devices.Any(x => x.ID == "Device2"));
var devices2 = _dataService.GetAllDevices(_testData.Org2Id);
Assert.AreEqual(2, devices2.Length);
Assert.IsTrue(devices2.Any(x => x.ID == "Org2Device1"));
Assert.IsTrue(devices2.Any(x => x.ID == "Org2Device2"));
var orgIDs = new string[]
var org1Ids = new string[]
{
_testData.Group1.OrganizationID,
_testData.Group2.OrganizationID,
_testData.Admin1.OrganizationID,
_testData.Admin2.OrganizationID,
_testData.User1.OrganizationID,
_testData.User2.OrganizationID,
_testData.Device1.OrganizationID,
_testData.Device2.OrganizationID
_testData.Org1Group1.OrganizationID,
_testData.Org1Group2.OrganizationID,
_testData.Org1Admin1.OrganizationID,
_testData.Org1Admin2.OrganizationID,
_testData.Org1User1.OrganizationID,
_testData.Org1User2.OrganizationID,
_testData.Org1Device1.OrganizationID,
_testData.Org1Device2.OrganizationID
};
Assert.IsTrue(orgIDs.All(x => x == _testData.OrganizationID));
Assert.IsTrue(org1Ids.All(x => x == _testData.Org1Id));
var org2Ids = new string[]
{
_testData.Org2Group1.OrganizationID,
_testData.Org2Group2.OrganizationID,
_testData.Org2Admin1.OrganizationID,
_testData.Org2Admin2.OrganizationID,
_testData.Org2User1.OrganizationID,
_testData.Org2User2.OrganizationID,
_testData.Org2Device1.OrganizationID,
_testData.Org2Device2.OrganizationID
};
Assert.IsTrue(org2Ids.All(x => x == _testData.Org2Id));
}
}
}

View File

@ -0,0 +1,46 @@
using Microsoft.AspNetCore.SignalR;
using Moq;
using Remotely.Server.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Remotely.Server.Tests.Mocks
{
public class HubContextFixture<T>
where T : Hub
{
public HubContextFixture()
{
HubContextMock = new Mock<IHubContext<T>>();
HubClientsMock = new Mock<IHubClients>();
GroupManagerMock = new Mock<IGroupManager>();
SingleClientProxyMock = new Mock<ISingleClientProxy>();
ClientProxyMock = new Mock<IClientProxy>();
HubContextMock
.Setup(x => x.Clients)
.Returns(HubClientsMock.Object);
HubContextMock
.Setup(x => x.Groups)
.Returns(GroupManagerMock.Object);
HubClientsMock
.Setup(x => x.Client(It.IsAny<string>()))
.Returns(SingleClientProxyMock.Object);
HubClientsMock
.Setup(x => x.Group(It.IsAny<string>()))
.Returns(ClientProxyMock.Object);
}
public Mock<IHubContext<T>> HubContextMock { get; }
public Mock<IHubClients> HubClientsMock { get; }
public Mock<IGroupManager> GroupManagerMock { get; }
public Mock<ISingleClientProxy> SingleClientProxyMock { get; }
public Mock<IClientProxy> ClientProxyMock { get; }
}
}

View File

@ -22,16 +22,17 @@ namespace Remotely.Tests
private ScriptSchedule _schedule1;
private Mock<IDataService> _dataService;
private Mock<ICircuitConnection> _circuitConnection;
private Mock<IServiceHubSessionCache> _serviceSessionCache;
private Mock<IAgentHubSessionCache> _serviceSessionCache;
private Mock<ILogger<ScriptScheduleDispatcher>> _logger;
private ScriptScheduleDispatcher _dispatcher;
private TestData _testData;
private SavedScript _savedScript;
[TestInitialize]
public void Init()
public async Task Init()
{
_testData = new TestData();
await _testData.Init();
_savedScript = new SavedScript()
{
@ -41,10 +42,10 @@ namespace Remotely.Tests
_schedule1 = new()
{
CreatedAt = Time.Now,
CreatorId = _testData.User1.Id,
CreatorId = _testData.Org1User1.Id,
Devices = new List<Device>()
{
_testData.Device1
_testData.Org1Device1
},
DeviceGroups = new List<DeviceGroup>()
{
@ -52,7 +53,7 @@ namespace Remotely.Tests
{
Devices = new List<Device>()
{
_testData.Device2
_testData.Org1Device2
}
}
},
@ -60,7 +61,7 @@ namespace Remotely.Tests
Name = "_scheduleName",
Id = 5,
NextRun = Time.Now.AddMinutes(1),
OrganizationID = _testData.User1.OrganizationID,
OrganizationID = _testData.Org1User1.OrganizationID,
SavedScriptId = _savedScript.Id
};
@ -72,12 +73,12 @@ namespace Remotely.Tests
_dataService = new Mock<IDataService>();
_dataService.Setup(x => x.GetScriptSchedulesDue()).Returns(Task.FromResult(scriptSchedules));
_dataService.Setup(x => x.GetDevices(It.Is<IEnumerable<string>>(x =>
x.Contains(_testData.Device1.ID) &&
x.Contains(_testData.Device2.ID)
))).Returns(new List<Device>() { _testData.Device1, _testData.Device2 });
x.Contains(_testData.Org1Device1.ID) &&
x.Contains(_testData.Org1Device2.ID)
))).Returns(new List<Device>() { _testData.Org1Device1, _testData.Org1Device2 });
_circuitConnection = new Mock<ICircuitConnection>();
_serviceSessionCache = new Mock<IServiceHubSessionCache>();
_serviceSessionCache = new Mock<IAgentHubSessionCache>();
_logger = new Mock<ILogger<ScriptScheduleDispatcher>>();
_dispatcher = new ScriptScheduleDispatcher(_dataService.Object, _serviceSessionCache.Object, _circuitConnection.Object, _logger.Object);
}
@ -109,8 +110,8 @@ namespace Remotely.Tests
x.Contains(_schedule1.Devices.First().ID))));
_dataService.Verify(x => x.AddScriptRun(It.Is<ScriptRun>(x =>
x.ScheduleId == _schedule1.Id &&
x.Devices.Exists(d => d.ID == _testData.Device1.ID) &&
x.Devices.Exists(d => d.ID == _testData.Device2.ID))));
x.Devices.Exists(d => d.ID == _testData.Org1Device1.ID) &&
x.Devices.Exists(d => d.ID == _testData.Org1Device2.ID))));
_dataService.VerifyNoOtherCalls();
_circuitConnection.Verify(x => x.RunScript(

View File

@ -14,49 +14,89 @@ namespace Remotely.Tests
{
public class TestData
{
public TestData()
{
Init().Wait();
}
#region Organization1
public Organization Org1 => Org1Admin1.Organization;
public RemotelyUser Admin1 { get; } = new RemotelyUser()
public RemotelyUser Org1Admin1 { get; } = new()
{
UserName = "admin1@test.com",
UserName = "org1admin1@test.com",
IsAdministrator = true,
IsServerAdmin = true,
Organization = new Organization(),
UserOptions = new RemotelyUserOptions()
};
public RemotelyUser Admin2 { get; private set; }
public RemotelyUser Org1Admin2 { get; private set; }
public Device Device1 { get; private set; } = new Device()
public Device Org1Device1 { get; private set; } = new Device()
{
ID = "Device1",
DeviceName = "Device1Name"
ID = "Org1Device1",
DeviceName = "Org1Device1Name"
};
public Device Device2 { get; private set; } = new Device()
public Device Org1Device2 { get; private set; } = new Device()
{
ID = "Device2",
DeviceName = "Device2Name"
ID = "Org1Device2",
DeviceName = "Org1Device2Name"
};
public DeviceGroup Group1 { get; private set; } = new DeviceGroup()
public DeviceGroup Org1Group1 { get; private set; } = new DeviceGroup()
{
Name = "Group1"
Name = "Org1Group1"
};
public DeviceGroup Group2 { get; private set; } = new DeviceGroup()
public DeviceGroup Org1Group2 { get; private set; } = new DeviceGroup()
{
Name = "Group2"
Name = "Org1Group2"
};
public string OrganizationID { get; private set; }
public string Org1Id => Org1.ID;
public RemotelyUser Org1User1 { get; private set; }
public RemotelyUser Org1User2 { get; private set; }
#endregion
public RemotelyUser User1 { get; private set; }
public RemotelyUser User2 { get; private set; }
#region Organization2
public Organization Org2 => Org2Admin1.Organization;
public RemotelyUser Org2Admin1 { get; } = new()
{
UserName = "org2admin1@test.com",
IsAdministrator = true,
IsServerAdmin = false,
Organization = new Organization(),
UserOptions = new RemotelyUserOptions()
};
public RemotelyUser Org2Admin2 { get; private set; }
public Device Org2Device1 { get; private set; } = new Device()
{
ID = "Org2Device1",
DeviceName = "Org2Device1Name"
};
public Device Org2Device2 { get; private set; } = new Device()
{
ID = "Org2Device2",
DeviceName = "Org2Device2Name"
};
public DeviceGroup Org2Group1 { get; private set; } = new DeviceGroup()
{
Name = "Org2Group1"
};
public DeviceGroup Org2Group2 { get; private set; } = new DeviceGroup()
{
Name = "Org2Group2"
};
public string Org2Id => Org2.ID;
public RemotelyUser Org2User1 { get; private set; }
public RemotelyUser Org2User2 { get; private set; }
#endregion
public void ClearData()
{
@ -74,7 +114,7 @@ namespace Remotely.Tests
}
private async Task Init()
public async Task Init()
{
ClearData();
@ -82,29 +122,52 @@ namespace Remotely.Tests
var userManager = IoCActivator.ServiceProvider.GetRequiredService<UserManager<RemotelyUser>>();
var emailSender = IoCActivator.ServiceProvider.GetRequiredService<IEmailSenderEx>();
await userManager.CreateAsync(Admin1);
// Organization 1
await userManager.CreateAsync(Org1Admin1);
await dataService.CreateUser("admin2@test.com", true, Admin1.OrganizationID);
Admin2 = dataService.GetUserByNameWithOrg("admin2@test.com");
await dataService.CreateUser("org1admin2@test.com", true, Org1Admin1.OrganizationID);
Org1Admin2 = dataService.GetUserByNameWithOrg("org1admin2@test.com");
await dataService.CreateUser("testuser1@test.com", false, Admin1.OrganizationID);
User1 = dataService.GetUserByNameWithOrg("testuser1@test.com");
await dataService.CreateUser("org1testuser1@test.com", false, Org1Admin1.OrganizationID);
Org1User1 = dataService.GetUserByNameWithOrg("org1testuser1@test.com");
await dataService.CreateUser("testuser2@test.com", false, Admin1.OrganizationID);
User2 = dataService.GetUserByNameWithOrg("testuser2@test.com");
await dataService.CreateUser("org1testuser2@test.com", false, Org1Admin1.OrganizationID);
Org1User2 = dataService.GetUserByNameWithOrg("org1testuser2@test.com");
Device1.OrganizationID = Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Device1); ;
Device2.OrganizationID = Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Device2);
Org1Device1.OrganizationID = Org1Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Org1Device1); ;
Org1Device2.OrganizationID = Org1Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Org1Device2);
dataService.AddDeviceGroup(Admin1.OrganizationID, Group1, out _, out _);
dataService.AddDeviceGroup(Admin1.OrganizationID, Group2, out _, out _);
var deviceGroups = dataService.GetDeviceGroups(Admin1.UserName);
Group1 = deviceGroups.First(x => x.Name == Group1.Name);
Group2 = deviceGroups.First(x => x.Name == Group2.Name);
dataService.AddDeviceGroup(Org1Admin1.OrganizationID, Org1Group1, out _, out _);
dataService.AddDeviceGroup(Org1Admin1.OrganizationID, Org1Group2, out _, out _);
var deviceGroups1 = dataService.GetDeviceGroups(Org1Admin1.UserName);
Org1Group1 = deviceGroups1.First(x => x.Name == Org1Group1.Name);
Org1Group2 = deviceGroups1.First(x => x.Name == Org1Group2.Name);
OrganizationID = Admin1.OrganizationID;
// Organization 2
await userManager.CreateAsync(Org2Admin1);
await dataService.CreateUser("org2admin2@test.com", true, Org2Admin1.OrganizationID);
Org2Admin2 = dataService.GetUserByNameWithOrg("org2admin2@test.com");
await dataService.CreateUser("org2testuser1@test.com", false, Org2Admin1.OrganizationID);
Org2User1 = dataService.GetUserByNameWithOrg("org2testuser1@test.com");
await dataService.CreateUser("org2testuser2@test.com", false, Org2Admin1.OrganizationID);
Org2User2 = dataService.GetUserByNameWithOrg("org2testuser2@test.com");
Org2Device1.OrganizationID = Org2Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Org2Device1); ;
Org2Device2.OrganizationID = Org2Admin1.OrganizationID;
await dataService.AddOrUpdateDevice(Org2Device2);
dataService.AddDeviceGroup(Org2Admin1.OrganizationID, Org2Group1, out _, out _);
dataService.AddDeviceGroup(Org2Admin1.OrganizationID, Org2Group2, out _, out _);
var deviceGroups2 = dataService.GetDeviceGroups(Org2Admin1.UserName);
Org2Group1 = deviceGroups2.First(x => x.Name == Org2Group1.Name);
Org2Group2 = deviceGroups2.First(x => x.Name == Org2Group2.Name);
}
}
}