From 84bd2ee52abbed9624e72435c37fe6fcc3439a8d Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 2 May 2023 00:07:48 +0100 Subject: [PATCH] Add more tests --- .../common/sender/AbstractSender.java | 11 +- .../common/sender/SenderFactory.java | 4 + .../standalone/CommandsIntegrationTest.java | 771 +++++++++++++----- .../ImportExportIntegrationTest.java | 4 +- .../luckperms/standalone/IntegrationTest.java | 4 +- .../standalone/StorageIntegrationTest.java | 136 ++- .../standalone/utils/CommandTester.java | 94 ++- .../standalone/utils/TestPluginBootstrap.java | 63 +- .../example/hocon-combined/groups.conf | 47 ++ .../example/hocon-combined/tracks.conf | 1 + .../example/hocon-combined/users.conf | 51 ++ .../example/hocon/groups/default.conf | 1 + .../resources/example/hocon/groups/test.conf | 43 + .../c1d60c50-70b5-4722-8057-87767557e50d.conf | 50 ++ .../example/json-combined/groups.json | 46 ++ .../example/json-combined/tracks.json | 1 + .../example/json-combined/users.json | 53 ++ .../example/json/groups/default.json | 3 + .../resources/example/json/groups/test.json | 45 + .../c1d60c50-70b5-4722-8057-87767557e50d.json | 52 ++ .../example/toml-combined/groups.toml | 33 + .../example/toml-combined/tracks.toml | 0 .../example/toml-combined/users.toml | 42 + .../example/toml/groups/default.toml | 1 + .../resources/example/toml/groups/test.toml | 37 + .../c1d60c50-70b5-4722-8057-87767557e50d.toml | 42 + .../example/yaml-combined/groups.yml | 28 + .../example/yaml-combined/tracks.yml | 1 + .../resources/example/yaml-combined/users.yml | 30 + .../resources/example/yaml/groups/default.yml | 1 + .../resources/example/yaml/groups/test.yml | 26 + .../c1d60c50-70b5-4722-8057-87767557e50d.yml | 30 + 32 files changed, 1521 insertions(+), 230 deletions(-) create mode 100644 standalone/src/test/resources/example/hocon-combined/groups.conf create mode 100644 standalone/src/test/resources/example/hocon-combined/tracks.conf create mode 100644 standalone/src/test/resources/example/hocon-combined/users.conf create mode 100644 standalone/src/test/resources/example/hocon/groups/default.conf create mode 100644 standalone/src/test/resources/example/hocon/groups/test.conf create mode 100644 standalone/src/test/resources/example/hocon/users/c1d60c50-70b5-4722-8057-87767557e50d.conf create mode 100644 standalone/src/test/resources/example/json-combined/groups.json create mode 100644 standalone/src/test/resources/example/json-combined/tracks.json create mode 100644 standalone/src/test/resources/example/json-combined/users.json create mode 100644 standalone/src/test/resources/example/json/groups/default.json create mode 100644 standalone/src/test/resources/example/json/groups/test.json create mode 100644 standalone/src/test/resources/example/json/users/c1d60c50-70b5-4722-8057-87767557e50d.json create mode 100644 standalone/src/test/resources/example/toml-combined/groups.toml create mode 100644 standalone/src/test/resources/example/toml-combined/tracks.toml create mode 100644 standalone/src/test/resources/example/toml-combined/users.toml create mode 100644 standalone/src/test/resources/example/toml/groups/default.toml create mode 100644 standalone/src/test/resources/example/toml/groups/test.toml create mode 100644 standalone/src/test/resources/example/toml/users/c1d60c50-70b5-4722-8057-87767557e50d.toml create mode 100644 standalone/src/test/resources/example/yaml-combined/groups.yml create mode 100644 standalone/src/test/resources/example/yaml-combined/tracks.yml create mode 100644 standalone/src/test/resources/example/yaml-combined/users.yml create mode 100644 standalone/src/test/resources/example/yaml/groups/default.yml create mode 100644 standalone/src/test/resources/example/yaml/groups/test.yml create mode 100644 standalone/src/test/resources/example/yaml/users/c1d60c50-70b5-4722-8057-87767557e50d.yml diff --git a/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java b/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java index 0d8db2101..0a72cd950 100644 --- a/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java +++ b/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java @@ -31,12 +31,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.luckperms.api.util.Tristate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; /** * Simple implementation of {@link Sender} using a {@link SenderFactory} @@ -89,12 +84,12 @@ public final class AbstractSender implements Sender { @Override public Tristate getPermissionValue(String permission) { - return isConsole() ? Tristate.TRUE : this.factory.getPermissionValue(this.sender, permission); + return (isConsole() && this.factory.consoleHasAllPermissions()) ? Tristate.TRUE : this.factory.getPermissionValue(this.sender, permission); } @Override public boolean hasPermission(String permission) { - return isConsole() || this.factory.hasPermission(this.sender, permission); + return (isConsole() && this.factory.consoleHasAllPermissions()) || this.factory.hasPermission(this.sender, permission); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/sender/SenderFactory.java b/common/src/main/java/me/lucko/luckperms/common/sender/SenderFactory.java index 5d2f2da73..0ec94ac84 100644 --- a/common/src/main/java/me/lucko/luckperms/common/sender/SenderFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/sender/SenderFactory.java @@ -63,6 +63,10 @@ public abstract class SenderFactory

implements Aut protected abstract boolean isConsole(T sender); + protected boolean consoleHasAllPermissions() { + return true; + } + public final Sender wrap(T sender) { Objects.requireNonNull(sender, "sender"); return new AbstractSender<>(this.plugin, this, sender); diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/CommandsIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/CommandsIntegrationTest.java index 419315490..9e29e3736 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/CommandsIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/CommandsIntegrationTest.java @@ -25,33 +25,55 @@ package me.lucko.luckperms.standalone; +import me.lucko.luckperms.common.model.Group; +import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.standalone.app.integration.CommandExecutor; +import me.lucko.luckperms.standalone.app.integration.SingletonPlayer; import me.lucko.luckperms.standalone.utils.CommandTester; import me.lucko.luckperms.standalone.utils.TestPluginProvider; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.luckperms.api.event.log.LogNotifyEvent; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; +import org.testcontainers.shaded.com.google.common.collect.ImmutableSet; import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.*; public class CommandsIntegrationTest { + + private static final Map CONFIG = ImmutableMap.builder() + .put("log-notify", "false") + .build(); @Test public void testGroupCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); - new CommandTester(executor) - .givenCommand("creategroup test") + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.creategroup") + .whenRunCommand("creategroup test") .thenExpect("[LP] test was successfully created.") - .givenCommand("creategroup test2") + .givenHasPermissions("luckperms.creategroup") + .whenRunCommand("creategroup test2") .thenExpect("[LP] test2 was successfully created.") - .givenCommand("deletegroup test2") + .givenHasPermissions("luckperms.deletegroup") + .whenRunCommand("deletegroup test2") .thenExpect("[LP] test2 was successfully deleted.") - .givenCommand("listgroups") + .givenHasPermissions("luckperms.listgroups") + .whenRunCommand("listgroups") .thenExpect(""" [LP] Showing group entries: (page 1 of 1 - 2 entries) [LP] Groups: (name, weight, tracks) @@ -60,7 +82,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test info") + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group test info") .thenExpect(""" [LP] > Group Info: test [LP] - Display Name: test @@ -72,22 +95,28 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test meta set hello world") + .givenHasAllPermissions() + .whenRunCommand("group test meta set hello world") .clearMessageBuffer() - .givenCommand("group test setweight 10") + .givenHasPermissions("luckperms.group.setweight") + .whenRunCommand("group test setweight 10") .thenExpect("[LP] Set weight to 10 for group test.") - .givenCommand("group test setweight 100") + .givenHasPermissions("luckperms.group.setweight") + .whenRunCommand("group test setweight 100") .thenExpect("[LP] Set weight to 100 for group test.") - .givenCommand("group test setdisplayname Test") + .givenHasPermissions("luckperms.group.setdisplayname") + .whenRunCommand("group test setdisplayname Test") .thenExpect("[LP] Set display name to Test for group test in context global.") - .givenCommand("group test setdisplayname Dummy") + .givenHasPermissions("luckperms.group.setdisplayname") + .whenRunCommand("group test setdisplayname Dummy") .thenExpect("[LP] Set display name to Dummy for group test in context global.") - .givenCommand("group Dummy info") + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group Dummy info") .thenExpect(""" [LP] > Group Info: test [LP] - Display Name: Dummy @@ -99,10 +128,12 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test clone testclone") + .givenHasPermissions("luckperms.group.clone") + .whenRunCommand("group test clone testclone") .thenExpect("[LP] test (Dummy) was successfully cloned onto testclone (Dummy).") - .givenCommand("group testclone info") + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group testclone info") .thenExpect(""" [LP] > Group Info: testclone [LP] - Display Name: Dummy @@ -114,10 +145,12 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test rename test2") + .givenHasPermissions("luckperms.group.rename") + .whenRunCommand("group test rename test2") .thenExpect("[LP] test (Dummy) was successfully renamed to test2 (Dummy).") - .givenCommand("group test2 info") + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group test2 info") .thenExpect(""" [LP] > Group Info: test2 [LP] - Display Name: Dummy @@ -129,7 +162,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("listgroups") + .givenHasPermissions("luckperms.listgroups") + .whenRunCommand("listgroups") .thenExpect(""" [LP] Showing group entries: (page 1 of 1 - 3 entries) [LP] Groups: (name, weight, tracks) @@ -143,32 +177,39 @@ public class CommandsIntegrationTest { @Test public void testGroupPermissionCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); - new CommandTester(executor) - .givenCommand("creategroup test") + new CommandTester(plugin, executor) + .whenRunCommand("creategroup test") .clearMessageBuffer() - .givenCommand("group test permission set test.node true") + .givenHasPermissions("luckperms.group.permission.set") + .whenRunCommand("group test permission set test.node true") .thenExpect("[LP] Set test.node to true for test in context global.") - .givenCommand("group test permission set test.node.other false server=test") + .givenHasPermissions("luckperms.group.permission.set") + .whenRunCommand("group test permission set test.node.other false server=test") .thenExpect("[LP] Set test.node.other to false for test in context server=test.") - .givenCommand("group test permission set test.node.other false server=test world=test2") + .givenHasPermissions("luckperms.group.permission.set") + .whenRunCommand("group test permission set test.node.other false server=test world=test2") .thenExpect("[LP] Set test.node.other to false for test in context server=test, world=test2.") - .givenCommand("group test permission settemp abc true 1h") + .givenHasPermissions("luckperms.group.permission.settemp") + .whenRunCommand("group test permission settemp abc true 1h") .thenExpect("[LP] Set abc to true for test for a duration of 1 hour in context global.") - .givenCommand("group test permission settemp abc true 2h replace") + .givenHasPermissions("luckperms.group.permission.settemp") + .whenRunCommand("group test permission settemp abc true 2h replace") .thenExpect("[LP] Set abc to true for test for a duration of 2 hours in context global.") - .givenCommand("group test permission unsettemp abc") + .givenHasPermissions("luckperms.group.permission.unsettemp") + .whenRunCommand("group test permission unsettemp abc") .thenExpect("[LP] Unset temporary permission abc for test in context global.") - .givenCommand("group test permission info") + .givenHasPermissions("luckperms.group.permission.info") + .whenRunCommand("group test permission info") .thenExpect(""" [LP] test's Permissions: (page 1 of 1 - 3 entries) > test.node.other (server=test) (world=test2) @@ -177,16 +218,20 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test permission unset test.node") + .givenHasPermissions("luckperms.group.permission.unset") + .whenRunCommand("group test permission unset test.node") .thenExpect("[LP] Unset test.node for test in context global.") - .givenCommand("group test permission unset test.node.other") + .givenHasPermissions("luckperms.group.permission.unset") + .whenRunCommand("group test permission unset test.node.other") .thenExpect("[LP] test does not have test.node.other set in context global.") - .givenCommand("group test permission unset test.node.other server=test") + .givenHasPermissions("luckperms.group.permission.unset") + .whenRunCommand("group test permission unset test.node.other server=test") .thenExpect("[LP] Unset test.node.other for test in context server=test.") - .givenCommand("group test permission check test.node.other") + .givenHasPermissions("luckperms.group.permission.check") + .whenRunCommand("group test permission check test.node.other") .thenExpect(""" [LP] Permission information for test.node.other: [LP] - test has test.node.other set to false in context server=test, world=test2. @@ -200,41 +245,49 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test permission clear server=test world=test2") + .givenHasPermissions("luckperms.group.permission.clear") + .whenRunCommand("group test permission clear server=test world=test2") .thenExpect("[LP] test's permissions were cleared in context server=test, world=test2. (1 node was removed.)") - .givenCommand("group test permission info") + .givenHasPermissions("luckperms.group.permission.info") + .whenRunCommand("group test permission info") .thenExpect("[LP] test does not have any permissions set."); }); } @Test public void testGroupParentCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); - new CommandTester(executor) - .givenCommand("creategroup test") - .givenCommand("creategroup test2") - .givenCommand("creategroup test3") + new CommandTester(plugin, executor) + .whenRunCommand("creategroup test") + .whenRunCommand("creategroup test2") + .whenRunCommand("creategroup test3") .clearMessageBuffer() - .givenCommand("group test parent add default") + .givenHasPermissions("luckperms.group.parent.add") + .whenRunCommand("group test parent add default") .thenExpect("[LP] test now inherits permissions from default in context global.") - .givenCommand("group test parent add test2 server=test") + .givenHasPermissions("luckperms.group.parent.add") + .whenRunCommand("group test parent add test2 server=test") .thenExpect("[LP] test now inherits permissions from test2 in context server=test.") - .givenCommand("group test parent add test3 server=test") + .givenHasPermissions("luckperms.group.parent.add") + .whenRunCommand("group test parent add test3 server=test") .thenExpect("[LP] test now inherits permissions from test3 in context server=test.") - .givenCommand("group test parent addtemp test2 1d server=hello") + .givenHasPermissions("luckperms.group.parent.addtemp") + .whenRunCommand("group test parent addtemp test2 1d server=hello") .thenExpect("[LP] test now inherits permissions from test2 for a duration of 1 day in context server=hello.") - .givenCommand("group test parent removetemp test2 server=hello") + .givenHasPermissions("luckperms.group.parent.removetemp") + .whenRunCommand("group test parent removetemp test2 server=hello") .thenExpect("[LP] test no longer temporarily inherits permissions from test2 in context server=hello.") - .givenCommand("group test parent info") + .givenHasPermissions("luckperms.group.parent.info") + .whenRunCommand("group test parent info") .thenExpect(""" [LP] test's Parents: (page 1 of 1 - 3 entries) > test2 (server=test) @@ -243,30 +296,35 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test parent set test2 server=test") + .givenHasPermissions("luckperms.group.parent.set") + .whenRunCommand("group test parent set test2 server=test") .thenExpect("[LP] test had their existing parent groups cleared, and now only inherits test2 in context server=test.") - .givenCommand("group test parent remove test2 server=test") + .givenHasPermissions("luckperms.group.parent.remove") + .whenRunCommand("group test parent remove test2 server=test") .thenExpect("[LP] test no longer inherits permissions from test2 in context server=test.") - .givenCommand("group test parent clear") + .givenHasPermissions("luckperms.group.parent.clear") + .whenRunCommand("group test parent clear") .thenExpect("[LP] test's parents were cleared in context global. (1 node was removed.)") - .givenCommand("group test parent info") + .givenHasPermissions("luckperms.group.parent.info") + .whenRunCommand("group test parent info") .thenExpect("[LP] test does not have any parents defined."); }); } @Test public void testGroupMetaCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); - new CommandTester(executor) - .givenCommand("creategroup test") + new CommandTester(plugin, executor) + .whenRunCommand("creategroup test") .clearMessageBuffer() - .givenCommand("group test meta info") + .givenHasPermissions("luckperms.group.meta.info") + .whenRunCommand("group test meta info") .thenExpect(""" [LP] test has no prefixes. [LP] test has no suffixes. @@ -274,40 +332,53 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test meta set hello world") + .givenHasPermissions("luckperms.group.meta.set") + .whenRunCommand("group test meta set hello world") .thenExpect("[LP] Set meta key 'hello' to 'world' for test in context global.") - .givenCommand("group test meta set hello world2 server=test") + + .givenHasPermissions("luckperms.group.meta.set") + .whenRunCommand("group test meta set hello world2 server=test") .thenExpect("[LP] Set meta key 'hello' to 'world2' for test in context server=test.") - .givenCommand("group test meta addprefix 10 \"&ehello world\"") + .givenHasPermissions("luckperms.group.meta.addprefix") + .whenRunCommand("group test meta addprefix 10 \"&ehello world\"") .thenExpect("[LP] test had prefix 'hello world' set at a priority of 10 in context global.") - .givenCommand("group test meta addsuffix 100 \"&ehi\"") + .givenHasPermissions("luckperms.group.meta.addsuffix") + .whenRunCommand("group test meta addsuffix 100 \"&ehi\"") .thenExpect("[LP] test had suffix 'hi' set at a priority of 100 in context global.") - .givenCommand("group test meta addsuffix 1 \"&6no\"") + .givenHasPermissions("luckperms.group.meta.addsuffix") + .whenRunCommand("group test meta addsuffix 1 \"&6no\"") .thenExpect("[LP] test had suffix 'no' set at a priority of 1 in context global.") - .givenCommand("group test meta settemp abc xyz 1d server=hello") + .givenHasPermissions("luckperms.group.meta.settemp") + .whenRunCommand("group test meta settemp abc xyz 1d server=hello") .thenExpect("[LP] Set meta key 'abc' to 'xyz' for test for a duration of 1 day in context server=hello.") - .givenCommand("group test meta addtempprefix 1000 abc 1d server=hello") + .givenHasPermissions("luckperms.group.meta.addtempprefix") + .whenRunCommand("group test meta addtempprefix 1000 abc 1d server=hello") .thenExpect("[LP] test had prefix 'abc' set at a priority of 1000 for a duration of 1 day in context server=hello.") - .givenCommand("group test meta addtempsuffix 1000 xyz 3d server=hello") + .givenHasPermissions("luckperms.group.meta.addtempsuffix") + .whenRunCommand("group test meta addtempsuffix 1000 xyz 3d server=hello") .thenExpect("[LP] test had suffix 'xyz' set at a priority of 1000 for a duration of 3 days in context server=hello.") - .givenCommand("group test meta unsettemp abc server=hello") + .givenHasPermissions("luckperms.group.meta.unsettemp") + .whenRunCommand("group test meta unsettemp abc server=hello") .thenExpect("[LP] Unset temporary meta key 'abc' for test in context server=hello.") - .givenCommand("group test meta removetempprefix 1000 abc server=hello") + .givenHasPermissions("luckperms.group.meta.removetempprefix") + .whenRunCommand("group test meta removetempprefix 1000 abc server=hello") .thenExpect("[LP] test had temporary prefix 'abc' at priority 1000 removed in context server=hello.") - .givenCommand("group test meta removetempsuffix 1000 xyz server=hello") + .givenHasPermissions("luckperms.group.meta.removetempsuffix") + .whenRunCommand("group test meta removetempsuffix 1000 xyz server=hello") .thenExpect("[LP] test had temporary suffix 'xyz' at priority 1000 removed in context server=hello.") - .givenCommand("group test meta info") + .givenHasPermissions("luckperms.group.meta.info") + .whenRunCommand("group test meta info") .thenExpect(""" [LP] test's Prefixes [LP] -> 10 - 'hello world' (inherited from self) @@ -320,7 +391,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test info") + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group test info") .thenExpect(""" [LP] > Group Info: test [LP] - Display Name: test @@ -332,22 +404,28 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("group test meta unset hello") + .givenHasPermissions("luckperms.group.meta.unset") + .whenRunCommand("group test meta unset hello") .thenExpect("[LP] Unset meta key 'hello' for test in context global.") - .givenCommand("group test meta unset hello server=test") + .givenHasPermissions("luckperms.group.meta.unset") + .whenRunCommand("group test meta unset hello server=test") .thenExpect("[LP] Unset meta key 'hello' for test in context server=test.") - .givenCommand("group test meta removeprefix 10") + .givenHasPermissions("luckperms.group.meta.removeprefix") + .whenRunCommand("group test meta removeprefix 10") .thenExpect("[LP] test had all prefixes at priority 10 removed in context global.") - .givenCommand("group test meta removesuffix 100") + .givenHasPermissions("luckperms.group.meta.removesuffix") + .whenRunCommand("group test meta removesuffix 100") .thenExpect("[LP] test had all suffixes at priority 100 removed in context global.") - .givenCommand("group test meta removesuffix 1") + .givenHasPermissions("luckperms.group.meta.removesuffix") + .whenRunCommand("group test meta removesuffix 1") .thenExpect("[LP] test had all suffixes at priority 1 removed in context global.") - .givenCommand("group test meta info") + .givenHasPermissions("luckperms.group.meta.info") + .whenRunCommand("group test meta info") .thenExpect(""" [LP] test has no prefixes. [LP] test has no suffixes. @@ -359,14 +437,15 @@ public class CommandsIntegrationTest { @Test public void testUserCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); plugin.getStorage().savePlayerData(UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5"), "Notch").join(); - new CommandTester(executor) - .givenCommand("user Luck info") + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.user.info") + .whenRunCommand("user Luck info") .thenExpect(""" [LP] > User Info: luck [LP] - UUID: c1d60c50-70b5-4722-8057-87767557e50d @@ -383,7 +462,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user c1d60c50-70b5-4722-8057-87767557e50d info") + .givenHasPermissions("luckperms.user.info") + .whenRunCommand("user c1d60c50-70b5-4722-8057-87767557e50d info") .thenExpect(""" [LP] > User Info: luck [LP] - UUID: c1d60c50-70b5-4722-8057-87767557e50d @@ -400,14 +480,17 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("creategroup admin") - .givenCommand("user Luck parent set admin") + .givenHasAllPermissions() + .whenRunCommand("creategroup admin") + .whenRunCommand("user Luck parent set admin") .clearMessageBuffer() - .givenCommand("user Luck clone Notch") + .givenHasPermissions("luckperms.user.clone") + .whenRunCommand("user Luck clone Notch") .thenExpect("[LP] luck was successfully cloned onto notch.") - .givenCommand("user Notch parent info") + .givenHasPermissions("luckperms.user.parent.info") + .whenRunCommand("user Notch parent info") .thenExpect(""" [LP] notch's Parents: (page 1 of 1 - 1 entries) > admin @@ -418,31 +501,38 @@ public class CommandsIntegrationTest { @Test public void testUserPermissionCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); - new CommandTester(executor) - .givenCommand("user Luck permission set test.node true") + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.user.permission.set") + .whenRunCommand("user Luck permission set test.node true") .thenExpect("[LP] Set test.node to true for luck in context global.") - .givenCommand("user Luck permission set test.node.other false server=test") + .givenHasPermissions("luckperms.user.permission.set") + .whenRunCommand("user Luck permission set test.node.other false server=test") .thenExpect("[LP] Set test.node.other to false for luck in context server=test.") - .givenCommand("user Luck permission set test.node.other false server=test world=test2") + .givenHasPermissions("luckperms.user.permission.set") + .whenRunCommand("user Luck permission set test.node.other false server=test world=test2") .thenExpect("[LP] Set test.node.other to false for luck in context server=test, world=test2.") - .givenCommand("user Luck permission settemp abc true 1h") + .givenHasPermissions("luckperms.user.permission.settemp") + .whenRunCommand("user Luck permission settemp abc true 1h") .thenExpect("[LP] Set abc to true for luck for a duration of 1 hour in context global.") - .givenCommand("user Luck permission settemp abc true 2h replace") + .givenHasPermissions("luckperms.user.permission.settemp") + .whenRunCommand("user Luck permission settemp abc true 2h replace") .thenExpect("[LP] Set abc to true for luck for a duration of 2 hours in context global.") - .givenCommand("user Luck permission unsettemp abc") + .givenHasPermissions("luckperms.user.permission.unsettemp") + .whenRunCommand("user Luck permission unsettemp abc") .thenExpect("[LP] Unset temporary permission abc for luck in context global.") - .givenCommand("user Luck permission info") + .givenHasPermissions("luckperms.user.permission.info") + .whenRunCommand("user Luck permission info") .thenExpect(""" [LP] luck's Permissions: (page 1 of 1 - 3 entries) > test.node.other (server=test) (world=test2) @@ -451,16 +541,20 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck permission unset test.node") + .givenHasPermissions("luckperms.user.permission.unset") + .whenRunCommand("user Luck permission unset test.node") .thenExpect("[LP] Unset test.node for luck in context global.") - .givenCommand("user Luck permission unset test.node.other") + .givenHasPermissions("luckperms.user.permission.unset") + .whenRunCommand("user Luck permission unset test.node.other") .thenExpect("[LP] luck does not have test.node.other set in context global.") - .givenCommand("user Luck permission unset test.node.other server=test") + .givenHasPermissions("luckperms.user.permission.unset") + .whenRunCommand("user Luck permission unset test.node.other server=test") .thenExpect("[LP] Unset test.node.other for luck in context server=test.") - .givenCommand("user Luck permission check test.node.other") + .givenHasPermissions("luckperms.user.permission.check") + .whenRunCommand("user Luck permission check test.node.other") .thenExpect(""" [LP] Permission information for test.node.other: [LP] - luck has test.node.other set to false in context server=test, world=test2. @@ -474,42 +568,50 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck permission clear server=test world=test2") + .givenHasPermissions("luckperms.user.permission.clear") + .whenRunCommand("user Luck permission clear server=test world=test2") .thenExpect("[LP] luck's permissions were cleared in context server=test, world=test2. (1 node was removed.)") - .givenCommand("user Luck permission info") + .givenHasPermissions("luckperms.user.permission.info") + .whenRunCommand("user Luck permission info") .thenExpect("[LP] luck does not have any permissions set."); }); } @Test public void testUserParentCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); - new CommandTester(executor) - .givenCommand("creategroup test2") - .givenCommand("creategroup test3") + new CommandTester(plugin, executor) + .whenRunCommand("creategroup test2") + .whenRunCommand("creategroup test3") .clearMessageBuffer() - .givenCommand("user Luck parent add default") + .givenHasPermissions("luckperms.user.parent.add") + .whenRunCommand("user Luck parent add default") .thenExpect("[LP] luck already inherits from default in context global.") - .givenCommand("user Luck parent add test2 server=test") + .givenHasPermissions("luckperms.user.parent.add") + .whenRunCommand("user Luck parent add test2 server=test") .thenExpect("[LP] luck now inherits permissions from test2 in context server=test.") - .givenCommand("user Luck parent add test3 server=test") + .givenHasPermissions("luckperms.user.parent.add") + .whenRunCommand("user Luck parent add test3 server=test") .thenExpect("[LP] luck now inherits permissions from test3 in context server=test.") - .givenCommand("user Luck parent addtemp test2 1d server=hello") + .givenHasPermissions("luckperms.user.parent.addtemp") + .whenRunCommand("user Luck parent addtemp test2 1d server=hello") .thenExpect("[LP] luck now inherits permissions from test2 for a duration of 1 day in context server=hello.") - .givenCommand("user Luck parent removetemp test2 server=hello") + .givenHasPermissions("luckperms.user.parent.removetemp") + .whenRunCommand("user Luck parent removetemp test2 server=hello") .thenExpect("[LP] luck no longer temporarily inherits permissions from test2 in context server=hello.") - .givenCommand("user Luck parent info") + .givenHasPermissions("luckperms.user.parent.info") + .whenRunCommand("user Luck parent info") .thenExpect(""" [LP] luck's Parents: (page 1 of 1 - 3 entries) > test2 (server=test) @@ -518,16 +620,20 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck parent set test2 server=test") + .givenHasPermissions("luckperms.user.parent.set") + .whenRunCommand("user Luck parent set test2 server=test") .thenExpect("[LP] luck had their existing parent groups cleared, and now only inherits test2 in context server=test.") - .givenCommand("user Luck parent remove test2 server=test") + .givenHasPermissions("luckperms.user.parent.remove") + .whenRunCommand("user Luck parent remove test2 server=test") .thenExpect("[LP] luck no longer inherits permissions from test2 in context server=test.") - .givenCommand("user Luck parent clear") + .givenHasPermissions("luckperms.user.parent.clear") + .whenRunCommand("user Luck parent clear") .thenExpect("[LP] luck's parents were cleared in context global. (0 nodes were removed.)") - .givenCommand("user Luck parent info") + .givenHasPermissions("luckperms.user.parent.info") + .whenRunCommand("user Luck parent info") .thenExpect(""" [LP] luck's Parents: (page 1 of 1 - 1 entries) > default @@ -538,13 +644,14 @@ public class CommandsIntegrationTest { @Test public void testUserMetaCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); - new CommandTester(executor) - .givenCommand("user Luck meta info") + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.user.meta.info") + .whenRunCommand("user Luck meta info") .thenExpect(""" [LP] luck has no prefixes. [LP] luck has no suffixes. @@ -552,40 +659,52 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck meta set hello world") + .givenHasPermissions("luckperms.user.meta.set") + .whenRunCommand("user Luck meta set hello world") .thenExpect("[LP] Set meta key 'hello' to 'world' for luck in context global.") - .givenCommand("user Luck meta set hello world2 server=test") + .givenHasPermissions("luckperms.user.meta.set") + .whenRunCommand("user Luck meta set hello world2 server=test") .thenExpect("[LP] Set meta key 'hello' to 'world2' for luck in context server=test.") - .givenCommand("user Luck meta addprefix 10 \"&ehello world\"") + .givenHasPermissions("luckperms.user.meta.addprefix") + .whenRunCommand("user Luck meta addprefix 10 \"&ehello world\"") .thenExpect("[LP] luck had prefix 'hello world' set at a priority of 10 in context global.") - .givenCommand("user Luck meta addsuffix 100 \"&ehi\"") + .givenHasPermissions("luckperms.user.meta.addsuffix") + .whenRunCommand("user Luck meta addsuffix 100 \"&ehi\"") .thenExpect("[LP] luck had suffix 'hi' set at a priority of 100 in context global.") - .givenCommand("user Luck meta addsuffix 1 \"&6no\"") + .givenHasPermissions("luckperms.user.meta.addsuffix") + .whenRunCommand("user Luck meta addsuffix 1 \"&6no\"") .thenExpect("[LP] luck had suffix 'no' set at a priority of 1 in context global.") - .givenCommand("user Luck meta settemp abc xyz 1d server=hello") + .givenHasPermissions("luckperms.user.meta.settemp") + .whenRunCommand("user Luck meta settemp abc xyz 1d server=hello") .thenExpect("[LP] Set meta key 'abc' to 'xyz' for luck for a duration of 1 day in context server=hello.") - .givenCommand("user Luck meta addtempprefix 1000 abc 1d server=hello") + .givenHasPermissions("luckperms.user.meta.addtempprefix") + .whenRunCommand("user Luck meta addtempprefix 1000 abc 1d server=hello") .thenExpect("[LP] luck had prefix 'abc' set at a priority of 1000 for a duration of 1 day in context server=hello.") - .givenCommand("user Luck meta addtempsuffix 1000 xyz 3d server=hello") + .givenHasPermissions("luckperms.user.meta.addtempsuffix") + .whenRunCommand("user Luck meta addtempsuffix 1000 xyz 3d server=hello") .thenExpect("[LP] luck had suffix 'xyz' set at a priority of 1000 for a duration of 3 days in context server=hello.") - .givenCommand("user Luck meta unsettemp abc server=hello") + .givenHasPermissions("luckperms.user.meta.unsettemp") + .whenRunCommand("user Luck meta unsettemp abc server=hello") .thenExpect("[LP] Unset temporary meta key 'abc' for luck in context server=hello.") - .givenCommand("user Luck meta removetempprefix 1000 abc server=hello") + .givenHasPermissions("luckperms.user.meta.removetempprefix") + .whenRunCommand("user Luck meta removetempprefix 1000 abc server=hello") .thenExpect("[LP] luck had temporary prefix 'abc' at priority 1000 removed in context server=hello.") - .givenCommand("user Luck meta removetempsuffix 1000 xyz server=hello") + .givenHasPermissions("luckperms.user.meta.removetempsuffix") + .whenRunCommand("user Luck meta removetempsuffix 1000 xyz server=hello") .thenExpect("[LP] luck had temporary suffix 'xyz' at priority 1000 removed in context server=hello.") - .givenCommand("user Luck meta info") + .givenHasPermissions("luckperms.user.meta.info") + .whenRunCommand("user Luck meta info") .thenExpect(""" [LP] luck's Prefixes [LP] -> 10 - 'hello world' (inherited from self) @@ -598,7 +717,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck info") + .givenHasPermissions("luckperms.user.info") + .whenRunCommand("user Luck info") .thenExpect(""" [LP] > User Info: luck [LP] - UUID: c1d60c50-70b5-4722-8057-87767557e50d @@ -615,22 +735,28 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck meta unset hello") + .givenHasPermissions("luckperms.user.meta.unset") + .whenRunCommand("user Luck meta unset hello") .thenExpect("[LP] Unset meta key 'hello' for luck in context global.") - .givenCommand("user Luck meta unset hello server=test") + .givenHasPermissions("luckperms.user.meta.unset") + .whenRunCommand("user Luck meta unset hello server=test") .thenExpect("[LP] Unset meta key 'hello' for luck in context server=test.") - .givenCommand("user Luck meta removeprefix 10") + .givenHasPermissions("luckperms.user.meta.removeprefix") + .whenRunCommand("user Luck meta removeprefix 10") .thenExpect("[LP] luck had all prefixes at priority 10 removed in context global.") - .givenCommand("user Luck meta removesuffix 100") + .givenHasPermissions("luckperms.user.meta.removesuffix") + .whenRunCommand("user Luck meta removesuffix 100") .thenExpect("[LP] luck had all suffixes at priority 100 removed in context global.") - .givenCommand("user Luck meta removesuffix 1") + .givenHasPermissions("luckperms.user.meta.removesuffix") + .whenRunCommand("user Luck meta removesuffix 1") .thenExpect("[LP] luck had all suffixes at priority 1 removed in context global.") - .givenCommand("user Luck meta info") + .givenHasPermissions("luckperms.user.meta.info") + .whenRunCommand("user Luck meta info") .thenExpect(""" [LP] luck has no prefixes. [LP] luck has no suffixes. @@ -642,75 +768,90 @@ public class CommandsIntegrationTest { @Test public void testTrackCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); - new CommandTester(executor) - .givenCommand("createtrack test1") + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.createtrack") + .whenRunCommand("createtrack test1") .thenExpect("[LP] test1 was successfully created.") - .givenCommand("createtrack test2") + .givenHasPermissions("luckperms.createtrack") + .whenRunCommand("createtrack test2") .thenExpect("[LP] test2 was successfully created.") - .givenCommand("listtracks") + .givenHasPermissions("luckperms.listtracks") + .whenRunCommand("listtracks") .thenExpect("[LP] Tracks: test1, test2") - .givenCommand("deletetrack test2") + .givenHasPermissions("luckperms.deletetrack") + .whenRunCommand("deletetrack test2") .thenExpect("[LP] test2 was successfully deleted.") - .givenCommand("creategroup aaa") - .givenCommand("creategroup bbb") - .givenCommand("creategroup ccc") + .givenHasAllPermissions() + .whenRunCommand("creategroup aaa") + .whenRunCommand("creategroup bbb") + .whenRunCommand("creategroup ccc") .clearMessageBuffer() - .givenCommand("track test1 append bbb") + .givenHasPermissions("luckperms.track.append") + .whenRunCommand("track test1 append bbb") .thenExpect("[LP] Group bbb was appended to track test1.") - .givenCommand("track test1 insert aaa 1") + .givenHasPermissions("luckperms.track.insert") + .whenRunCommand("track test1 insert aaa 1") .thenExpect(""" [LP] Group aaa was inserted into track test1 at position 1. [LP] aaa ---> bbb """ ) - .givenCommand("track test1 insert ccc 3") + .givenHasPermissions("luckperms.track.insert") + .whenRunCommand("track test1 insert ccc 3") .thenExpect(""" [LP] Group ccc was inserted into track test1 at position 3. [LP] aaa ---> bbb ---> ccc """ ) - .givenCommand("track test1 info") + .givenHasPermissions("luckperms.track.info") + .whenRunCommand("track test1 info") .thenExpect(""" [LP] > Showing Track: test1 [LP] - Path: aaa ---> bbb ---> ccc """ ) - .givenCommand("track test1 clone testclone") + .givenHasPermissions("luckperms.track.clone") + .whenRunCommand("track test1 clone testclone") .thenExpect("[LP] test1 was successfully cloned onto testclone.") - .givenCommand("track testclone info") + .givenHasPermissions("luckperms.track.info") + .whenRunCommand("track testclone info") .thenExpect(""" [LP] > Showing Track: testclone [LP] - Path: aaa ---> bbb ---> ccc """ ) - .givenCommand("track test1 rename test2") + .givenHasPermissions("luckperms.track.rename") + .whenRunCommand("track test1 rename test2") .thenExpect("[LP] test1 was successfully renamed to test2.") - .givenCommand("listtracks") + .givenHasPermissions("luckperms.listtracks") + .whenRunCommand("listtracks") .thenExpect("[LP] Tracks: test2, testclone") - .givenCommand("track test2 info") + .givenHasPermissions("luckperms.track.info") + .whenRunCommand("track test2 info") .thenExpect(""" [LP] > Showing Track: test2 [LP] - Path: aaa ---> bbb ---> ccc """ ) - .givenCommand("group aaa showtracks") + .givenHasPermissions("luckperms.group.showtracks") + .whenRunCommand("group aaa showtracks") .thenExpect(""" [LP] aaa's Tracks: > test2: @@ -720,93 +861,106 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("track test2 remove bbb") + .givenHasPermissions("luckperms.track.remove") + .whenRunCommand("track test2 remove bbb") .thenExpect(""" [LP] Group bbb was removed from track test2. [LP] aaa ---> ccc """ ) - .givenCommand("track test2 clear") + .givenHasPermissions("luckperms.track.clear") + .whenRunCommand("track test2 clear") .thenExpect("[LP] test2's groups track was cleared."); }); } @Test public void testUserTrackCommands(@TempDir Path tempDir) { - TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { CommandExecutor executor = app.getCommandExecutor(); plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); - new CommandTester(executor) - .givenCommand("createtrack staff") - .givenCommand("createtrack premium") + new CommandTester(plugin, executor) + .whenRunCommand("createtrack staff") + .whenRunCommand("createtrack premium") - .givenCommand("creategroup mod") - .givenCommand("creategroup admin") + .whenRunCommand("creategroup mod") + .whenRunCommand("creategroup admin") - .givenCommand("creategroup vip") - .givenCommand("creategroup vip+") - .givenCommand("creategroup mvp") - .givenCommand("creategroup mvp+") + .whenRunCommand("creategroup vip") + .whenRunCommand("creategroup vip+") + .whenRunCommand("creategroup mvp") + .whenRunCommand("creategroup mvp+") - .givenCommand("track staff append mod") - .givenCommand("track staff append admin") - .givenCommand("track premium append vip") - .givenCommand("track premium append vip+") - .givenCommand("track premium append mvp") - .givenCommand("track premium append mvp+") + .whenRunCommand("track staff append mod") + .whenRunCommand("track staff append admin") + .whenRunCommand("track premium append vip") + .whenRunCommand("track premium append vip+") + .whenRunCommand("track premium append mvp") + .whenRunCommand("track premium append mvp+") .clearMessageBuffer() - .givenCommand("user Luck promote staff") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote staff") .thenExpect("[LP] luck isn't in any groups on staff, so they were added to the first group, mod in context global.") - .givenCommand("user Luck promote staff") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote staff") .thenExpect(""" [LP] Promoting luck along track staff from mod to admin in context global. [LP] mod ---> admin """ ) - .givenCommand("user Luck promote staff") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote staff") .thenExpect("[LP] The end of track staff was reached, unable to promote luck.") - .givenCommand("user Luck demote staff") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote staff") .thenExpect(""" [LP] Demoting luck along track staff from admin to mod in context global. [LP] mod <--- admin """ ) - .givenCommand("user Luck demote staff") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote staff") .thenExpect("[LP] The end of track staff was reached, so luck was removed from mod.") - .givenCommand("user Luck demote staff") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote staff") .thenExpect("[LP] luck isn't already in any groups on staff.") - .givenCommand("user Luck promote premium server=test1") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote premium server=test1") .thenExpect("[LP] luck isn't in any groups on premium, so they were added to the first group, vip in context server=test1.") - .givenCommand("user Luck promote premium server=test2") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote premium server=test2") .thenExpect("[LP] luck isn't in any groups on premium, so they were added to the first group, vip in context server=test2.") - .givenCommand("user Luck promote premium server=test1") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote premium server=test1") .thenExpect(""" [LP] Promoting luck along track premium from vip to vip+ in context server=test1. [LP] vip ---> vip+ ---> mvp ---> mvp+ """ ) - .givenCommand("user Luck promote premium server=test2") + .givenHasPermissions("luckperms.user.promote") + .whenRunCommand("user Luck promote premium server=test2") .thenExpect(""" [LP] Promoting luck along track premium from vip to vip+ in context server=test2. [LP] vip ---> vip+ ---> mvp ---> mvp+ """ ) - .givenCommand("user Luck parent info") + .givenHasPermissions("luckperms.user.parent.info") + .whenRunCommand("user Luck parent info") .thenExpect(""" [LP] luck's Parents: (page 1 of 1 - 3 entries) > vip+ (server=test2) @@ -815,7 +969,8 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck showtracks") + .givenHasPermissions("luckperms.user.showtracks") + .whenRunCommand("user Luck showtracks") .thenExpect(""" [LP] luck's Tracks: > premium: (server=test2) @@ -825,27 +980,32 @@ public class CommandsIntegrationTest { """ ) - .givenCommand("user Luck demote premium server=test1") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote premium server=test1") .thenExpect(""" [LP] Demoting luck along track premium from vip+ to vip in context server=test1. [LP] vip <--- vip+ <--- mvp <--- mvp+ """ ) - .givenCommand("user Luck demote premium server=test2") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote premium server=test2") .thenExpect(""" [LP] Demoting luck along track premium from vip+ to vip in context server=test2. [LP] vip <--- vip+ <--- mvp <--- mvp+ """ ) - .givenCommand("user Luck demote premium server=test1") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote premium server=test1") .thenExpect("[LP] The end of track premium was reached, so luck was removed from vip.") - .givenCommand("user Luck demote premium server=test2") + .givenHasPermissions("luckperms.user.demote") + .whenRunCommand("user Luck demote premium server=test2") .thenExpect("[LP] The end of track premium was reached, so luck was removed from vip.") - .givenCommand("user Luck parent info") + .givenHasPermissions("luckperms.user.parent.info") + .whenRunCommand("user Luck parent info") .thenExpect(""" [LP] luck's Parents: (page 1 of 1 - 1 entries) > default @@ -854,4 +1014,245 @@ public class CommandsIntegrationTest { }); } + @Test + public void testSearchCommand(@TempDir Path tempDir) { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + + plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); + + new CommandTester(plugin, executor) + .whenRunCommand("creategroup test") + .whenRunCommand("user Luck permission set hello.world true server=survival") + .whenRunCommand("group test permission set hello.world true world=nether") + .whenRunCommand("user Luck parent add test") + .clearMessageBuffer() + + .givenHasPermissions("luckperms.search") + .whenRunCommand("search hello.world") + .thenExpect(""" + [LP] Searching for users and groups with permissions == hello.world... + [LP] Found 2 entries from 1 users and 1 groups. + [LP] Showing user entries: (page 1 of 1 - 1 entries) + > luck - true (server=survival) + [LP] Showing group entries: (page 1 of 1 - 1 entries) + > test - true (world=nether) + """ + ) + + .givenHasPermissions("luckperms.search") + .whenRunCommand("search ~~ group.%") + .thenExpect(""" + [LP] Searching for users and groups with permissions ~~ group.%... + [LP] Found 2 entries from 2 users and 0 groups. + [LP] Showing user entries: (page 1 of 1 - 2 entries) + > luck - (group.test) - true + > luck - (group.default) - true + """ + ); + }); + } + + @Test + public void testBulkUpdate(@TempDir Path tempDir) throws InterruptedException { + Map config = new HashMap<>(CONFIG); + config.put("skip-bulkupdate-confirmation", "true"); + + TestPluginProvider.use(tempDir, config, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + + plugin.getStorage().savePlayerData(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), "Luck").join(); + plugin.getStorage().savePlayerData(UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5"), "Notch").join(); + + CountDownLatch completed = new CountDownLatch(1); + + SingletonPlayer.INSTANCE.addMessageSink(component -> { + String plain = PlainTextComponentSerializer.plainText().serialize(component); + if (plain.contains("Bulk update completed successfully")) { + completed.countDown(); + } + }); + + new CommandTester(plugin, executor) + .whenRunCommand("creategroup moderator") + .whenRunCommand("creategroup admin") + .whenRunCommand("user Luck parent add moderator server=survival") + .whenRunCommand("user Notch parent add moderator") + .whenRunCommand("group admin parent add moderator") + .whenRunCommand("group moderator rename mod") + .clearMessageBuffer() + + .givenHasPermissions("luckperms.bulkupdate") + .whenRunCommand("bulkupdate all update permission group.mod \"permission == group.moderator\"") + .thenExpect("[LP] Running bulk update."); + + assertTrue(completed.await(5, TimeUnit.SECONDS)); + + Group adminGroup = plugin.getGroupManager().getIfLoaded("admin"); + assertNotNull(adminGroup); + assertEquals(ImmutableSet.of(Inheritance.builder("mod").build()), adminGroup.normalData().asSet()); + + User luckUser = plugin.getStorage().loadUser(UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"), null).join(); + assertNotNull(luckUser); + assertEquals( + ImmutableSet.of( + Inheritance.builder("default").build(), + Inheritance.builder("mod").withContext("server", "survival").build() + ), + luckUser.normalData().asSet() + ); + + User notchUser = plugin.getStorage().loadUser(UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5"), null).join(); + assertNotNull(notchUser); + assertEquals( + ImmutableSet.of( + Inheritance.builder("default").build(), + Inheritance.builder("mod").build() + ), + notchUser.normalData().asSet() + ); + }); + } + + @Test + public void testInvalidCommands(@TempDir Path tempDir) { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.user.info") + .whenRunCommand("user unknown info") + .thenExpect("[LP] A user for unknown could not be found.") + + .givenHasPermissions("luckperms.user.info") + .whenRunCommand("user unknown unknown") + .thenExpect("[LP] Command not recognised.") + + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group unknown info") + .thenExpect("[LP] A group named unknown could not be found.") + + .givenHasPermissions("luckperms.group.info") + .whenRunCommand("group unknown unknown") + .thenExpect("[LP] Command not recognised.") + + .givenHasPermissions("luckperms.track.info") + .whenRunCommand("track unknown info") + .thenExpect("[LP] A track named unknown could not be found.") + + .givenHasPermissions("luckperms.track.info") + .whenRunCommand("track unknown unknown") + .thenExpect("[LP] Command not recognised."); + }); + } + + @Test + public void testNoPermissions(@TempDir Path tempDir) { + TestPluginProvider.use(tempDir, CONFIG, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + String version = "v" + bootstrap.getVersion(); + + new CommandTester(plugin, executor) + .givenHasPermissions(/* empty */) + + .whenRunCommand("") + .thenExpect(""" + [LP] Running LuckPerms %s. + [LP] It seems that no permissions have been setup yet! + [LP] Before you can use any of the LuckPerms commands in-game, you need to use the console to give yourself access. + [LP] Open your console and run: + [LP] > lp user StandaloneUser permission set luckperms.* true + [LP] After you've done this, you can begin to define your permission assignments and groups. + [LP] Don't know where to start? Check here: https://luckperms.net/wiki/Usage + """.formatted(version) + ) + + .whenRunCommand("help") + .thenExpect("[LP] Running LuckPerms %s.".formatted(version)) + + .whenRunCommand("group default info") + .thenExpect("[LP] Running LuckPerms %s.".formatted(version)); + }); + } + + @Test + public void testLogNotify(@TempDir Path tempDir) { + Map config = new HashMap<>(CONFIG); + config.put("log-notify", "true"); + + TestPluginProvider.use(tempDir, config, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + + // by default, notifications are not sent to the user who initiated the event - override that + app.getApi().getEventBus().subscribe(LogNotifyEvent.class, e -> e.setCancelled(false)); + + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.group.permission.set", "luckperms.log.notify") + .whenRunCommand("group default permission set hello.world true server=test") + .thenExpect(""" + [LP] Set hello.world to true for default in context server=test. + [LP] LOG > (StandaloneUser) [G] (default) + [LP] LOG > permission set hello.world true server=test + """ + ); + }); + } + + @Test + public void testArgumentBasedCommandPermissions(@TempDir Path tempDir) { + Map config = new HashMap<>(CONFIG); + config.put("argument-based-command-permissions", "true"); + + TestPluginProvider.use(tempDir, config, (app, bootstrap, plugin) -> { + CommandExecutor executor = app.getCommandExecutor(); + + new CommandTester(plugin, executor) + .givenHasPermissions("luckperms.group.permission.set") + .whenRunCommand("group default permission set hello.world true server=test") + .thenExpect("[LP] You do not have permission to use this command!") + + .givenHasPermissions( + "luckperms.group.permission.set", + "luckperms.group.permission.set.modify.default", + "luckperms.group.permission.set.usecontext.global", + "luckperms.group.permission.set.test.permission" + ) + .whenRunCommand("group default permission set test.permission") + .thenExpect("[LP] Set test.permission to true for default in context global.") + + .givenHasPermissions( + "luckperms.group.permission.unset", + "luckperms.group.permission.unset.modify.default", + "luckperms.group.permission.unset.usecontext.global", + "luckperms.group.permission.unset.test.permission" + ) + .whenRunCommand("group default permission unset test.permission") + .thenExpect("[LP] Unset test.permission for default in context global.") + + .givenHasPermissions( + "luckperms.group.permission.set", + "luckperms.group.permission.set.modify.default", + "luckperms.group.permission.set.usecontext.server.test", + "luckperms.group.permission.set.hello.world" + ) + .whenRunCommand("group default permission set hello.world true server=test") + .thenExpect("[LP] Set hello.world to true for default in context server=test.") + + .givenHasPermissions("luckperms.group.permission.info") + .whenRunCommand("group default permission info") + .thenExpect("[LP] You do not have permission to use this command!") + + .givenHasPermissions( + "luckperms.group.permission.info", + "luckperms.group.permission.info.view.default" + ) + .whenRunCommand("group default permission info") + .thenExpect(""" + [LP] default's Permissions: (page 1 of 1 - 1 entries) + > hello.world (server=test) + """ + ); + }); + } + } diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/ImportExportIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/ImportExportIntegrationTest.java index 2600033d5..0da5ee7e3 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/ImportExportIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/ImportExportIntegrationTest.java @@ -51,9 +51,7 @@ import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.*; public class ImportExportIntegrationTest { diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java index 278dacb58..cde973c4d 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java @@ -40,9 +40,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * A set of 'integration tests' for the standalone LuckPerms app. diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java index a2652e306..da8bb281b 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java @@ -28,8 +28,11 @@ package me.lucko.luckperms.standalone; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import me.lucko.luckperms.common.model.Group; +import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.types.Inheritance; +import me.lucko.luckperms.common.node.types.Meta; import me.lucko.luckperms.common.node.types.Permission; +import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.standalone.app.LuckPermsApplication; import me.lucko.luckperms.standalone.app.integration.HealthReporter; import me.lucko.luckperms.standalone.utils.TestPluginBootstrap; @@ -47,22 +50,31 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneOffset; import java.util.Map; -import java.util.concurrent.TimeUnit; +import java.util.UUID; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @Testcontainers -@Tag("docker") public class StorageIntegrationTest { - private static final Node TEST_PERMISSION = Permission.builder() + private static final Node TEST_PERMISSION_1 = Permission.builder() + .permission("example.permission") + .build(); + + private static final Node TEST_PERMISSION_2 = Permission.builder() .permission("test") .value(false) - .expiry(1, TimeUnit.HOURS) + .expiry(LocalDate.of(2050, Month.APRIL, 1).atStartOfDay().toInstant(ZoneOffset.UTC)) .withContext("server", "foo") .withContext("world", "bar") .withContext("test", "test") @@ -71,12 +83,24 @@ public class StorageIntegrationTest { private static final Node TEST_GROUP = Inheritance.builder() .group("default") .value(false) - .expiry(1, TimeUnit.HOURS) + .expiry(LocalDate.of(2050, Month.APRIL, 1).atStartOfDay().toInstant(ZoneOffset.UTC)) .withContext("server", "foo") .withContext("world", "bar") .withContext("test", "test") .build(); + private static final Node TEST_PREFIX = Prefix.builder() + .priority(100) + .prefix("TEST") + .withContext("server", "foo") + .withContext("world", "bar") + .build(); + + private static final Node TEST_META = Meta.builder() + .key("foo") + .value("bar") + .build(); + private static void testStorage(LuckPermsApplication app, TestPluginBootstrap bootstrap, TestPlugin plugin) { // check the plugin is healthy @@ -86,19 +110,37 @@ public class StorageIntegrationTest { // try to create / save a group Group group = plugin.getStorage().createAndLoadGroup("test", CreationCause.INTERNAL).join(); - group.setNode(DataType.NORMAL, TEST_PERMISSION, true); + group.setNode(DataType.NORMAL, TEST_PERMISSION_1, true); + group.setNode(DataType.NORMAL, TEST_PERMISSION_2, true); group.setNode(DataType.NORMAL, TEST_GROUP, true); + group.setNode(DataType.NORMAL, TEST_PREFIX, true); + group.setNode(DataType.NORMAL, TEST_META, true); plugin.getStorage().saveGroup(group).join(); + // try to create / save a user + UUID exampleUniqueId = UUID.fromString("c1d60c50-70b5-4722-8057-87767557e50d"); + plugin.getStorage().savePlayerData(exampleUniqueId, "Luck").join(); + User user = plugin.getStorage().loadUser(exampleUniqueId, "Luck").join(); + user.setNode(DataType.NORMAL, TEST_PERMISSION_1, true); + user.setNode(DataType.NORMAL, TEST_PERMISSION_2, true); + user.setNode(DataType.NORMAL, TEST_GROUP, true); + user.setNode(DataType.NORMAL, TEST_PREFIX, true); + user.setNode(DataType.NORMAL, TEST_META, true); + plugin.getStorage().saveUser(user).join(); + plugin.getStorage().loadAllGroups().join(); Group testGroup = plugin.getGroupManager().getIfLoaded("test"); assertNotNull(testGroup); + assertEquals(ImmutableSet.of(TEST_PERMISSION_1, TEST_PERMISSION_2, TEST_GROUP, TEST_PREFIX, TEST_META), testGroup.normalData().asSet()); - assertEquals(ImmutableSet.of(TEST_PERMISSION, TEST_GROUP), testGroup.normalData().asSet()); + User testUser = plugin.getStorage().loadUser(exampleUniqueId, null).join(); + assertNotNull(testUser); + assertEquals(ImmutableSet.of(Inheritance.builder("default").build(), TEST_PERMISSION_1, TEST_PERMISSION_2, TEST_GROUP, TEST_PREFIX, TEST_META), testUser.normalData().asSet()); } @Nested + @Tag("docker") class MySql { @Container @@ -127,6 +169,7 @@ public class StorageIntegrationTest { } @Nested + @Tag("docker") class MariaDb { @Container @@ -157,6 +200,7 @@ public class StorageIntegrationTest { } @Nested + @Tag("docker") class Postgres { @Container @@ -184,6 +228,7 @@ public class StorageIntegrationTest { } @Nested + @Tag("docker") class MongoDb { @Container @@ -213,43 +258,98 @@ public class StorageIntegrationTest { class FlatFile { @Test - public void testYaml(@TempDir Path tempDir) { + public void testYaml(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "yaml"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("yaml-storage"); + compareFiles(storageDir, "example/yaml", "groups/default.yml"); + compareFiles(storageDir, "example/yaml", "groups/test.yml"); + compareFiles(storageDir, "example/yaml", "users/c1d60c50-70b5-4722-8057-87767557e50d.yml"); } @Test - public void testJson(@TempDir Path tempDir) { + public void testJson(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "json"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("json-storage"); + compareFiles(storageDir, "example/json", "groups/default.json"); + compareFiles(storageDir, "example/json", "groups/test.json"); + compareFiles(storageDir, "example/json", "users/c1d60c50-70b5-4722-8057-87767557e50d.json"); } @Test - public void testHocon(@TempDir Path tempDir) { + public void testHocon(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "hocon"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("hocon-storage"); + compareFiles(storageDir, "example/hocon", "groups/default.conf"); + compareFiles(storageDir, "example/hocon", "groups/test.conf"); + compareFiles(storageDir, "example/hocon", "users/c1d60c50-70b5-4722-8057-87767557e50d.conf"); } @Test - public void testToml(@TempDir Path tempDir) { + public void testToml(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "toml"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("toml-storage"); + compareFiles(storageDir, "example/toml", "groups/default.toml"); + compareFiles(storageDir, "example/toml", "groups/test.toml"); + compareFiles(storageDir, "example/toml", "users/c1d60c50-70b5-4722-8057-87767557e50d.toml"); } @Test - public void testYamlCombined(@TempDir Path tempDir) { + public void testYamlCombined(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "yaml-combined"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("yaml-storage"); + compareFiles(storageDir, "example/yaml-combined", "groups.yml"); + compareFiles(storageDir, "example/yaml-combined", "tracks.yml"); + compareFiles(storageDir, "example/yaml-combined", "users.yml"); } @Test - public void testJsonCombined(@TempDir Path tempDir) { + public void testJsonCombined(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "json-combined"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("json-storage"); + compareFiles(storageDir, "example/json-combined", "groups.json"); + compareFiles(storageDir, "example/json-combined", "tracks.json"); + compareFiles(storageDir, "example/json-combined", "users.json"); } @Test - public void testHoconCombined(@TempDir Path tempDir) { + public void testHoconCombined(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "hocon-combined"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("hocon-storage"); + compareFiles(storageDir, "example/hocon-combined", "groups.conf"); + compareFiles(storageDir, "example/hocon-combined", "tracks.conf"); + compareFiles(storageDir, "example/hocon-combined", "users.conf"); } @Test - public void testTomlCombined(@TempDir Path tempDir) { + public void testTomlCombined(@TempDir Path tempDir) throws IOException { TestPluginProvider.use(tempDir, ImmutableMap.of("storage-method", "toml-combined"), StorageIntegrationTest::testStorage); + + Path storageDir = tempDir.resolve("toml-storage"); + compareFiles(storageDir, "example/toml-combined", "groups.toml"); + compareFiles(storageDir, "example/toml-combined", "tracks.toml"); + compareFiles(storageDir, "example/toml-combined", "users.toml"); + } + + private static void compareFiles(Path dir, String examplePath, String file) throws IOException { + String exampleFile = examplePath + "/" + file; + + String expected; + try (InputStream in = StorageIntegrationTest.class.getClassLoader().getResourceAsStream(exampleFile)) { + if (in == null) { + throw new IOException("File does not exist: " + exampleFile); + } + expected = new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + + String actual = Files.readString(dir.resolve(Paths.get(file))); + assertEquals(expected.trim(), actual.trim()); } } diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/utils/CommandTester.java b/standalone/src/test/java/me/lucko/luckperms/standalone/utils/CommandTester.java index b3a83e23e..d3ebf27be 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/utils/CommandTester.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/utils/CommandTester.java @@ -27,15 +27,17 @@ package me.lucko.luckperms.standalone.utils; import me.lucko.luckperms.standalone.app.integration.CommandExecutor; import me.lucko.luckperms.standalone.app.integration.SingletonPlayer; +import me.lucko.luckperms.standalone.utils.TestPluginBootstrap.TestPlugin; +import me.lucko.luckperms.standalone.utils.TestPluginBootstrap.TestSenderFactory; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.luckperms.api.util.Tristate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -43,17 +45,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals; /** * Utility for testing LuckPerms commands with BDD-like given/when/then assertions. */ -public final class CommandTester implements Consumer { +public final class CommandTester implements Consumer, Function { private static final Logger LOGGER = LogManager.getLogger(CommandTester.class); + /** The test plugin */ + private final TestPlugin plugin; + /** The LuckPerms command executor */ private final CommandExecutor executor; + /** The current map of permissions held by the fake executor */ + private Map permissions = null; + + /** A set of the permissions that have been checked for */ + private final Set checkedPermissions = Collections.synchronizedSet(new HashSet<>()); + /** A buffer of messages received by the test tool */ private final List messageBuffer = Collections.synchronizedList(new ArrayList<>()); - public CommandTester(CommandExecutor executor) { + public CommandTester(TestPlugin plugin, CommandExecutor executor) { + this.plugin = plugin; this.executor = executor; } @@ -67,19 +79,66 @@ public final class CommandTester implements Consumer { this.messageBuffer.add(component); } + /** + * Perform a permission check for the fake executor + * + * @param permission the permission + * @return the result of the permission check + */ + @Override + public Tristate apply(String permission) { + if (this.permissions == null) { + this.checkedPermissions.add(permission); + return Tristate.TRUE; + } else { + Tristate result = this.permissions.getOrDefault(permission, Tristate.UNDEFINED); + if (result != Tristate.UNDEFINED) { + this.checkedPermissions.add(permission); + } + return result; + } + } + + /** + * Marks that the fake executor should have all permissions + * + * @return this + */ + public CommandTester givenHasAllPermissions() { + this.permissions = null; + return this; + } + + /** + * Marks that the fake executor should have the given permissions + * + * @return this + */ + public CommandTester givenHasPermissions(String... permissions) { + this.permissions = new HashMap<>(); + for (String permission : permissions) { + this.permissions.put(permission, Tristate.TRUE); + } + return this; + } + /** * Execute a command using the {@link CommandExecutor} and capture output to this test instance. * * @param command the command to run * @return this */ - public CommandTester givenCommand(String command) { + public CommandTester whenRunCommand(String command) { LOGGER.info("Executing test command: " + command); + TestSenderFactory senderFactory = this.plugin.getSenderFactory(); + senderFactory.setPermissionChecker(this); SingletonPlayer.INSTANCE.addMessageSink(this); - this.executor.execute(command).join(); - SingletonPlayer.INSTANCE.removeMessageSink(this); + this.executor.execute(command).join(); + + SingletonPlayer.INSTANCE.removeMessageSink(this); + senderFactory.resetPermissionChecker(); return this; } @@ -96,6 +155,10 @@ public final class CommandTester implements Consumer { assertEquals(expected.trim(), actual.trim()); + if (this.permissions != null) { + assertEquals(this.checkedPermissions, this.permissions.keySet()); + } + return this.clearMessageBuffer(); } @@ -106,6 +169,7 @@ public final class CommandTester implements Consumer { */ public CommandTester clearMessageBuffer() { this.messageBuffer.clear(); + this.checkedPermissions.clear(); return this; } @@ -127,14 +191,20 @@ public final class CommandTester implements Consumer { * @return this */ public CommandTester outputTest(String cmd) { - System.out.printf(".executeCommand(\"%s\")%n", cmd); - this.givenCommand(cmd); + this.whenRunCommand(cmd); + + String checkedPermissions = this.checkedPermissions.stream() + .map(s -> "\"" + s + "\"") + .collect(Collectors.joining(", ")); + + System.out.printf(".givenHasPermissions(%s)%n", checkedPermissions); + System.out.printf(".whenRunCommand(\"%s\")%n", cmd); List render = this.renderBuffer(); if (render.size() == 1) { - System.out.printf(".expect(\"%s\")%n", render.get(0)); + System.out.printf(".thenExpect(\"%s\")%n", render.get(0)); } else { - System.out.println(".expect(\"\"\""); + System.out.println(".thenExpect(\"\"\""); for (String s : render) { System.out.println(" " + s); } diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/utils/TestPluginBootstrap.java b/standalone/src/test/java/me/lucko/luckperms/standalone/utils/TestPluginBootstrap.java index a6b72939e..6686d92a0 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/utils/TestPluginBootstrap.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/utils/TestPluginBootstrap.java @@ -27,14 +27,21 @@ package me.lucko.luckperms.standalone.utils; import me.lucko.luckperms.common.dependencies.Dependency; import me.lucko.luckperms.common.dependencies.DependencyManager; +import me.lucko.luckperms.common.locale.TranslationManager; import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.storage.StorageType; import me.lucko.luckperms.standalone.LPStandaloneBootstrap; import me.lucko.luckperms.standalone.LPStandalonePlugin; +import me.lucko.luckperms.standalone.StandaloneSenderFactory; import me.lucko.luckperms.standalone.app.LuckPermsApplication; +import me.lucko.luckperms.standalone.app.integration.SingletonPlayer; +import net.kyori.adventure.text.Component; +import net.luckperms.api.util.Tristate; import java.nio.file.Path; +import java.util.Locale; import java.util.Set; +import java.util.function.Function; /** * An extension standalone bootstrap for testing. @@ -43,7 +50,7 @@ import java.util.Set; *

*

*

*/ @@ -74,6 +81,8 @@ public final class TestPluginBootstrap extends LPStandaloneBootstrap { } public static final class TestPlugin extends LPStandalonePlugin { + private TestSenderFactory senderFactory; + TestPlugin(LPStandaloneBootstrap bootstrap) { super(bootstrap); } @@ -82,6 +91,16 @@ public final class TestPluginBootstrap extends LPStandaloneBootstrap { protected DependencyManager createDependencyManager() { return new TestDependencyManager(); } + + @Override + protected void setupSenderFactory() { + this.senderFactory = new TestSenderFactory(this); + } + + @Override + public TestSenderFactory getSenderFactory() { + return this.senderFactory; + } } static final class TestDependencyManager implements DependencyManager { @@ -106,4 +125,46 @@ public final class TestPluginBootstrap extends LPStandaloneBootstrap { } } + + static final class TestSenderFactory extends StandaloneSenderFactory { + + private Function permissionChecker; + + public TestSenderFactory(LPStandalonePlugin plugin) { + super(plugin); + } + + public void setPermissionChecker(Function permissionChecker) { + this.permissionChecker = permissionChecker; + } + + public void resetPermissionChecker() { + this.permissionChecker = null; + } + + @Override + protected boolean consoleHasAllPermissions() { + return false; + } + + @Override + protected void sendMessage(SingletonPlayer sender, Component message) { + Component rendered = TranslationManager.render(message, Locale.ENGLISH); + sender.sendMessage(rendered); + } + + @Override + protected Tristate getPermissionValue(SingletonPlayer sender, String node) { + return this.permissionChecker == null + ? super.getPermissionValue(sender, node) + : this.permissionChecker.apply(node); + } + + @Override + protected boolean hasPermission(SingletonPlayer sender, String node) { + return this.permissionChecker == null + ? super.hasPermission(sender, node) + : this.permissionChecker.apply(node).asBoolean(); + } + } } diff --git a/standalone/src/test/resources/example/hocon-combined/groups.conf b/standalone/src/test/resources/example/hocon-combined/groups.conf new file mode 100644 index 000000000..6cd167bde --- /dev/null +++ b/standalone/src/test/resources/example/hocon-combined/groups.conf @@ -0,0 +1,47 @@ +default { + permissions=[] +} +test { + meta=[ + { + key=foo + value=bar + } + ] + permissions=[ + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission="group.default" + value=false + }, + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission=test + value=false + }, + { + permission="example.permission" + value=true + } + ] + prefixes=[ + { + context { + server=foo + world=bar + } + prefix=TEST + priority=100 + } + ] +} diff --git a/standalone/src/test/resources/example/hocon-combined/tracks.conf b/standalone/src/test/resources/example/hocon-combined/tracks.conf new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/standalone/src/test/resources/example/hocon-combined/tracks.conf @@ -0,0 +1 @@ + diff --git a/standalone/src/test/resources/example/hocon-combined/users.conf b/standalone/src/test/resources/example/hocon-combined/users.conf new file mode 100644 index 000000000..9b23671e9 --- /dev/null +++ b/standalone/src/test/resources/example/hocon-combined/users.conf @@ -0,0 +1,51 @@ +c1d60c50-70b5-4722-8057-87767557e50d { + meta=[ + { + key=foo + value=bar + } + ] + name=Luck + parents=[ + { + group=default + } + ] + permissions=[ + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission="group.default" + value=false + }, + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission=test + value=false + }, + { + permission="example.permission" + value=true + } + ] + prefixes=[ + { + context { + server=foo + world=bar + } + prefix=TEST + priority=100 + } + ] + primary-group=default +} diff --git a/standalone/src/test/resources/example/hocon/groups/default.conf b/standalone/src/test/resources/example/hocon/groups/default.conf new file mode 100644 index 000000000..54a5379f8 --- /dev/null +++ b/standalone/src/test/resources/example/hocon/groups/default.conf @@ -0,0 +1 @@ +name=default diff --git a/standalone/src/test/resources/example/hocon/groups/test.conf b/standalone/src/test/resources/example/hocon/groups/test.conf new file mode 100644 index 000000000..ed27b9332 --- /dev/null +++ b/standalone/src/test/resources/example/hocon/groups/test.conf @@ -0,0 +1,43 @@ +meta=[ + { + key=foo + value=bar + } +] +name=test +permissions=[ + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission="group.default" + value=false + }, + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission=test + value=false + }, + { + permission="example.permission" + value=true + } +] +prefixes=[ + { + context { + server=foo + world=bar + } + prefix=TEST + priority=100 + } +] diff --git a/standalone/src/test/resources/example/hocon/users/c1d60c50-70b5-4722-8057-87767557e50d.conf b/standalone/src/test/resources/example/hocon/users/c1d60c50-70b5-4722-8057-87767557e50d.conf new file mode 100644 index 000000000..3801deb53 --- /dev/null +++ b/standalone/src/test/resources/example/hocon/users/c1d60c50-70b5-4722-8057-87767557e50d.conf @@ -0,0 +1,50 @@ +meta=[ + { + key=foo + value=bar + } +] +name=Luck +parents=[ + { + group=default + } +] +permissions=[ + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission="group.default" + value=false + }, + { + context { + server=foo + test=test + world=bar + } + expiry=2532384000 + permission=test + value=false + }, + { + permission="example.permission" + value=true + } +] +prefixes=[ + { + context { + server=foo + world=bar + } + prefix=TEST + priority=100 + } +] +primary-group=default +uuid=c1d60c50-70b5-4722-8057-87767557e50d diff --git a/standalone/src/test/resources/example/json-combined/groups.json b/standalone/src/test/resources/example/json-combined/groups.json new file mode 100644 index 000000000..8d463416a --- /dev/null +++ b/standalone/src/test/resources/example/json-combined/groups.json @@ -0,0 +1,46 @@ +{ + "test": { + "permissions": [ + { + "permission": "group.default", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "test", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "example.permission", + "value": true + } + ], + "prefixes": [ + { + "prefix": "TEST", + "priority": 100, + "context": { + "server": "foo", + "world": "bar" + } + } + ], + "meta": [ + { + "key": "foo", + "value": "bar" + } + ] + } +} diff --git a/standalone/src/test/resources/example/json-combined/tracks.json b/standalone/src/test/resources/example/json-combined/tracks.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/standalone/src/test/resources/example/json-combined/tracks.json @@ -0,0 +1 @@ +{} diff --git a/standalone/src/test/resources/example/json-combined/users.json b/standalone/src/test/resources/example/json-combined/users.json new file mode 100644 index 000000000..e35011724 --- /dev/null +++ b/standalone/src/test/resources/example/json-combined/users.json @@ -0,0 +1,53 @@ +{ + "c1d60c50-70b5-4722-8057-87767557e50d": { + "name": "Luck", + "primaryGroup": "default", + "permissions": [ + { + "permission": "group.default", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "test", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "example.permission", + "value": true + } + ], + "parents": [ + { + "group": "default" + } + ], + "prefixes": [ + { + "prefix": "TEST", + "priority": 100, + "context": { + "server": "foo", + "world": "bar" + } + } + ], + "meta": [ + { + "key": "foo", + "value": "bar" + } + ] + } +} diff --git a/standalone/src/test/resources/example/json/groups/default.json b/standalone/src/test/resources/example/json/groups/default.json new file mode 100644 index 000000000..b61c30f95 --- /dev/null +++ b/standalone/src/test/resources/example/json/groups/default.json @@ -0,0 +1,3 @@ +{ + "name": "default" +} diff --git a/standalone/src/test/resources/example/json/groups/test.json b/standalone/src/test/resources/example/json/groups/test.json new file mode 100644 index 000000000..8e96f3d5d --- /dev/null +++ b/standalone/src/test/resources/example/json/groups/test.json @@ -0,0 +1,45 @@ +{ + "name": "test", + "permissions": [ + { + "permission": "group.default", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "test", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "example.permission", + "value": true + } + ], + "prefixes": [ + { + "prefix": "TEST", + "priority": 100, + "context": { + "server": "foo", + "world": "bar" + } + } + ], + "meta": [ + { + "key": "foo", + "value": "bar" + } + ] +} diff --git a/standalone/src/test/resources/example/json/users/c1d60c50-70b5-4722-8057-87767557e50d.json b/standalone/src/test/resources/example/json/users/c1d60c50-70b5-4722-8057-87767557e50d.json new file mode 100644 index 000000000..8a5aa6e02 --- /dev/null +++ b/standalone/src/test/resources/example/json/users/c1d60c50-70b5-4722-8057-87767557e50d.json @@ -0,0 +1,52 @@ +{ + "uuid": "c1d60c50-70b5-4722-8057-87767557e50d", + "name": "Luck", + "primaryGroup": "default", + "permissions": [ + { + "permission": "group.default", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "test", + "value": false, + "expiry": 2532384000, + "context": { + "server": "foo", + "test": "test", + "world": "bar" + } + }, + { + "permission": "example.permission", + "value": true + } + ], + "parents": [ + { + "group": "default" + } + ], + "prefixes": [ + { + "prefix": "TEST", + "priority": 100, + "context": { + "server": "foo", + "world": "bar" + } + } + ], + "meta": [ + { + "key": "foo", + "value": "bar" + } + ] +} diff --git a/standalone/src/test/resources/example/toml-combined/groups.toml b/standalone/src/test/resources/example/toml-combined/groups.toml new file mode 100644 index 000000000..5fdf4f04d --- /dev/null +++ b/standalone/src/test/resources/example/toml-combined/groups.toml @@ -0,0 +1,33 @@ + [[test.prefixes]] + prefix = "TEST" + priority = 100 + + [test.prefixes.context] + server = "foo" + world = "bar" + [[test.permissions]] + permission = "group.default" + expiry = 2532384000 + value = false + + [test.permissions.context] + server = "foo" + world = "bar" + test = "test" + + [[test.permissions]] + permission = "test" + expiry = 2532384000 + value = false + + [test.permissions.context] + server = "foo" + world = "bar" + test = "test" + + [[test.permissions]] + permission = "example.permission" + value = true + [[test.meta]] + value = "bar" + key = "foo" diff --git a/standalone/src/test/resources/example/toml-combined/tracks.toml b/standalone/src/test/resources/example/toml-combined/tracks.toml new file mode 100644 index 000000000..e69de29bb diff --git a/standalone/src/test/resources/example/toml-combined/users.toml b/standalone/src/test/resources/example/toml-combined/users.toml new file mode 100644 index 000000000..28453a132 --- /dev/null +++ b/standalone/src/test/resources/example/toml-combined/users.toml @@ -0,0 +1,42 @@ +[c1d60c50-70b5-4722-8057-87767557e50d] + name = "Luck" + primary-group = "default" + + [[c1d60c50-70b5-4722-8057-87767557e50d.permissions]] + permission = "group.default" + value = false + expiry = 2532384000 + + [c1d60c50-70b5-4722-8057-87767557e50d.permissions.context] + server = "foo" + test = "test" + world = "bar" + + [[c1d60c50-70b5-4722-8057-87767557e50d.permissions]] + permission = "test" + value = false + expiry = 2532384000 + + [c1d60c50-70b5-4722-8057-87767557e50d.permissions.context] + server = "foo" + test = "test" + world = "bar" + + [[c1d60c50-70b5-4722-8057-87767557e50d.permissions]] + permission = "example.permission" + value = true + + [[c1d60c50-70b5-4722-8057-87767557e50d.parents]] + group = "default" + + [[c1d60c50-70b5-4722-8057-87767557e50d.prefixes]] + prefix = "TEST" + priority = 100 + + [c1d60c50-70b5-4722-8057-87767557e50d.prefixes.context] + server = "foo" + world = "bar" + + [[c1d60c50-70b5-4722-8057-87767557e50d.meta]] + key = "foo" + value = "bar" diff --git a/standalone/src/test/resources/example/toml/groups/default.toml b/standalone/src/test/resources/example/toml/groups/default.toml new file mode 100644 index 000000000..0df4b23ea --- /dev/null +++ b/standalone/src/test/resources/example/toml/groups/default.toml @@ -0,0 +1 @@ +name = "default" diff --git a/standalone/src/test/resources/example/toml/groups/test.toml b/standalone/src/test/resources/example/toml/groups/test.toml new file mode 100644 index 000000000..206e86ee0 --- /dev/null +++ b/standalone/src/test/resources/example/toml/groups/test.toml @@ -0,0 +1,37 @@ +name = "test" + +[[permissions]] + permission = "group.default" + value = false + expiry = 2532384000 + + [permissions.context] + server = "foo" + test = "test" + world = "bar" + +[[permissions]] + permission = "test" + value = false + expiry = 2532384000 + + [permissions.context] + server = "foo" + test = "test" + world = "bar" + +[[permissions]] + permission = "example.permission" + value = true + +[[prefixes]] + prefix = "TEST" + priority = 100 + + [prefixes.context] + server = "foo" + world = "bar" + +[[meta]] + key = "foo" + value = "bar" diff --git a/standalone/src/test/resources/example/toml/users/c1d60c50-70b5-4722-8057-87767557e50d.toml b/standalone/src/test/resources/example/toml/users/c1d60c50-70b5-4722-8057-87767557e50d.toml new file mode 100644 index 000000000..12371883e --- /dev/null +++ b/standalone/src/test/resources/example/toml/users/c1d60c50-70b5-4722-8057-87767557e50d.toml @@ -0,0 +1,42 @@ +uuid = "c1d60c50-70b5-4722-8057-87767557e50d" +name = "Luck" +primary-group = "default" + +[[permissions]] + permission = "group.default" + value = false + expiry = 2532384000 + + [permissions.context] + server = "foo" + test = "test" + world = "bar" + +[[permissions]] + permission = "test" + value = false + expiry = 2532384000 + + [permissions.context] + server = "foo" + test = "test" + world = "bar" + +[[permissions]] + permission = "example.permission" + value = true + +[[parents]] + group = "default" + +[[prefixes]] + prefix = "TEST" + priority = 100 + + [prefixes.context] + server = "foo" + world = "bar" + +[[meta]] + key = "foo" + value = "bar" diff --git a/standalone/src/test/resources/example/yaml-combined/groups.yml b/standalone/src/test/resources/example/yaml-combined/groups.yml new file mode 100644 index 000000000..97c2610ea --- /dev/null +++ b/standalone/src/test/resources/example/yaml-combined/groups.yml @@ -0,0 +1,28 @@ +default: + permissions: [] +test: + permissions: + - group.default: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar + - test: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar + - example.permission + prefixes: + - TEST: + priority: 100 + context: + server: foo + world: bar + meta: + - foo: + value: bar diff --git a/standalone/src/test/resources/example/yaml-combined/tracks.yml b/standalone/src/test/resources/example/yaml-combined/tracks.yml new file mode 100644 index 000000000..19765bd50 --- /dev/null +++ b/standalone/src/test/resources/example/yaml-combined/tracks.yml @@ -0,0 +1 @@ +null diff --git a/standalone/src/test/resources/example/yaml-combined/users.yml b/standalone/src/test/resources/example/yaml-combined/users.yml new file mode 100644 index 000000000..2421d4de1 --- /dev/null +++ b/standalone/src/test/resources/example/yaml-combined/users.yml @@ -0,0 +1,30 @@ +c1d60c50-70b5-4722-8057-87767557e50d: + name: Luck + primary-group: default + permissions: + - group.default: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar + - test: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar + - example.permission + parents: + - default + prefixes: + - TEST: + priority: 100 + context: + server: foo + world: bar + meta: + - foo: + value: bar diff --git a/standalone/src/test/resources/example/yaml/groups/default.yml b/standalone/src/test/resources/example/yaml/groups/default.yml new file mode 100644 index 000000000..970ba0c56 --- /dev/null +++ b/standalone/src/test/resources/example/yaml/groups/default.yml @@ -0,0 +1 @@ +name: default diff --git a/standalone/src/test/resources/example/yaml/groups/test.yml b/standalone/src/test/resources/example/yaml/groups/test.yml new file mode 100644 index 000000000..7ec1139c2 --- /dev/null +++ b/standalone/src/test/resources/example/yaml/groups/test.yml @@ -0,0 +1,26 @@ +name: test +permissions: +- group.default: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar +- test: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar +- example.permission +prefixes: +- TEST: + priority: 100 + context: + server: foo + world: bar +meta: +- foo: + value: bar diff --git a/standalone/src/test/resources/example/yaml/users/c1d60c50-70b5-4722-8057-87767557e50d.yml b/standalone/src/test/resources/example/yaml/users/c1d60c50-70b5-4722-8057-87767557e50d.yml new file mode 100644 index 000000000..b00f6cae2 --- /dev/null +++ b/standalone/src/test/resources/example/yaml/users/c1d60c50-70b5-4722-8057-87767557e50d.yml @@ -0,0 +1,30 @@ +uuid: c1d60c50-70b5-4722-8057-87767557e50d +name: Luck +primary-group: default +permissions: +- group.default: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar +- test: + value: false + expiry: 2532384000 + context: + server: foo + test: test + world: bar +- example.permission +parents: +- default +prefixes: +- TEST: + priority: 100 + context: + server: foo + world: bar +meta: +- foo: + value: bar