From 9d852ac989c76bd1aff8ddab5e83fe954a330d5b Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Sun, 5 Jun 2022 10:15:11 +0300 Subject: [PATCH] Wrote a generic test for "No permission" for all commands --- .../commands/use/CommandWithSubcommands.java | 11 +++ .../plan/commands/PlanCommandTest.java | 90 ++++++++++++++++++- .../utilities/mocks/PluginMockComponent.java | 7 +- 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java index 9abbe610a..1b4a893f4 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java @@ -54,6 +54,17 @@ public class CommandWithSubcommands extends Subcommand { return subcommands; } + public Optional findSubCommand(Arguments arguments) { + return arguments.get(0).flatMap(alias -> { + for (Subcommand subcommand : subcommands) { + if (subcommand.getAliases().contains(alias)) { + return Optional.of(subcommand); + } + } + return Optional.empty(); + }); + } + public void onHelp(CMDSender sender, Arguments arguments) { List hasPermissionFor = getPermittedSubcommands(sender); sender.buildMessage() diff --git a/Plan/common/src/test/java/com/djrapitops/plan/commands/PlanCommandTest.java b/Plan/common/src/test/java/com/djrapitops/plan/commands/PlanCommandTest.java index 57522e8e6..7b80d0794 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/commands/PlanCommandTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/commands/PlanCommandTest.java @@ -16,24 +16,44 @@ */ package com.djrapitops.plan.commands; +import com.djrapitops.plan.PlanSystem; +import com.djrapitops.plan.commands.use.*; +import com.djrapitops.plan.settings.Permissions; +import com.djrapitops.plan.settings.locale.lang.CommandLang; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; import utilities.dagger.PlanPluginComponent; import utilities.mocks.PluginMockComponent; import java.nio.file.Path; +import java.util.Collections; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; class PlanCommandTest { - private PlanCommand underTest; + PlanCommand underTest; + PlanSystem system; @BeforeEach void preparePlanCommand(@TempDir Path tempDir) throws Exception { PlanPluginComponent component = new PluginMockComponent(tempDir).getComponent(); underTest = component.planCommand(); + system = component.system(); + system.enable(); + } + + @AfterEach + void tearDownSystem() { + if (system != null) system.disable(); } @Test @@ -41,4 +61,72 @@ class PlanCommandTest { assertNotNull(underTest.build()); } + @ParameterizedTest(name = "Command not executed without permission: /plan {0}") + @CsvSource({ + "server", + "server Server 1", + "network", + "player", + "player Test", + "search Test", + "ingame", + "ingame Test", + "json", + "json Test", + "register", + "unregister", + "unregister Test", + "logout Test", + "users", + "info", + "reload", + "disable", + "disable kickCount", + "export players", + "export", + "db", + "db backup SQLite", + "db clear SQLite", + "db remove Test", + "db uninstalled 1", + }) + void commandWithoutPermissionsReturnsPermissionDenied(String command) { + CMDSender sender = runCommand(command); + + Set requiredPermissions = underTest.build().findSubCommand(new Arguments(command)) + .map(Subcommand::getRequiredPermissions) + .orElse(Collections.emptySet()); + + verify(sender, times(1)).send(CommandLang.FAIL_NO_PERMISSION.getDefault() + " " + requiredPermissions); + } + + private CMDSender runCommand(String command, String... permissions) { + CommandWithSubcommands executor = underTest.build(); + CMDSender sender = mockSender(permissions); + + executor.executeCommand(sender, new Arguments(command)); + + return sender; + } + + private CMDSender mockSender(String[] permissions) { + CMDSender sender = Mockito.mock(CMDSender.class); + + // Sending messages + ConsoleMessageBuilder messageBuilder = new ConsoleMessageBuilder(System.out::println); + ConsoleChatFormatter chatFormatter = new ConsoleChatFormatter(); + lenient().when(sender.buildMessage()).thenReturn(messageBuilder); + lenient().when(sender.getFormatter()).thenReturn(chatFormatter); + + // Permissions + lenient().when(sender.hasAllPermissionsFor(any())).thenCallRealMethod(); + lenient().when(sender.isMissingPermissionsFor(any())).thenCallRealMethod(); + lenient().when(sender.hasPermission((Permissions) any())).thenCallRealMethod(); + for (String permission : permissions) { + when(sender.hasPermission(permission)).thenReturn(true); + } + + return sender; + } + } \ No newline at end of file diff --git a/Plan/common/src/test/java/utilities/mocks/PluginMockComponent.java b/Plan/common/src/test/java/utilities/mocks/PluginMockComponent.java index 1ea55abf6..ebff0087f 100644 --- a/Plan/common/src/test/java/utilities/mocks/PluginMockComponent.java +++ b/Plan/common/src/test/java/utilities/mocks/PluginMockComponent.java @@ -18,6 +18,7 @@ package utilities.mocks; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.PlanSystem; +import com.djrapitops.plan.settings.config.paths.WebserverSettings; import com.djrapitops.plan.storage.database.SQLDB; import com.djrapitops.plan.utilities.logging.PluginErrorLogger; import net.playeranalytics.plugin.PlatformAbstractionLayer; @@ -25,6 +26,7 @@ import utilities.dagger.DaggerPlanPluginComponent; import utilities.dagger.PlanPluginComponent; import java.nio.file.Path; +import java.util.concurrent.ThreadLocalRandom; /** * Test utility for creating a dagger PlanComponent using a mocked Plan. @@ -55,7 +57,10 @@ public class PluginMockComponent { public PlanSystem getPlanSystem() throws Exception { initComponent(); - return component.system(); + PlanSystem system = component.system(); + system.getConfigSystem().getConfig().set(WebserverSettings.PORT, ThreadLocalRandom.current() + .nextInt(65535 - 1024) + 1024); // Random non-privileged port + return system; } private void initComponent() throws Exception {