diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs
index 0da506839..0d887b84d 100644
--- a/Application/IW4MServer.cs
+++ b/Application/IW4MServer.cs
@@ -177,8 +177,6 @@ namespace IW4MAdmin
await command.ExecuteAsync(E);
}
-
-
var pluginTasks = Manager.Plugins.Where(_plugin => _plugin.Name != "Login").Select(async _plugin =>
{
try
@@ -202,7 +200,10 @@ namespace IW4MAdmin
}
});
- await Task.WhenAny(pluginTasks);
+ if (pluginTasks.Count() > 0)
+ {
+ await Task.WhenAny(pluginTasks);
+ }
}
catch (Exception e)
diff --git a/SharedLibraryCore/Command.cs b/SharedLibraryCore/Command.cs
index cbde52552..ec8bd4a72 100644
--- a/SharedLibraryCore/Command.cs
+++ b/SharedLibraryCore/Command.cs
@@ -15,6 +15,7 @@ namespace SharedLibraryCore
{
private readonly CommandConfiguration _config;
protected readonly ITranslationLookup _translationLookup;
+ protected ILogger logger;
public Command(CommandConfiguration config, ITranslationLookup layout)
{
diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs
index 27412f032..333260e47 100644
--- a/SharedLibraryCore/Commands/NativeCommands.cs
+++ b/SharedLibraryCore/Commands/NativeCommands.cs
@@ -76,6 +76,13 @@ namespace SharedLibraryCore.Commands
public override async Task ExecuteAsync(GameEvent E)
{
+ // they're trying to set the console's permission level... sigh...
+ if (E.Origin.Level == Permission.Console)
+ {
+ E.Origin.Tell(_translationLookup["COMMANDS_OWNER_IDIOT"]);
+ return;
+ }
+
if (await (E.Owner.Manager.GetClientService() as ClientService).GetOwnerCount() == 0 &&
!E.Origin.SetLevel(EFClient.Permission.Owner, Utilities.IW4MAdminClient(E.Owner)).Failed)
{
@@ -604,7 +611,7 @@ namespace SharedLibraryCore.Commands
///
public class SetLevelCommand : Command
{
- public SetLevelCommand(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
+ public SetLevelCommand(CommandConfiguration config, ITranslationLookup translationLookup, ILogger logger) : base(config, translationLookup)
{
Name = "setlevel";
Description = _translationLookup["COMMANDS_SETLEVEL_DESC"];
@@ -624,77 +631,95 @@ namespace SharedLibraryCore.Commands
Required = true
}
};
+ this.logger = logger;
}
- public override async Task ExecuteAsync(GameEvent E)
+ public override async Task ExecuteAsync(GameEvent gameEvent)
{
- Permission oldPerm = E.Target.Level;
- Permission newPerm = Utilities.MatchPermission(E.Data);
+ Permission oldPerm = gameEvent.Target.Level;
+ Permission newPerm = Utilities.MatchPermission(gameEvent.Data);
+ bool allowMultiOwner = gameEvent.Owner.Manager.GetApplicationSettings().Configuration().EnableMultipleOwners;
+ bool steppedPrivileges = gameEvent.Owner.Manager.GetApplicationSettings().Configuration().EnableSteppedHierarchy;
+ var targetClient = gameEvent.Target;
- if (E.Target == E.Origin)
+ // pre setup logic
+ bool canPromoteSteppedPriv = gameEvent.Origin.Level > newPerm || gameEvent.Origin.Level == Permission.Owner;
+ bool hasOwner = await gameEvent.Owner.Manager.GetClientService().GetOwnerCount() > 0;
+
+ // trying to set self
+ if (gameEvent.Target == gameEvent.Origin)
{
- E.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_SELF"]);
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_SELF"]);
return;
}
- else if (newPerm == Permission.Owner &&
- !E.Owner.Manager.GetApplicationSettings().Configuration().EnableMultipleOwners &&
- await E.Owner.Manager.GetClientService().GetOwnerCount() > 0)
+ // origin permission not high enough
+ else if (gameEvent.Origin.Level < gameEvent.Target.Level)
+ {
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_PERMISSION"].FormatExt(gameEvent.Target.Name));
+ return;
+ }
+
+ // trying to set owner without enabling multiple owners
+ else if (newPerm == Permission.Owner && !allowMultiOwner && hasOwner)
{
// only one owner is allowed
- E.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_OWNER"]);
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_OWNER"]);
return;
}
- else if (E.Origin.Level < Permission.Owner &&
- !E.Owner.Manager.GetApplicationSettings().Configuration().EnableSteppedHierarchy)
+ // trying to set level when only owner is allowed to
+ else if (gameEvent.Origin.Level < Permission.Owner && !steppedPrivileges)
{
// only the owner is allowed to set levels
- E.Origin.Tell($"{_translationLookup["COMMANDS_SETLEVEL_STEPPEDDISABLED"]} ^5{E.Target.Name}");
+ gameEvent.Origin.Tell($"{_translationLookup["COMMANDS_SETLEVEL_STEPPEDDISABLED"]} ^5{gameEvent.Target.Name}");
return;
}
- else if ((E.Origin.Level <= newPerm &&
- E.Origin.Level < Permission.Owner) ||
- E.Origin.Level == newPerm)
+ // stepped privilege is enabled, but the new level is too high
+ else if (steppedPrivileges && !canPromoteSteppedPriv)
{
// can't promote a client to higher than your current perms
// or your peer
- E.Origin.Tell(string.Format(_translationLookup["COMMANDS_SETLEVEL_LEVELTOOHIGH"], E.Target.Name, (E.Origin.Level - 1).ToString()));
+ gameEvent.Origin.Tell(string.Format(_translationLookup["COMMANDS_SETLEVEL_LEVELTOOHIGH"], gameEvent.Target.Name, (gameEvent.Origin.Level - 1).ToString()));
return;
}
+ // valid
else if (newPerm > Permission.Banned)
{
- var ActiveClient = E.Owner.Manager.GetActiveClients()
- .FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
+ targetClient = targetClient.ClientNumber < 0 ?
+ gameEvent.Owner.Manager.GetActiveClients()
+ .FirstOrDefault(c => c.ClientId == targetClient?.ClientId) ?? targetClient : targetClient;
- if (ActiveClient != null)
+ logger.WriteInfo($"Beginning set level of client {gameEvent.Origin} to {newPerm}");
+
+ var result = await targetClient.SetLevel(newPerm, gameEvent.Origin).WaitAsync(Utilities.DefaultCommandTimeout, gameEvent.Owner.Manager.CancellationToken);
+
+ if (result.Failed)
{
- ActiveClient.SetLevel(newPerm, E.Origin);
-
- // inform the client that they were promoted
- // we don't really want to tell them if they're demoted haha
- if (newPerm > oldPerm)
- {
- ActiveClient.Tell(_translationLookup["COMMANDS_SETLEVEL_SUCCESS_TARGET"].FormatExt(newPerm));
- }
+ logger.WriteInfo($"Failed to set level of client {gameEvent.Origin}");
+ gameEvent.Origin.Tell(_translationLookup["SERVER_ERROR_COMMAND_INGAME"]);
+ return;
}
- else
+ // inform the client that they were promoted
+ // we don't really want to tell them if they're demoted haha
+ if (targetClient.IsIngame && newPerm > oldPerm)
{
- E.Target.SetLevel(newPerm, E.Origin);
+ targetClient.Tell(_translationLookup["COMMANDS_SETLEVEL_SUCCESS_TARGET"].FormatExt(newPerm));
}
// inform the origin that the client has been updated
_ = newPerm < oldPerm ?
- E.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_DEMOTE_SUCCESS"].FormatExt(E.Target.Name)) :
- E.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_SUCCESS"].FormatExt(E.Target.Name));
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_DEMOTE_SUCCESS"].FormatExt(targetClient.Name)) :
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_SUCCESS"].FormatExt(targetClient.Name));
}
+ // all other tests failed so it's invalid group
else
{
- E.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_FAIL"]);
+ gameEvent.Origin.Tell(_translationLookup["COMMANDS_SETLEVEL_FAIL"]);
}
}
}
diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs
index 1a6144ac3..cd24acee8 100644
--- a/SharedLibraryCore/Services/ClientService.cs
+++ b/SharedLibraryCore/Services/ClientService.cs
@@ -239,7 +239,7 @@ namespace SharedLibraryCore.Services
///
///
///
- public async Task UpdateLevel(Permission newPermission, EFClient temporalClient, EFClient origin)
+ public virtual async Task UpdateLevel(Permission newPermission, EFClient temporalClient, EFClient origin)
{
using (var ctx = new DatabaseContext())
{
@@ -483,7 +483,7 @@ namespace SharedLibraryCore.Services
/// (client level is owner)
///
///
- public async Task GetOwnerCount()
+ public virtual async Task GetOwnerCount()
{
using (var ctx = new DatabaseContext(true))
{
diff --git a/Tests/ApplicationTests/CommandTests.cs b/Tests/ApplicationTests/CommandTests.cs
index 88b6bbd4d..3d5d50488 100644
--- a/Tests/ApplicationTests/CommandTests.cs
+++ b/Tests/ApplicationTests/CommandTests.cs
@@ -3,21 +3,17 @@ using System;
using SharedLibraryCore.Interfaces;
using IW4MAdmin;
using FakeItEasy;
-using IW4MAdmin.Application.EventParsers;
using System.Linq;
-using IW4MAdmin.Plugins.Stats.Models;
-using IW4MAdmin.Application.Helpers;
-using IW4MAdmin.Plugins.Stats.Config;
-using System.Collections.Generic;
using SharedLibraryCore.Database.Models;
using Microsoft.Extensions.DependencyInjection;
-using IW4MAdmin.Plugins.Stats.Helpers;
using ApplicationTests.Fixtures;
using System.Threading.Tasks;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration;
using SharedLibraryCore;
using ApplicationTests.Mocks;
+using SharedLibraryCore.Services;
+using static SharedLibraryCore.Database.Models.EFClient;
namespace ApplicationTests
{
@@ -28,7 +24,10 @@ namespace ApplicationTests
private IServiceProvider serviceProvider;
private ITranslationLookup transLookup;
private CommandConfiguration cmdConfig;
- private MockEventHandler mockEventHandler;
+ private ApplicationConfiguration appConfig;
+ private EventHandlerMock mockEventHandler;
+ private ClientService clientService;
+ private IManager manager;
[SetUp]
public void Setup()
@@ -37,24 +36,31 @@ namespace ApplicationTests
cmdConfig = new CommandConfiguration();
serviceProvider = new ServiceCollection()
- .BuildBase(new MockEventHandler(true))
- .BuildServiceProvider();
+ .BuildBase(new EventHandlerMock(true))
+ .BuildServiceProvider()
+ .SetupTestHooks();
- mockEventHandler = serviceProvider.GetRequiredService();
-
- var mgr = serviceProvider.GetRequiredService();
+ mockEventHandler = serviceProvider.GetRequiredService();
+ manager = serviceProvider.GetRequiredService();
transLookup = serviceProvider.GetRequiredService();
+ clientService = serviceProvider.GetRequiredService();
+ appConfig = serviceProvider.GetRequiredService();
- A.CallTo(() => mgr.GetCommands())
+ A.CallTo(() => manager.GetClientService())
+ .Returns(clientService);
+
+ A.CallTo(() => clientService.UpdateLevel(A.Ignored, A.Ignored, A.Ignored))
+ .Returns(Task.CompletedTask);
+
+ A.CallTo(() => manager.GetCommands())
.Returns(new Command[]
{
new ImpersonatableCommand(cmdConfig, transLookup),
new NonImpersonatableCommand(cmdConfig, transLookup)
});
- A.CallTo(() => mgr.AddEvent(A.Ignored))
- .Invokes((fakeCall) => mockEventHandler.HandleEvent(mgr, fakeCall.Arguments[0] as GameEvent));
-
+ A.CallTo(() => manager.AddEvent(A.Ignored))
+ .Invokes((fakeCall) => mockEventHandler.HandleEvent(manager, fakeCall.Arguments[0] as GameEvent));
}
#region RUNAS
@@ -174,5 +180,343 @@ namespace ApplicationTests
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command && !_event.Failed));
}
#endregion
+
+ #region SETLEVEL
+ [Test]
+ public async Task Test_SetLevelFailOnSelf()
+ {
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var server = serviceProvider.GetRequiredService();
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.Owner;
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = target,
+ Data = "Administrator",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Owner, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelFailWithSourcePrivilegeTooLow()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Moderator;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.Administrator;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Administrator",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Administrator, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelFailWithExistingOwner_AndOnlyOneOwnerAllowed()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Owner",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.User, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelFailWithStepPrivilegesDisabled_AndNonOwner()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.SeniorAdmin;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.Moderator;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Administrator",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Moderator, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelFailWithStepPrivilegesEnabled_ButNewPermissionTooHigh()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Moderator;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+ appConfig.EnableSteppedHierarchy = true;
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Moderator",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.User, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelFailInvalidGroup()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Banned",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.User, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission));
+ }
+
+ [Test]
+ public async Task Test_SetLevelSucceedWithNoExistingOwner_AndOnlyOneOwnerAllowed()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(0));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Owner",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Owner, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+
+ [Test]
+ public async Task Test_SetLevelOwnerSucceedWithMultiOwnerAllowed()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+ appConfig.EnableMultipleOwners = true;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Owner",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Owner, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+
+ [Test]
+ public async Task Test_SetLevelOwnerSucceedWithMultiOwnerAllowed_AndSteppedPrivileges()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+ appConfig.EnableMultipleOwners = true;
+ appConfig.EnableSteppedHierarchy = true;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Owner",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Owner, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+
+ [Test]
+ public async Task Test_SetLevelSucceedWithSteppedPrivileges()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Moderator;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+ appConfig.EnableSteppedHierarchy = true;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Trusted",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Trusted, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+
+ [Test]
+ public async Task Test_SetLevelSucceed()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var target = ClientGenerators.CreateBasicClient(server);
+ target.Level = Permission.User;
+ appConfig.EnableSteppedHierarchy = true;
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = target,
+ Origin = origin,
+ Data = "Trusted",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.Trusted, target.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+
+ [Test]
+ public async Task Test_SetLevelSucceed_AndFindsIngameClient()
+ {
+ var server = serviceProvider.GetRequiredService();
+ var cmd = new SetLevelCommand(cmdConfig, transLookup, logger);
+ var origin = ClientGenerators.CreateBasicClient(server);
+ origin.Level = Permission.Owner;
+ var databaseTarget = ClientGenerators.CreateDatabaseClient();
+ databaseTarget.Level = Permission.Administrator;
+
+ var ingameTarget = ClientGenerators.CreateBasicClient(server);
+ ingameTarget.Level = Permission.Administrator;
+
+ A.CallTo(() => manager.GetActiveClients())
+ .Returns(new[] { ingameTarget });
+
+ A.CallTo(() => clientService.GetOwnerCount())
+ .Returns(Task.FromResult(1));
+
+ var gameEvent = new GameEvent()
+ {
+ Target = databaseTarget,
+ Origin = origin,
+ Data = "User",
+ Owner = server,
+ };
+
+ await cmd.ExecuteAsync(gameEvent);
+
+ Assert.AreEqual(Permission.User, ingameTarget.Level);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ChangePermission && !_event.Failed));
+ }
+ #endregion
}
}
diff --git a/Tests/ApplicationTests/DependencyInjectionExtensions.cs b/Tests/ApplicationTests/DependencyInjectionExtensions.cs
index 2784955fa..fb34a285d 100644
--- a/Tests/ApplicationTests/DependencyInjectionExtensions.cs
+++ b/Tests/ApplicationTests/DependencyInjectionExtensions.cs
@@ -3,9 +3,11 @@ using ApplicationTests.Mocks;
using FakeItEasy;
using IW4MAdmin;
using Microsoft.Extensions.DependencyInjection;
+using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Services;
+using System;
namespace ApplicationTests
{
@@ -16,11 +18,11 @@ namespace ApplicationTests
if (eventHandler == null)
{
- eventHandler = new MockEventHandler();
- serviceCollection.AddSingleton(eventHandler as MockEventHandler);
+ eventHandler = new EventHandlerMock();
+ serviceCollection.AddSingleton(eventHandler as EventHandlerMock);
}
- else if (eventHandler is MockEventHandler mockEventHandler)
+ else if (eventHandler is EventHandlerMock mockEventHandler)
{
serviceCollection.AddSingleton(mockEventHandler);
}
@@ -42,7 +44,10 @@ namespace ApplicationTests
.AddSingleton()
.AddSingleton(A.Fake())
.AddSingleton(A.Fake())
- .AddSingleton(eventHandler);
+ .AddSingleton(eventHandler)
+ .AddSingleton(ConfigurationGenerators.CreateApplicationConfiguration())
+ .AddSingleton(ConfigurationGenerators.CreateCommandConfiguration())
+ .AddSingleton, ApplicationConfigurationHandlerMock>();
serviceCollection.AddSingleton(_sp => new IW4MServer(_sp.GetRequiredService(), ConfigurationGenerators.CreateServerConfiguration(),
_sp.GetRequiredService(), _sp.GetRequiredService(), _sp.GetRequiredService())
@@ -52,5 +57,14 @@ namespace ApplicationTests
return serviceCollection;
}
+
+ public static IServiceProvider SetupTestHooks(this IServiceProvider serviceProvider)
+ {
+ var mgr = serviceProvider.GetRequiredService();
+ A.CallTo(() => mgr.GetApplicationSettings())
+ .Returns(serviceProvider.GetRequiredService>());
+
+ return serviceProvider;
+ }
}
}
diff --git a/Tests/ApplicationTests/Fixtures/ConfigurationGenerators.cs b/Tests/ApplicationTests/Fixtures/ConfigurationGenerators.cs
index 7e3b70a70..7c4a6b094 100644
--- a/Tests/ApplicationTests/Fixtures/ConfigurationGenerators.cs
+++ b/Tests/ApplicationTests/Fixtures/ConfigurationGenerators.cs
@@ -18,5 +18,7 @@ namespace ApplicationTests.Fixtures
Say = "say"
}
};
+ public static ApplicationConfiguration CreateApplicationConfiguration() => new ApplicationConfiguration() { Servers = new[] { CreateServerConfiguration() } };
+ public static CommandConfiguration CreateCommandConfiguration() => new CommandConfiguration();
}
}
diff --git a/Tests/ApplicationTests/IW4MServerTests.cs b/Tests/ApplicationTests/IW4MServerTests.cs
index 899be42f0..02d645b6b 100644
--- a/Tests/ApplicationTests/IW4MServerTests.cs
+++ b/Tests/ApplicationTests/IW4MServerTests.cs
@@ -25,7 +25,8 @@ namespace ApplicationTests
private IManager fakeManager;
private IRConConnection fakeRConConnection;
private IRConParser fakeRConParser;
- private MockEventHandler mockEventHandler;
+ private EventHandlerMock mockEventHandler;
+ private ApplicationConfiguration appConfig;
[SetUp]
public void Setup()
@@ -36,7 +37,8 @@ namespace ApplicationTests
fakeManager = serviceProvider.GetRequiredService();
fakeRConConnection = serviceProvider.GetRequiredService();
fakeRConParser = serviceProvider.GetRequiredService();
- mockEventHandler = serviceProvider.GetRequiredService();
+ mockEventHandler = serviceProvider.GetRequiredService();
+ appConfig = serviceProvider.GetRequiredService();
var rconConnectionFactory = serviceProvider.GetRequiredService();
@@ -517,12 +519,7 @@ namespace ApplicationTests
{
var server = serviceProvider.GetService();
var fakeConfigHandler = A.Fake>();
-
- A.CallTo(() => fakeManager.GetApplicationSettings())
- .Returns(fakeConfigHandler);
-
- A.CallTo(() => fakeConfigHandler.Configuration())
- .Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = true });
+ appConfig.IgnoreServerConnectionLost = true;
A.CallTo(() => fakeRConParser.GetStatusAsync(A.Ignored))
.ThrowsAsync(new NetworkException("err"));
@@ -535,7 +532,6 @@ namespace ApplicationTests
A.CallTo(() => fakeLogger.WriteError(A.Ignored))
.MustNotHaveHappened();
- Assert.IsEmpty(mockEventHandler.Events);
}
[Test]
@@ -544,12 +540,6 @@ namespace ApplicationTests
var server = serviceProvider.GetService();
var fakeConfigHandler = A.Fake>();
- A.CallTo(() => fakeManager.GetApplicationSettings())
- .Returns(fakeConfigHandler);
-
- A.CallTo(() => fakeConfigHandler.Configuration())
- .Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = false });
-
A.CallTo(() => fakeRConParser.GetStatusAsync(A.Ignored))
.ThrowsAsync(new NetworkException("err"));
@@ -568,7 +558,7 @@ namespace ApplicationTests
A.CallTo(() => fakeLogger.WriteError(A.Ignored))
.MustHaveHappenedOnceExactly();
- Assert.IsNotEmpty(mockEventHandler.Events);
+ Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.ConnectionLost));
Assert.AreEqual("err", (mockEventHandler.Events[0].Extra as NetworkException).Message);
}
}
diff --git a/Tests/ApplicationTests/Mocks/ApplicationConfigurationHandlerMock.cs b/Tests/ApplicationTests/Mocks/ApplicationConfigurationHandlerMock.cs
new file mode 100644
index 000000000..22ab7037b
--- /dev/null
+++ b/Tests/ApplicationTests/Mocks/ApplicationConfigurationHandlerMock.cs
@@ -0,0 +1,36 @@
+using SharedLibraryCore.Configuration;
+using SharedLibraryCore.Interfaces;
+using System;
+using System.Threading.Tasks;
+
+namespace ApplicationTests.Mocks
+{
+ class ApplicationConfigurationHandlerMock : IConfigurationHandler
+ {
+ private readonly ApplicationConfiguration _appConfig;
+
+ public ApplicationConfigurationHandlerMock(ApplicationConfiguration configuration)
+ {
+ _appConfig = configuration;
+ }
+
+ public string FileName => "";
+
+ public void Build()
+ {
+
+ }
+
+ public ApplicationConfiguration Configuration() => _appConfig;
+
+ public Task Save()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Set(ApplicationConfiguration config)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Tests/ApplicationTests/Mocks/EventHandler.cs b/Tests/ApplicationTests/Mocks/EventHandlerMock.cs
similarity index 85%
rename from Tests/ApplicationTests/Mocks/EventHandler.cs
rename to Tests/ApplicationTests/Mocks/EventHandlerMock.cs
index e61a9a206..d00291d09 100644
--- a/Tests/ApplicationTests/Mocks/EventHandler.cs
+++ b/Tests/ApplicationTests/Mocks/EventHandlerMock.cs
@@ -4,12 +4,12 @@ using System.Collections.Generic;
namespace ApplicationTests.Mocks
{
- class MockEventHandler : IEventHandler
+ class EventHandlerMock : IEventHandler
{
public IList Events = new List();
private readonly bool _autoExecute;
- public MockEventHandler(bool autoExecute = false)
+ public EventHandlerMock(bool autoExecute = false)
{
_autoExecute = autoExecute;
}
diff --git a/Tests/ApplicationTests/PluginTests.cs b/Tests/ApplicationTests/PluginTests.cs
index f4f5ac017..5278eaed1 100644
--- a/Tests/ApplicationTests/PluginTests.cs
+++ b/Tests/ApplicationTests/PluginTests.cs
@@ -2,6 +2,7 @@
using ApplicationTests.Mocks;
using FakeItEasy;
using IW4MAdmin;
+using IW4MAdmin.Application.Factories;
using IW4MAdmin.Application.Misc;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
@@ -24,14 +25,16 @@ namespace ApplicationTests
private static string PLUGIN_DIR = @"X:\IW4MAdmin\Plugins\ScriptPlugins";
private IServiceProvider serviceProvider;
private IManager fakeManager;
- private MockEventHandler mockEventHandler;
+ private EventHandlerMock mockEventHandler;
[SetUp]
public void Setup()
{
- serviceProvider = new ServiceCollection().BuildBase().BuildServiceProvider();
+ serviceProvider = new ServiceCollection().BuildBase()
+ .AddSingleton()
+ .BuildServiceProvider();
fakeManager = serviceProvider.GetRequiredService();
- mockEventHandler = serviceProvider.GetRequiredService();
+ mockEventHandler = serviceProvider.GetRequiredService();
var rconConnectionFactory = serviceProvider.GetRequiredService();
@@ -62,7 +65,7 @@ namespace ApplicationTests
A.CallTo(() => fakeManager.GetClientService())
.Returns(fakeClientService);
- await plugin.Initialize(serviceProvider.GetRequiredService());
+ await plugin.Initialize(serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService());
var gameEvent = new GameEvent()
{
diff --git a/Tests/ApplicationTests/StatsTests.cs b/Tests/ApplicationTests/StatsTests.cs
index a2296ed00..cff545ceb 100644
--- a/Tests/ApplicationTests/StatsTests.cs
+++ b/Tests/ApplicationTests/StatsTests.cs
@@ -22,14 +22,17 @@ namespace ApplicationTests
{
ILogger logger;
private IServiceProvider serviceProvider;
+ private IConfigurationHandlerFactory handlerFactory;
[SetUp]
public void Setup()
{
logger = A.Fake();
+ handlerFactory = A.Fake();
serviceProvider = new ServiceCollection()
.BuildBase()
+ .AddSingleton()
.BuildServiceProvider();
void testLog(string msg) => Console.WriteLine(msg);
@@ -44,9 +47,8 @@ namespace ApplicationTests
public void TestKDR()
{
var mgr = A.Fake();
- var handlerFactory = A.Fake();
var config = A.Fake>();
- var plugin = new IW4MAdmin.Plugins.Stats.Plugin(handlerFactory, null);
+ var plugin = serviceProvider.GetRequiredService();
A.CallTo(() => config.Configuration())
.Returns(new StatsConfiguration()