Add more tests

This commit is contained in:
Luck 2023-05-02 00:07:48 +01:00
parent bd08507150
commit 84bd2ee52a
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
32 changed files with 1521 additions and 230 deletions

View File

@ -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<T> 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

View File

@ -63,6 +63,10 @@ public abstract class SenderFactory<P extends LuckPermsPlugin, T> 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);

View File

@ -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 {

View File

@ -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.

View File

@ -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());
}
}

View File

@ -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<Component> {
public final class CommandTester implements Consumer<Component>, Function<String, Tristate> {
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<String, Tristate> permissions = null;
/** A set of the permissions that have been checked for */
private final Set<String> checkedPermissions = Collections.synchronizedSet(new HashSet<>());
/** A buffer of messages received by the test tool */
private final List<Component> 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<Component> {
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<Component> {
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<Component> {
*/
public CommandTester clearMessageBuffer() {
this.messageBuffer.clear();
this.checkedPermissions.clear();
return this;
}
@ -127,14 +191,20 @@ public final class CommandTester implements Consumer<Component> {
* @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<String> 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);
}

View File

@ -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;
* <p>
* <ul>
* <li>Dependency loading system is replaced with a no-op stub that delegates to the test classloader</li>
* <li>Translations aren't downloaded automatically</li>
* <li>Sender factory is extended and allows for permission checks to be intercepted</li>
* </ul>
* </p>
*/
@ -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<String, Tristate> permissionChecker;
public TestSenderFactory(LPStandalonePlugin plugin) {
super(plugin);
}
public void setPermissionChecker(Function<String, Tristate> 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();
}
}
}

View File

@ -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
}
]
}

View File

@ -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
}

View File

@ -0,0 +1 @@
name=default

View File

@ -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
}
]

View File

@ -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

View File

@ -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"
}
]
}
}

View File

@ -0,0 +1 @@
{}

View File

@ -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"
}
]
}
}

View File

@ -0,0 +1,3 @@
{
"name": "default"
}

View File

@ -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"
}
]
}

View File

@ -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"
}
]
}

View File

@ -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"

View File

@ -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"

View File

@ -0,0 +1 @@
name = "default"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -0,0 +1 @@
null

View File

@ -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

View File

@ -0,0 +1 @@
name: default

View File

@ -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

View File

@ -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