mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2025-01-29 19:51:40 +01:00
Add more unit tests (#3555)
This commit is contained in:
parent
4d726f4e8b
commit
3ecdeacaf8
@ -9,8 +9,13 @@ test {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1'
|
||||
testImplementation 'org.mockito:mockito-core:4.11.0'
|
||||
testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0'
|
||||
|
||||
testImplementation 'com.h2database:h2:2.1.214'
|
||||
|
||||
api project(':api')
|
||||
api 'org.checkerframework:checker-qual:3.12.0'
|
||||
|
@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A simple pagination utility
|
||||
@ -93,6 +94,19 @@ public class Paginated<T> {
|
||||
public String toString() {
|
||||
return this.position + ": " + this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Entry)) return false;
|
||||
Entry<?> entry = (Entry<?>) o;
|
||||
return this.position == entry.position && Objects.equals(this.value, entry.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.position, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.calculator;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
|
||||
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
|
||||
import me.lucko.luckperms.common.calculator.processor.AbstractOverrideWildcardProcessor;
|
||||
import me.lucko.luckperms.common.calculator.processor.DirectProcessor;
|
||||
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.calculator.processor.RegexProcessor;
|
||||
import me.lucko.luckperms.common.calculator.processor.SpongeWildcardProcessor;
|
||||
import me.lucko.luckperms.common.calculator.processor.WildcardProcessor;
|
||||
import me.lucko.luckperms.common.model.HolderType;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsImpl;
|
||||
import me.lucko.luckperms.common.treeview.PermissionRegistry;
|
||||
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
|
||||
import me.lucko.luckperms.common.verbose.VerboseHandler;
|
||||
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.util.Tristate;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.assertSame;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class PermissionCalculatorTest {
|
||||
|
||||
private static final CacheMetadata MOCK_METADATA = new CacheMetadata(
|
||||
HolderType.GROUP,
|
||||
VerboseCheckTarget.of(VerboseCheckTarget.GROUP_TYPE, "test"),
|
||||
QueryOptionsImpl.DEFAULT_CONTEXTUAL
|
||||
);
|
||||
|
||||
private static final Map<String, Node> EXAMPLE_PERMISSIONS = ImmutableMap.<String, Boolean>builder()
|
||||
// direct
|
||||
.put("test.node1", true)
|
||||
.put("test.node2", false)
|
||||
|
||||
// wildcard
|
||||
.put("one.two.three.four", true)
|
||||
.put("one.two.three.*", false)
|
||||
.put("one.two.three", true)
|
||||
.put("one.two.*", false)
|
||||
.put("one.two", true)
|
||||
.put("one.*", false)
|
||||
.put("one", true)
|
||||
.put("*", false)
|
||||
|
||||
// regex
|
||||
.put("r=hello\\d+", true)
|
||||
.put("R=rege(x(es)?|xps?)[1-5]", false)
|
||||
|
||||
// override
|
||||
.put("overridetest.*", true)
|
||||
|
||||
.build().entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> NodeBuilders.determineMostApplicable(e.getKey()).value(e.getValue()).build()
|
||||
));
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
lenient().when(this.plugin.getVerboseHandler()).thenReturn(mock(VerboseHandler.class));
|
||||
lenient().when(this.plugin.getPermissionRegistry()).thenReturn(mock(PermissionRegistry.class));
|
||||
}
|
||||
|
||||
private PermissionCalculator createCalculator(PermissionProcessor... processors) {
|
||||
return new PermissionCalculator(this.plugin, MOCK_METADATA, ImmutableList.copyOf(processors));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"test, UNDEFINED",
|
||||
"test.node1, TRUE",
|
||||
"test.node2, FALSE"
|
||||
})
|
||||
public void testDirect(String node, Tristate expected) {
|
||||
PermissionCalculator calculator = createCalculator(new DirectProcessor());
|
||||
calculator.setSourcePermissions(EXAMPLE_PERMISSIONS);
|
||||
|
||||
TristateResult result = calculator.checkPermission(node, CheckOrigin.INTERNAL);
|
||||
assertEquals(expected, result.result());
|
||||
assertNull(result.overriddenResult());
|
||||
|
||||
if (expected != Tristate.UNDEFINED) {
|
||||
assertNotNull(result.node());
|
||||
assertSame(DirectProcessor.class, result.processorClass());
|
||||
} else {
|
||||
assertNull(result.node());
|
||||
assertNull(result.processorClass());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"one.two.three.four, true, direct",
|
||||
"one.two.three.test, false, wildcard",
|
||||
"one.two.three.*, false, direct",
|
||||
"one.two.three, true, direct",
|
||||
"one.two.test, false, wildcard",
|
||||
"one.two.*, false, direct",
|
||||
"one.two, true, direct",
|
||||
"one.test, false, wildcard",
|
||||
"one.*, false, direct",
|
||||
"one, true, direct",
|
||||
"test, false, wildcard",
|
||||
"*, false, direct",
|
||||
})
|
||||
public void testWildcard(String node, boolean expected, String type) {
|
||||
PermissionCalculator calculator = createCalculator(new DirectProcessor(), new WildcardProcessor());
|
||||
calculator.setSourcePermissions(EXAMPLE_PERMISSIONS);
|
||||
|
||||
TristateResult result = calculator.checkPermission(node, CheckOrigin.INTERNAL);
|
||||
assertEquals(Tristate.of(expected), result.result());
|
||||
assertNull(result.overriddenResult());
|
||||
assertNotNull(result.node());
|
||||
|
||||
if (type.equals("direct")) {
|
||||
assertSame(DirectProcessor.class, result.processorClass());
|
||||
} else if (type.equals("wildcard")) {
|
||||
assertSame(WildcardProcessor.class, result.processorClass());
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"one, true, direct",
|
||||
"one.test, true, wildcard",
|
||||
"one.two, true, direct",
|
||||
"one.two.test, true, wildcard",
|
||||
})
|
||||
public void testSpongeWildcard(String node, boolean expected, String type) {
|
||||
PermissionCalculator calculator = createCalculator(new DirectProcessor(), new SpongeWildcardProcessor());
|
||||
calculator.setSourcePermissions(EXAMPLE_PERMISSIONS);
|
||||
|
||||
TristateResult result = calculator.checkPermission(node, CheckOrigin.INTERNAL);
|
||||
assertEquals(Tristate.of(expected), result.result());
|
||||
assertNull(result.overriddenResult());
|
||||
assertNotNull(result.node());
|
||||
|
||||
if (type.equals("direct")) {
|
||||
assertSame(DirectProcessor.class, result.processorClass());
|
||||
} else if (type.equals("wildcard")) {
|
||||
assertSame(SpongeWildcardProcessor.class, result.processorClass());
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"hello, UNDEFINED",
|
||||
"hello1, TRUE",
|
||||
"hello123, TRUE",
|
||||
"helloo, UNDEFINED",
|
||||
"regex1, FALSE",
|
||||
"regexes2, FALSE",
|
||||
"regexp3, FALSE",
|
||||
"regexps4, FALSE",
|
||||
})
|
||||
public void testRegex(String node, Tristate expected) {
|
||||
PermissionCalculator calculator = createCalculator(new DirectProcessor(), new RegexProcessor());
|
||||
calculator.setSourcePermissions(EXAMPLE_PERMISSIONS);
|
||||
|
||||
TristateResult result = calculator.checkPermission(node, CheckOrigin.INTERNAL);
|
||||
assertEquals(expected, result.result());
|
||||
assertNull(result.overriddenResult());
|
||||
|
||||
if (expected != Tristate.UNDEFINED) {
|
||||
assertNotNull(result.node());
|
||||
assertSame(RegexProcessor.class, result.processorClass());
|
||||
} else {
|
||||
assertNull(result.node());
|
||||
assertNull(result.processorClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideWildcard() {
|
||||
AbstractOverrideWildcardProcessor overrideProcessor = new AbstractOverrideWildcardProcessor(true) {
|
||||
@Override
|
||||
protected TristateResult hasPermission(String permission) {
|
||||
if (permission.equals("overridetest.test")) {
|
||||
return new TristateResult.Factory(AbstractOverrideWildcardProcessor.class)
|
||||
.result(Tristate.FALSE);
|
||||
}
|
||||
return TristateResult.UNDEFINED;
|
||||
}
|
||||
};
|
||||
|
||||
PermissionCalculator calculator = createCalculator(new DirectProcessor(), new WildcardProcessor(), overrideProcessor);
|
||||
calculator.setSourcePermissions(EXAMPLE_PERMISSIONS);
|
||||
|
||||
TristateResult result = calculator.checkPermission("overridetest.test", CheckOrigin.INTERNAL);
|
||||
assertEquals(Tristate.FALSE, result.result());
|
||||
assertSame(AbstractOverrideWildcardProcessor.class, result.processorClass());
|
||||
|
||||
TristateResult overriddenResult = result.overriddenResult();
|
||||
assertNotNull(overriddenResult);
|
||||
assertSame(WildcardProcessor.class, overriddenResult.processorClass());
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.common.context;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.luckperms.api.context.Context;
|
||||
@ -33,19 +32,20 @@ import net.luckperms.api.context.ContextSatisfyMode;
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ContextSetTest {
|
||||
public class ImmutableContextSetTest {
|
||||
|
||||
@Test
|
||||
public void testImmutableBuilder() {
|
||||
List<Consumer<ImmutableContextSet.Builder>> tests = ImmutableList.of(
|
||||
private static Stream<Consumer<ImmutableContextSet.Builder>> testBuilder() {
|
||||
return Stream.of(
|
||||
builder -> {
|
||||
builder.add("test", "a");
|
||||
builder.add("test", "b");
|
||||
@ -73,29 +73,31 @@ public class ContextSetTest {
|
||||
builder.add("test", "c");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (Consumer<ImmutableContextSet.Builder> action : tests) {
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
action.accept(builder);
|
||||
ImmutableContextSet set = builder.build();
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testBuilder(Consumer<ImmutableContextSet.Builder> action) {
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
action.accept(builder);
|
||||
ImmutableContextSet set = builder.build();
|
||||
|
||||
ImmutableSet<Context> expected = ImmutableSet.of(
|
||||
new ContextImpl("test", "a"),
|
||||
new ContextImpl("test", "b"),
|
||||
new ContextImpl("test", "c")
|
||||
);
|
||||
ImmutableSet<Context> expected = ImmutableSet.of(
|
||||
new ContextImpl("test", "a"),
|
||||
new ContextImpl("test", "b"),
|
||||
new ContextImpl("test", "c")
|
||||
);
|
||||
|
||||
assertEquals(expected, set.toSet());
|
||||
assertEquals(3, set.size());
|
||||
assertEquals(expected, set.toSet());
|
||||
assertEquals(3, set.size());
|
||||
|
||||
assertTrue(set.contains("test", "a"));
|
||||
assertTrue(set.contains("test", "b"));
|
||||
assertTrue(set.contains("test", "c"));
|
||||
}
|
||||
assertTrue(set.contains("test", "a"));
|
||||
assertTrue(set.contains("test", "b"));
|
||||
assertTrue(set.contains("test", "c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmutableContains() {
|
||||
public void testContains() {
|
||||
ImmutableContextSet set = new ImmutableContextSetImpl.BuilderImpl()
|
||||
.add("test", "a")
|
||||
.add("test", "a")
|
||||
@ -111,8 +113,18 @@ public class ContextSetTest {
|
||||
assertFalse(set.containsKey("aaa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmutableContainsAll() {
|
||||
private static Stream<Consumer<ImmutableContextSet.Builder>> testContainsAllTrue() {
|
||||
return Stream.of(
|
||||
builder -> builder.add("aaa", "a").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "b").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "c").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "c").add("bbb", "b")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testContainsAllTrue(Consumer<ImmutableContextSet.Builder> setup) {
|
||||
ImmutableContextSetImpl set = (ImmutableContextSetImpl) new ImmutableContextSetImpl.BuilderImpl()
|
||||
.add("aaa", "a")
|
||||
.add("aaa", "b")
|
||||
@ -121,38 +133,43 @@ public class ContextSetTest {
|
||||
.add("bbb", "b")
|
||||
.build();
|
||||
|
||||
List<Consumer<ImmutableContextSet.Builder>> trueTests = ImmutableList.of(
|
||||
builder -> builder.add("aaa", "a").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "b").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "c").add("bbb", "a"),
|
||||
builder -> builder.add("aaa", "c").add("bbb", "b")
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
setup.accept(builder);
|
||||
|
||||
assertTrue(set.otherContainsAll(
|
||||
builder.build(),
|
||||
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|
||||
);
|
||||
}
|
||||
|
||||
for (Consumer<ImmutableContextSet.Builder> test : trueTests) {
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
test.accept(builder);
|
||||
assertTrue(set.otherContainsAll(
|
||||
builder.build(),
|
||||
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|
||||
);
|
||||
}
|
||||
|
||||
List<Consumer<ImmutableContextSet.Builder>> falseTests = ImmutableList.of(
|
||||
private static Stream<Consumer<ImmutableContextSet.Builder>> testContainsAllFalse() {
|
||||
return Stream.of(
|
||||
builder -> builder.add("aaa", "a").add("bbb", "z"),
|
||||
builder -> builder.add("aaa", "b").add("bbb", "z"),
|
||||
builder -> builder.add("aaa", "b"),
|
||||
builder -> builder.add("aaa", "c"),
|
||||
builder -> {}
|
||||
);
|
||||
}
|
||||
|
||||
for (Consumer<ImmutableContextSet.Builder> test : falseTests) {
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
test.accept(builder);
|
||||
assertFalse(set.otherContainsAll(
|
||||
builder.build(),
|
||||
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|
||||
);
|
||||
}
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testContainsAllFalse(Consumer<ImmutableContextSet.Builder> setup) {
|
||||
ImmutableContextSetImpl set = (ImmutableContextSetImpl) new ImmutableContextSetImpl.BuilderImpl()
|
||||
.add("aaa", "a")
|
||||
.add("aaa", "b")
|
||||
.add("aaa", "c")
|
||||
.add("bbb", "a")
|
||||
.add("bbb", "b")
|
||||
.build();
|
||||
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
setup.accept(builder);
|
||||
|
||||
assertFalse(set.otherContainsAll(
|
||||
builder.build(),
|
||||
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -25,54 +25,23 @@
|
||||
|
||||
package me.lucko.luckperms.common.dependencies;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class DependencyChecksumTest {
|
||||
|
||||
@Test
|
||||
@ParameterizedTest
|
||||
@EnumSource
|
||||
@Tag("dependency_checksum")
|
||||
public void check() {
|
||||
Dependency[] dependencies = Dependency.values();
|
||||
DependencyRepository[] repos = DependencyRepository.values();
|
||||
ExecutorService pool = Executors.newCachedThreadPool();
|
||||
|
||||
AtomicBoolean failed = new AtomicBoolean(false);
|
||||
|
||||
for (Dependency dependency : dependencies) {
|
||||
for (DependencyRepository repo : repos) {
|
||||
pool.submit(() -> {
|
||||
try {
|
||||
byte[] hash = Dependency.createDigest().digest(repo.downloadRaw(dependency));
|
||||
if (!dependency.checksumMatches(hash)) {
|
||||
System.out.println("NO MATCH - " + repo.name() + " - " + dependency.name() + ": " + Base64.getEncoder().encodeToString(hash));
|
||||
failed.set(true);
|
||||
} else {
|
||||
System.out.println("OK - " + repo.name() + " - " + dependency.name());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pool.shutdown();
|
||||
try {
|
||||
pool.awaitTermination(1, TimeUnit.HOURS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (failed.get()) {
|
||||
Assertions.fail("Some dependency checksums did not match");
|
||||
public void checksumMatches(Dependency dependency) throws DependencyDownloadException {
|
||||
for (DependencyRepository repo : DependencyRepository.values()) {
|
||||
byte[] hash = Dependency.createDigest().digest(repo.downloadRaw(dependency));
|
||||
assertTrue(dependency.checksumMatches(hash), "Dependency " + dependency.name() + " has hash " + Base64.getEncoder().encodeToString(hash));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.event;
|
||||
|
||||
import me.lucko.luckperms.common.event.gen.GeneratedEventClass;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.event.LuckPermsEvent;
|
||||
import net.luckperms.api.event.player.PlayerDataSaveEvent;
|
||||
import net.luckperms.api.event.sync.PreSyncEvent;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class EventGeneratorTest {
|
||||
|
||||
@Mock public LuckPerms luckPermsApi;
|
||||
|
||||
@Test
|
||||
public void testGenerateAll() {
|
||||
GeneratedEventClass.preGenerate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimple() throws Throwable {
|
||||
UUID randomUniqueId = UUID.randomUUID();
|
||||
String randomUsername = "random";
|
||||
PlayerSaveResult mockResult = mock(PlayerSaveResult.class);
|
||||
|
||||
GeneratedEventClass eventClass = GeneratedEventClass.generate(PlayerDataSaveEvent.class);
|
||||
LuckPermsEvent rawEvent = eventClass.newInstance(this.luckPermsApi, randomUniqueId, randomUsername, mockResult);
|
||||
|
||||
assertTrue(rawEvent instanceof PlayerDataSaveEvent);
|
||||
PlayerDataSaveEvent event = (PlayerDataSaveEvent) rawEvent;
|
||||
|
||||
assertEquals(PlayerDataSaveEvent.class, event.getEventType());
|
||||
assertSame(randomUniqueId, event.getUniqueId());
|
||||
assertSame(randomUsername, event.getUsername());
|
||||
assertSame(mockResult, event.getResult());
|
||||
assertSame(this.luckPermsApi, event.getLuckPerms());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMethods() throws Throwable {
|
||||
AtomicBoolean state = new AtomicBoolean(false);
|
||||
GeneratedEventClass eventClass = GeneratedEventClass.generate(PreSyncEvent.class);
|
||||
PreSyncEvent event = (PreSyncEvent) eventClass.newInstance(this.luckPermsApi, state);
|
||||
|
||||
assertFalse(event.isCancelled());
|
||||
assertTrue(event.isNotCancelled());
|
||||
assertEquals("PreSyncEvent{cancellationState=false}", event.toString());
|
||||
|
||||
assertFalse(event.setCancelled(true));
|
||||
|
||||
assertTrue(event.isCancelled());
|
||||
assertFalse(event.isNotCancelled());
|
||||
assertEquals("PreSyncEvent{cancellationState=true}", event.toString());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.model.manager.group.StandardGroupManager;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class GroupManagerTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
|
||||
@Test
|
||||
public void testSanitizeIdentifier() {
|
||||
StandardGroupManager manager = new StandardGroupManager(this.plugin) {
|
||||
@Override
|
||||
public Group apply(String name) {
|
||||
Group group = mock(Group.class);
|
||||
when(group.getName()).thenReturn(name);
|
||||
return group;
|
||||
}
|
||||
};
|
||||
|
||||
Group group = manager.getOrMake("DEFAULT");
|
||||
assertEquals("default", group.getName());
|
||||
assertEquals(ImmutableSet.of("default"), manager.getAll().keySet());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByDisplayName() {
|
||||
StandardGroupManager manager = new StandardGroupManager(this.plugin) {
|
||||
@Override
|
||||
public Group apply(String name) {
|
||||
return mock(Group.class);
|
||||
}
|
||||
};
|
||||
|
||||
Group defaultGroup = manager.getOrMake("default");
|
||||
when(defaultGroup.getDisplayName()).thenReturn(Optional.of("member"));
|
||||
|
||||
assertSame(defaultGroup, manager.getByDisplayName("default"));
|
||||
assertSame(defaultGroup, manager.getByDisplayName("Default"));
|
||||
assertSame(defaultGroup, manager.getByDisplayName("member"));
|
||||
assertSame(defaultGroup, manager.getByDisplayName("Member"));
|
||||
assertNull(manager.getByDisplayName("test"));
|
||||
|
||||
Group memberGroup = manager.getOrMake("member");
|
||||
|
||||
assertSame(defaultGroup, manager.getByDisplayName("default"));
|
||||
assertSame(defaultGroup, manager.getByDisplayName("Default"));
|
||||
assertSame(memberGroup, manager.getByDisplayName("member"));
|
||||
assertSame(memberGroup, manager.getByDisplayName("Member"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
|
||||
import me.lucko.luckperms.common.event.EventDispatcher;
|
||||
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
|
||||
import me.lucko.luckperms.common.inheritance.InheritanceGraphFactory;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.model.manager.group.StandardGroupManager;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Weight;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsImpl;
|
||||
|
||||
import net.luckperms.api.context.ContextSatisfyMode;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class InheritanceTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
@Mock private LuckPermsConfiguration configuration;
|
||||
|
||||
private StandardGroupManager groupManager;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
this.groupManager = new StandardGroupManager(this.plugin);
|
||||
|
||||
//noinspection unchecked,rawtypes
|
||||
lenient().when(this.plugin.getGroupManager()).thenReturn((GroupManager) this.groupManager);
|
||||
lenient().when(this.plugin.getInheritanceGraphFactory()).thenReturn(new InheritanceGraphFactory(this.plugin));
|
||||
lenient().when(this.plugin.getConfiguration()).thenReturn(this.configuration);
|
||||
lenient().when(this.plugin.getEventDispatcher()).thenReturn(mock(EventDispatcher.class));
|
||||
lenient().when(this.configuration.get(ConfigKeys.CONTEXT_SATISFY_MODE)).thenReturn(ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY);
|
||||
lenient().when(this.configuration.get(ConfigKeys.GROUP_WEIGHTS)).thenReturn(Collections.emptyMap());
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the following inheritance setup:
|
||||
* (value in brackets is the group weight)
|
||||
*
|
||||
* test user
|
||||
* │
|
||||
* ├── owner (13)
|
||||
* │ └── admin (12)
|
||||
* │ └── mod (11)
|
||||
* │ └── helper (10)
|
||||
* │ └── member (0)
|
||||
* └── vip+ (6)
|
||||
* └── vip (5)
|
||||
* └── member (0)
|
||||
*
|
||||
* This test checks if the resolved inheritance order is correct :)
|
||||
*/
|
||||
@ParameterizedTest(name = "[{index}] {0}, {1}")
|
||||
@CsvSource({
|
||||
"DEPTH_FIRST_PRE_ORDER, false, 'owner -> admin -> mod -> helper -> member -> vip+ -> vip'",
|
||||
"BREADTH_FIRST, false, 'owner -> vip+ -> admin -> vip -> mod -> member -> helper'",
|
||||
"DEPTH_FIRST_POST_ORDER, false, 'member -> helper -> mod -> admin -> owner -> vip -> vip+'",
|
||||
"DEPTH_FIRST_PRE_ORDER, true, 'owner -> admin -> mod -> helper -> vip+ -> vip -> member'",
|
||||
"BREADTH_FIRST, true, 'owner -> admin -> mod -> helper -> vip+ -> vip -> member'",
|
||||
"DEPTH_FIRST_POST_ORDER, true, 'owner -> admin -> mod -> helper -> vip+ -> vip -> member'"
|
||||
})
|
||||
public void testInheritanceTree(TraversalAlgorithm traversalAlgorithm, boolean postTraversalSort, String expected) {
|
||||
when(this.configuration.get(ConfigKeys.INHERITANCE_TRAVERSAL_ALGORITHM)).thenReturn(traversalAlgorithm);
|
||||
when(this.configuration.get(ConfigKeys.POST_TRAVERSAL_INHERITANCE_SORT)).thenReturn(postTraversalSort);
|
||||
|
||||
Group member = this.groupManager.getOrMake("member");
|
||||
|
||||
Group helper = createGroup("helper", 10, member);
|
||||
Group mod = createGroup("mod", 11, helper);
|
||||
Group admin = createGroup("admin", 12, mod);
|
||||
Group owner = createGroup("owner", 13, admin);
|
||||
|
||||
Group vip = createGroup("vip", 5, member);
|
||||
Group vipPlus = createGroup("vip+", 6, vip);
|
||||
|
||||
PermissionHolder testHolder = this.groupManager.getOrMake("test");
|
||||
testHolder.normalData().add(Inheritance.builder().group(owner.getName()).build());
|
||||
testHolder.normalData().add(Inheritance.builder().group(vipPlus.getName()).build());
|
||||
|
||||
List<String> groups = testHolder.resolveInheritanceTree(QueryOptionsImpl.DEFAULT_CONTEXTUAL)
|
||||
.stream().map(Group::getName).collect(Collectors.toList());
|
||||
|
||||
List<String> expectedList = Arrays.stream(expected.split(" -> ")).collect(Collectors.toList());
|
||||
assertEquals(expectedList, groups);
|
||||
}
|
||||
|
||||
private Group createGroup(String name, int weight, Group parent) {
|
||||
Group group = this.groupManager.getOrMake(name);
|
||||
group.normalData().add(Inheritance.builder().group(parent.getName()).build());
|
||||
group.normalData().add(Weight.builder().weight(weight).build());
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
|
||||
import me.lucko.luckperms.common.model.nodemap.NodeMapMutable;
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsBuilderImpl;
|
||||
import me.lucko.luckperms.common.util.Difference;
|
||||
|
||||
import net.luckperms.api.context.ContextSatisfyMode;
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeType;
|
||||
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
|
||||
import net.luckperms.api.node.types.InheritanceNode;
|
||||
import net.luckperms.api.query.Flag;
|
||||
import net.luckperms.api.query.QueryMode;
|
||||
import net.luckperms.api.query.QueryOptions;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class NodeMapTest {
|
||||
|
||||
private static final PermissionHolderIdentifier ORIGIN = new PermissionHolderIdentifier(HolderType.GROUP, "test");
|
||||
|
||||
@Mock private PermissionHolder mockHolder;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
when(this.mockHolder.getIdentifier()).thenReturn(ORIGIN);
|
||||
}
|
||||
|
||||
private static Node makeNode(String key) {
|
||||
return NodeBuilders.determineMostApplicable(key).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleAddAndRemove() {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
assertEquals(0, map.size());
|
||||
|
||||
Node node = makeNode("test");
|
||||
|
||||
Difference<Node> r1 = map.add(node);
|
||||
assertEquals(ImmutableSet.of(node), r1.getAdded());
|
||||
assertEquals(ImmutableSet.of(), r1.getRemoved());
|
||||
assertEquals(1, map.size());
|
||||
|
||||
Difference<Node> r2 = map.remove(node);
|
||||
assertEquals(ImmutableSet.of(), r2.getAdded());
|
||||
assertEquals(ImmutableSet.of(node), r2.getRemoved());
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInheritanceOrigin() {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
Node node = makeNode("test");
|
||||
|
||||
map.add(node);
|
||||
|
||||
List<Node> nodes = map.asList();
|
||||
assertEquals(ImmutableList.of(node), map.asList());
|
||||
|
||||
InheritanceOriginMetadata origin = nodes.get(0).metadata(InheritanceOriginMetadata.KEY);
|
||||
assertEquals(ORIGIN, origin.getOrigin());
|
||||
assertEquals(DataType.NORMAL, origin.getDataType());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"test, true, false",
|
||||
"test, false, true",
|
||||
"group.test, true, false",
|
||||
"group.test, false, true"
|
||||
})
|
||||
public void testRemoveMatchingButNotSameValue(String nodeKey, boolean firstValue, boolean secondValue) {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
|
||||
Node first = makeNode(nodeKey).toBuilder().value(firstValue).build();
|
||||
Node second = makeNode(nodeKey).toBuilder().value(secondValue).build();
|
||||
|
||||
map.add(first);
|
||||
|
||||
Difference<Node> diff = map.add(second);
|
||||
assertEquals(ImmutableSet.of(first), diff.getRemoved());
|
||||
assertEquals(ImmutableSet.of(second), diff.getAdded());
|
||||
assertEquals(ImmutableList.of(second), map.asList());
|
||||
|
||||
if (second.getType() == NodeType.INHERITANCE && second.getValue()) {
|
||||
assertEquals(ImmutableList.of(second), map.inheritanceAsList());
|
||||
} else {
|
||||
assertEquals(ImmutableList.of(), map.inheritanceAsList());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"test, 1, 5",
|
||||
"test, 5, 1",
|
||||
"group.test, 1, 5",
|
||||
"group.test, 5, 1"
|
||||
})
|
||||
public void testRemoveMatchingButNotSameExpiry(String nodeKey, int firstDuration, int secondDuration) {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
|
||||
Node first = makeNode(nodeKey).toBuilder()
|
||||
.expiry(firstDuration == 0 ? null : Duration.ofDays(firstDuration))
|
||||
.build();
|
||||
Node second = makeNode(nodeKey).toBuilder()
|
||||
.expiry(secondDuration == 0 ? null : Duration.ofDays(secondDuration))
|
||||
.build();
|
||||
|
||||
map.add(first);
|
||||
|
||||
Difference<Node> diff = map.add(second);
|
||||
assertEquals(ImmutableSet.of(first), diff.getRemoved());
|
||||
assertEquals(ImmutableSet.of(second), diff.getAdded());
|
||||
assertEquals(ImmutableList.of(second), map.asList());
|
||||
|
||||
if (second.getType() == NodeType.INHERITANCE) {
|
||||
assertEquals(ImmutableList.of(second), map.inheritanceAsList());
|
||||
} else {
|
||||
assertEquals(ImmutableList.of(), map.inheritanceAsList());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
map.add(makeNode("test1"));
|
||||
map.add(makeNode("test2").toBuilder().value(false).build());
|
||||
map.add(makeNode("test3").toBuilder().expiry(1, TimeUnit.HOURS).build());
|
||||
map.add(makeNode("test4").toBuilder().withContext("hello", "world").build());
|
||||
|
||||
assertEquals(4, map.size());
|
||||
|
||||
map.remove(makeNode("test1").toBuilder().withContext("hello", "world").build());
|
||||
map.remove(makeNode("test3"));
|
||||
map.remove(makeNode("test4"));
|
||||
map.remove(makeNode("test4").toBuilder().withContext("hello", "world").withContext("aaa", "bbb").build());
|
||||
map.remove(makeNode("test5"));
|
||||
|
||||
assertEquals(4, map.size());
|
||||
|
||||
map.remove(makeNode("test1"));
|
||||
map.remove(makeNode("test2").toBuilder().value(true).build());
|
||||
map.remove(makeNode("test3").toBuilder().expiry(2, TimeUnit.HOURS).build());
|
||||
map.remove(makeNode("test4").toBuilder().withContext("hello", "world").build());
|
||||
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveExact() {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL);
|
||||
map.add(makeNode("test1"));
|
||||
map.add(makeNode("test2").toBuilder().value(false).build());
|
||||
map.add(makeNode("test3").toBuilder().expiry(1, TimeUnit.HOURS).build());
|
||||
map.add(makeNode("test4").toBuilder().withContext("hello", "world").build());
|
||||
|
||||
assertEquals(4, map.size());
|
||||
|
||||
map.removeExact(makeNode("test1").toBuilder().withContext("hello", "world").build());
|
||||
map.removeExact(makeNode("test3"));
|
||||
map.removeExact(makeNode("test4"));
|
||||
map.removeExact(makeNode("test4").toBuilder().withContext("hello", "world").withContext("aaa", "bbb").build());
|
||||
map.removeExact(makeNode("test5"));
|
||||
|
||||
assertEquals(4, map.size());
|
||||
|
||||
map.removeExact(makeNode("test2").toBuilder().value(true).build());
|
||||
map.removeExact(makeNode("test3").toBuilder().expiry(2, TimeUnit.HOURS).build());
|
||||
map.removeExact(makeNode("test4").toBuilder().withContext("hello", "world").withContext("aaa", "bbb").build());
|
||||
|
||||
assertEquals(4, map.size());
|
||||
|
||||
map.removeExact(makeNode("test1"));
|
||||
map.removeExact(makeNode("test2").toBuilder().value(false).build());
|
||||
map.removeExact(makeNode("test3").toBuilder().expiry(1, TimeUnit.HOURS).build());
|
||||
map.removeExact(makeNode("test4").toBuilder().withContext("hello", "world").build());
|
||||
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "s={0} w={1} is={2} iw={3}")
|
||||
@CsvSource({
|
||||
"true, true, true, true, 8, 4",
|
||||
"true, true, false, false, 8, 1",
|
||||
"false, true, true, true, 6, 4",
|
||||
"true, false, true, true, 6, 4",
|
||||
"false, false, true, true, 5, 4",
|
||||
"false, true, false, true, 4, 2",
|
||||
"true, false, true, false, 4, 2",
|
||||
"false, false, false, false, 2, 1"
|
||||
})
|
||||
public void testFlagsFiltering(boolean includeServer, boolean includeWorld, boolean inheritanceIncludeServer, boolean inheritanceIncludeWorld, int expected, int expectedInheritance) {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL) {
|
||||
@Override
|
||||
protected ContextSatisfyMode defaultSatisfyMode() {
|
||||
return ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY;
|
||||
}
|
||||
};
|
||||
|
||||
map.add(makeNode("test1"));
|
||||
map.add(makeNode("test2").toBuilder().withContext("server", "test").build());
|
||||
map.add(makeNode("test3").toBuilder().withContext("world", "test").build());
|
||||
map.add(makeNode("test4").toBuilder().withContext("server", "test").withContext("world", "test").build());
|
||||
map.add(makeNode("group.test1"));
|
||||
map.add(makeNode("group.test2").toBuilder().withContext("server", "test").build());
|
||||
map.add(makeNode("group.test3").toBuilder().withContext("world", "test").build());
|
||||
map.add(makeNode("group.test4").toBuilder().withContext("server", "test").withContext("world", "test").build());
|
||||
|
||||
Set<Flag> flags = EnumSet.noneOf(Flag.class);
|
||||
if (includeServer) flags.add(Flag.INCLUDE_NODES_WITHOUT_SERVER_CONTEXT);
|
||||
if (includeWorld) flags.add(Flag.INCLUDE_NODES_WITHOUT_WORLD_CONTEXT);
|
||||
if (inheritanceIncludeServer) flags.add(Flag.APPLY_INHERITANCE_NODES_WITHOUT_SERVER_CONTEXT);
|
||||
if (inheritanceIncludeWorld) flags.add(Flag.APPLY_INHERITANCE_NODES_WITHOUT_WORLD_CONTEXT);
|
||||
|
||||
QueryOptions options = new QueryOptionsBuilderImpl(QueryMode.NON_CONTEXTUAL)
|
||||
.flags(flags)
|
||||
.build();
|
||||
|
||||
Set<Node> output = new HashSet<>();
|
||||
map.copyTo(output, options);
|
||||
assertEquals(expected, output.size());
|
||||
|
||||
output.clear();
|
||||
map.forEach(options, output::add);
|
||||
assertEquals(expected, output.size());
|
||||
|
||||
Set<InheritanceNode> inheritanceOutput = new HashSet<>();
|
||||
map.copyInheritanceNodesTo(inheritanceOutput, options);
|
||||
assertEquals(expectedInheritance, inheritanceOutput.size());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"'', 2, 1",
|
||||
"server=test, 4, 2",
|
||||
"world=test, 4, 2",
|
||||
"server=test|world=test, 8, 4",
|
||||
"server=test|world=test|test=test, 8, 4",
|
||||
})
|
||||
public void testContextFiltering(String context, int expected, int expectedInheritance) {
|
||||
NodeMapMutable map = new NodeMapMutable(this.mockHolder, DataType.NORMAL) {
|
||||
@Override
|
||||
protected ContextSatisfyMode defaultSatisfyMode() {
|
||||
return ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY;
|
||||
}
|
||||
};
|
||||
|
||||
map.add(makeNode("test1"));
|
||||
map.add(makeNode("test2").toBuilder().withContext("server", "test").build());
|
||||
map.add(makeNode("test3").toBuilder().withContext("world", "test").build());
|
||||
map.add(makeNode("test4").toBuilder().withContext("server", "test").withContext("world", "test").build());
|
||||
map.add(makeNode("group.test1"));
|
||||
map.add(makeNode("group.test2").toBuilder().withContext("server", "test").build());
|
||||
map.add(makeNode("group.test3").toBuilder().withContext("world", "test").build());
|
||||
map.add(makeNode("group.test4").toBuilder().withContext("server", "test").withContext("world", "test").build());
|
||||
|
||||
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
|
||||
if (!context.isEmpty()) {
|
||||
Splitter.on('|').withKeyValueSeparator('=').split(context).forEach(builder::add);
|
||||
}
|
||||
|
||||
QueryOptions options = new QueryOptionsBuilderImpl(QueryMode.CONTEXTUAL)
|
||||
.context(builder.build())
|
||||
.build();
|
||||
|
||||
Set<Node> output = new HashSet<>();
|
||||
map.copyTo(output, options);
|
||||
assertEquals(expected, output.size());
|
||||
|
||||
output.clear();
|
||||
map.forEach(options, output::add);
|
||||
assertEquals(expected, output.size());
|
||||
|
||||
Set<InheritanceNode> inheritanceOutput = new HashSet<>();
|
||||
map.copyInheritanceNodesTo(inheritanceOutput, options);
|
||||
assertEquals(expectedInheritance, inheritanceOutput.size());
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.common.event.EventDispatcher;
|
||||
import me.lucko.luckperms.common.node.types.Permission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import net.luckperms.api.model.data.DataMutateResult;
|
||||
import net.luckperms.api.model.data.DataType;
|
||||
import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
|
||||
import net.luckperms.api.node.types.PermissionNode;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class PermissionHolderTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
when(this.plugin.getEventDispatcher()).thenReturn(mock(EventDispatcher.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemporaryMergeNone() {
|
||||
PermissionHolder holder = new Group("test", this.plugin);
|
||||
|
||||
PermissionNode node1 = Permission.builder().permission("test").expiry(1, TimeUnit.HOURS).build();
|
||||
PermissionNode node2 = Permission.builder().permission("test").expiry(2, TimeUnit.HOURS).build();
|
||||
|
||||
TemporaryNodeMergeStrategy strategy = TemporaryNodeMergeStrategy.NONE;
|
||||
|
||||
DataMutateResult.WithMergedNode r1 = holder.setNode(DataType.NORMAL, node1, strategy);
|
||||
assertEquals(DataMutateResult.SUCCESS, r1.getResult());
|
||||
assertEquals(ImmutableList.of(node1), holder.normalData().asList());
|
||||
|
||||
DataMutateResult.WithMergedNode r2 = holder.setNode(DataType.NORMAL, node2, strategy);
|
||||
assertEquals(DataMutateResult.FAIL_ALREADY_HAS, r2.getResult());
|
||||
assertEquals(ImmutableList.of(node1), holder.normalData().asList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemporaryMergeReplaceIfLonger() {
|
||||
PermissionHolder holder = new Group("test", this.plugin);
|
||||
|
||||
PermissionNode node1 = Permission.builder().permission("test").expiry(1, TimeUnit.HOURS).build();
|
||||
PermissionNode node2 = Permission.builder().permission("test").expiry(2, TimeUnit.HOURS).build();
|
||||
|
||||
TemporaryNodeMergeStrategy strategy = TemporaryNodeMergeStrategy.REPLACE_EXISTING_IF_DURATION_LONGER;
|
||||
|
||||
DataMutateResult.WithMergedNode r1 = holder.setNode(DataType.NORMAL, node1, strategy);
|
||||
assertEquals(DataMutateResult.SUCCESS, r1.getResult());
|
||||
assertEquals(ImmutableList.of(node1), holder.normalData().asList());
|
||||
|
||||
DataMutateResult.WithMergedNode r2 = holder.setNode(DataType.NORMAL, node2, strategy);
|
||||
assertEquals(DataMutateResult.SUCCESS, r2.getResult());
|
||||
assertEquals(ImmutableList.of(node2), holder.normalData().asList());
|
||||
assertEquals(node2, r2.getMergedNode());
|
||||
|
||||
DataMutateResult.WithMergedNode r3 = holder.setNode(DataType.NORMAL, node1, strategy);
|
||||
assertEquals(DataMutateResult.FAIL_ALREADY_HAS, r3.getResult());
|
||||
assertEquals(ImmutableList.of(node2), holder.normalData().asList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemporaryMergeAddDurations() {
|
||||
PermissionHolder holder = new Group("test", this.plugin);
|
||||
|
||||
PermissionNode node1 = Permission.builder().permission("test").expiry(2, TimeUnit.HOURS).build();
|
||||
PermissionNode node2 = Permission.builder().permission("test").expiry(1, TimeUnit.HOURS).build();
|
||||
|
||||
TemporaryNodeMergeStrategy strategy = TemporaryNodeMergeStrategy.ADD_NEW_DURATION_TO_EXISTING;
|
||||
|
||||
DataMutateResult.WithMergedNode r1 = holder.setNode(DataType.NORMAL, node1, strategy);
|
||||
assertEquals(DataMutateResult.SUCCESS, r1.getResult());
|
||||
assertEquals(ImmutableList.of(node1), holder.normalData().asList());
|
||||
|
||||
DataMutateResult.WithMergedNode r2 = holder.setNode(DataType.NORMAL, node2, strategy);
|
||||
assertEquals(DataMutateResult.SUCCESS, r2.getResult());
|
||||
|
||||
Instant originalExpiry = node1.getExpiry();
|
||||
assertNotNull(originalExpiry);
|
||||
|
||||
Instant newExpiry = r2.getMergedNode().getExpiry();
|
||||
assertNotNull(newExpiry);
|
||||
|
||||
Instant expectedExpiry = node1.getExpiry().plus(1, ChronoUnit.HOURS);
|
||||
|
||||
// uses wall-clock time, so allow for the tests to run slowly
|
||||
assertTrue(Duration.between(newExpiry, expectedExpiry).abs().getSeconds() < 5);
|
||||
}
|
||||
|
||||
}
|
@ -23,48 +23,31 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node.utils;
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.model.manager.track.StandardTrackManager;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ShorthandParserTest {
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class TrackManagerTest {
|
||||
|
||||
private static void test(String shorthand, String... expected) {
|
||||
assertEquals(ImmutableSet.copyOf(expected), ShorthandParser.expandShorthand(shorthand));
|
||||
}
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
|
||||
@Test
|
||||
void testNumericRange() {
|
||||
test("{2-4}", "2", "3", "4");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCharacterRange() {
|
||||
test("{a-d}", "a", "b", "c", "d");
|
||||
test("{A-D}", "A", "B", "C", "D");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testList() {
|
||||
test("{aa,bb,cc}", "aa", "bb", "cc");
|
||||
test("{aa|bb|cc}", "aa", "bb", "cc");
|
||||
test("{aa,bb|cc}", "aa", "bb", "cc");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGroups() {
|
||||
test("he{y|llo} {1-2}", "hey 1", "hey 2", "hello 1", "hello 2");
|
||||
test("my.permission.{test,hi}", "my.permission.test", "my.permission.hi");
|
||||
test("my.permission.{a-c}", "my.permission.a", "my.permission.b", "my.permission.c");
|
||||
|
||||
// use ( ) instead
|
||||
test("he(y|llo) (1-2)", "hey 1", "hey 2", "hello 1", "hello 2");
|
||||
test("my.permission.(test,hi)", "my.permission.test", "my.permission.hi");
|
||||
test("my.permission.(a-c)", "my.permission.a", "my.permission.b", "my.permission.c");
|
||||
public void testSanitizeIdentifier() {
|
||||
StandardTrackManager manager = new StandardTrackManager(this.plugin);
|
||||
Track track = manager.getOrMake("TEST");
|
||||
assertEquals("test", track.getName());
|
||||
assertEquals(ImmutableSet.of("test"), manager.getAll().keySet());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
|
||||
import me.lucko.luckperms.common.event.EventDispatcher;
|
||||
import me.lucko.luckperms.common.model.manager.user.StandardUserManager;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Permission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
|
||||
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UserManagerTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
@Mock private LuckPermsBootstrap bootstrap;
|
||||
@Mock private LuckPermsConfiguration configuration;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
lenient().when(this.plugin.getBootstrap()).thenReturn(this.bootstrap);
|
||||
lenient().when(this.plugin.getConfiguration()).thenReturn(this.configuration);
|
||||
lenient().when(this.plugin.getEventDispatcher()).thenReturn(mock(EventDispatcher.class));
|
||||
lenient().when(this.bootstrap.getScheduler()).thenReturn(mock(SchedulerAdapter.class));
|
||||
lenient().when(this.configuration.get(ConfigKeys.PRIMARY_GROUP_CALCULATION)).thenReturn(PrimaryGroupHolder.AllParentsByWeight::new);
|
||||
lenient().when(this.configuration.get(ConfigKeys.PRIMARY_GROUP_CALCULATION_METHOD)).thenReturn("parents-by-weight");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGiveDefaultIfNeeded() {
|
||||
StandardUserManager manager = new StandardUserManager(this.plugin);
|
||||
|
||||
User user = manager.getOrMake(UUID.randomUUID());
|
||||
assertEquals(ImmutableList.of(), user.normalData().asList());
|
||||
|
||||
boolean changed = manager.giveDefaultIfNeeded(user);
|
||||
assertTrue(changed);
|
||||
|
||||
Inheritance defaultNode = Inheritance.builder("default").build();
|
||||
assertEquals(ImmutableList.of(defaultNode), user.normalData().asList());
|
||||
|
||||
changed = manager.giveDefaultIfNeeded(user);
|
||||
assertFalse(changed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNonDefaultUser() {
|
||||
StandardUserManager manager = new StandardUserManager(this.plugin);
|
||||
User user = manager.getOrMake(UUID.randomUUID());
|
||||
manager.giveDefaultIfNeeded(user);
|
||||
|
||||
assertFalse(manager.isNonDefaultUser(user));
|
||||
|
||||
user.normalData().add(Permission.builder().permission("test").build());
|
||||
assertTrue(manager.isNonDefaultUser(user));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsDefaultNode() {
|
||||
StandardUserManager manager = new StandardUserManager(this.plugin);
|
||||
|
||||
assertTrue(manager.isDefaultNode(Inheritance.builder().group("default").build()));
|
||||
assertTrue(manager.isDefaultNode(Inheritance.builder().group("Default").build()));
|
||||
|
||||
assertFalse(manager.isDefaultNode(Inheritance.builder().group("default").value(false).build()));
|
||||
assertFalse(manager.isDefaultNode(Inheritance.builder().group("default").withContext("server", "test").build()));
|
||||
assertFalse(manager.isDefaultNode(Inheritance.builder().group("default").expiry(1, TimeUnit.DAYS).build()));
|
||||
assertFalse(manager.isDefaultNode(Inheritance.builder().group("test").build()));
|
||||
assertFalse(manager.isDefaultNode(Permission.builder().permission("hello").build()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node;
|
||||
|
||||
import me.lucko.luckperms.common.node.factory.NodeBuilders;
|
||||
import me.lucko.luckperms.common.node.types.Permission;
|
||||
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.NodeBuilder;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class NodeBuildersTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"luckperms.user.info, Permission$Builder, PERMISSION",
|
||||
"group.default, Inheritance$Builder, INHERITANCE",
|
||||
"meta.key.value, Meta$Builder, META",
|
||||
"prefix.100.hello, Prefix$Builder, PREFIX",
|
||||
"suffix.100.hello, Suffix$Builder, SUFFIX",
|
||||
"displayname.hello, DisplayName$Builder, DISPLAY_NAME",
|
||||
"weight.10, Weight$Builder, WEIGHT",
|
||||
"r=hello, RegexPermission$Builder, REGEX_PERMISSION",
|
||||
"R=hello, RegexPermission$Builder, REGEX_PERMISSION"
|
||||
})
|
||||
public void testDetermineMostApplicableType(String key, String expectedBuilderClass, String expectedType) {
|
||||
NodeBuilder<?, ?> builder = NodeBuilders.determineMostApplicable(key);
|
||||
assertTrue(builder.getClass().getName().endsWith(expectedBuilderClass));
|
||||
|
||||
Node node = builder.build();
|
||||
assertEquals(expectedType, node.getType().name());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonSpecificNodeBuild() {
|
||||
Permission.Builder builder = Permission.builder().permission("group.default");
|
||||
assertThrows(IllegalArgumentException.class, builder::build);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node;
|
||||
|
||||
import me.lucko.luckperms.common.node.types.DisplayName;
|
||||
import me.lucko.luckperms.common.node.types.Inheritance;
|
||||
import me.lucko.luckperms.common.node.types.Meta;
|
||||
import me.lucko.luckperms.common.node.types.Prefix;
|
||||
import me.lucko.luckperms.common.node.types.RegexPermission;
|
||||
import me.lucko.luckperms.common.node.types.Suffix;
|
||||
import me.lucko.luckperms.common.node.types.Weight;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
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.assertThrows;
|
||||
|
||||
public class NodeParseTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"group.test, test",
|
||||
"group.TEST, test",
|
||||
"group.hello world, hello world"
|
||||
})
|
||||
public void testInheritance(String key, String expectedGroupName) {
|
||||
Inheritance.Builder builder = Inheritance.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
Inheritance node = builder.build();
|
||||
assertEquals(expectedGroupName, node.getGroupName());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa"
|
||||
})
|
||||
public void testInheritanceFail(String key) {
|
||||
Inheritance.Builder builder = Inheritance.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"displayname.test, test",
|
||||
"displayname.TEST, TEST",
|
||||
"displayname.hello world, hello world"
|
||||
})
|
||||
public void testDisplayName(String key, String expectedDisplayName) {
|
||||
DisplayName.Builder builder = DisplayName.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
DisplayName node = builder.build();
|
||||
assertEquals(expectedDisplayName, node.getDisplayName());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa"
|
||||
})
|
||||
public void testDisplayNameFail(String key) {
|
||||
DisplayName.Builder builder = DisplayName.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"weight.100, 100",
|
||||
"weight.-100, -100",
|
||||
"weight.0, 0"
|
||||
})
|
||||
public void testWeight(String key, int expectedWeight) {
|
||||
Weight.Builder builder = Weight.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
Weight node = builder.build();
|
||||
assertEquals(expectedWeight, node.getWeight());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa",
|
||||
"weight.",
|
||||
"weight.hello"
|
||||
})
|
||||
public void testWeightFail(String key) {
|
||||
Weight.Builder builder = Weight.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"prefix.100.hello, 100, hello",
|
||||
"prefix.-100.hello, -100, hello",
|
||||
"prefix.0.hello, 0, hello",
|
||||
"prefix.100.hello world, 100, hello world",
|
||||
"prefix.100.HELLO world &123, 100, HELLO world &123",
|
||||
"prefix.100., 100, ''"
|
||||
})
|
||||
public void testPrefix(String key, int expectedPriority, String expectedValue) {
|
||||
Prefix.Builder builder = Prefix.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
Prefix node = builder.build();
|
||||
assertEquals(expectedPriority, node.getPriority());
|
||||
assertEquals(expectedValue, node.getMetaValue());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa",
|
||||
"prefix.",
|
||||
"prefix.hello",
|
||||
"prefix.100",
|
||||
"prefix.hello.hello"
|
||||
})
|
||||
public void testPrefixFail(String key) {
|
||||
Prefix.Builder builder = Prefix.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"suffix.100.hello, 100, hello",
|
||||
"suffix.-100.hello, -100, hello",
|
||||
"suffix.0.hello, 0, hello",
|
||||
"suffix.100.hello world, 100, hello world",
|
||||
"suffix.100.HELLO world &123, 100, HELLO world &123",
|
||||
"suffix.100., 100, ''"
|
||||
})
|
||||
public void testSuffix(String key, int expectedPriority, String expectedValue) {
|
||||
Suffix.Builder builder = Suffix.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
Suffix node = builder.build();
|
||||
assertEquals(expectedPriority, node.getPriority());
|
||||
assertEquals(expectedValue, node.getMetaValue());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa",
|
||||
"suffix.",
|
||||
"suffix.hello",
|
||||
"suffix.100",
|
||||
"suffix.hello.hello"
|
||||
})
|
||||
public void testSuffixFail(String key) {
|
||||
Suffix.Builder builder = Suffix.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"meta.k.v, k, v",
|
||||
"meta.hello.world, hello, world",
|
||||
"meta.hello., hello, ''"
|
||||
})
|
||||
public void testMeta(String key, String expectedKey, String expectedValue) {
|
||||
Meta.Builder builder = Meta.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
Meta node = builder.build();
|
||||
assertEquals(expectedKey, node.getMetaKey());
|
||||
assertEquals(expectedValue, node.getMetaValue());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa",
|
||||
"meta.",
|
||||
"meta.hello",
|
||||
})
|
||||
public void testMetaFail(String key) {
|
||||
Meta.Builder builder = Meta.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"meta.."
|
||||
})
|
||||
public void testMetaFailThrows(String key) {
|
||||
assertThrows(IllegalArgumentException.class, () -> Meta.parse(key));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"r=hello, hello",
|
||||
"R=hello, hello",
|
||||
"r=.*&^12 3[], .*&^12 3[]"
|
||||
})
|
||||
public void testRegexPermission(String key, String expectedPattern) {
|
||||
RegexPermission.Builder builder = RegexPermission.parse(key);
|
||||
assertNotNull(builder);
|
||||
|
||||
RegexPermission node = builder.build();
|
||||
assertEquals(expectedPattern, node.getPatternString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"",
|
||||
"aaaa"
|
||||
})
|
||||
public void testRegexPermissionFail(String key) {
|
||||
RegexPermission.Builder builder = RegexPermission.parse(key);
|
||||
assertNull(builder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"r=",
|
||||
"R="
|
||||
})
|
||||
public void testRegexPermissionFailThrows(String key) {
|
||||
assertThrows(IllegalArgumentException.class, () -> RegexPermission.parse(key));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node;
|
||||
|
||||
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
|
||||
import me.lucko.luckperms.common.node.types.Permission;
|
||||
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.metadata.NodeMetadataKey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class NodeTest {
|
||||
|
||||
@Test
|
||||
public void testBasic() {
|
||||
Node node = Permission.builder()
|
||||
.permission("hello.world")
|
||||
.build();
|
||||
|
||||
assertEquals("hello.world", node.getKey());
|
||||
assertTrue(node.getValue());
|
||||
assertNull(node.getExpiry());
|
||||
assertNull(node.getExpiryDuration());
|
||||
assertFalse(node.hasExpired());
|
||||
assertFalse(node.hasExpiry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpiry() {
|
||||
Instant instant = Instant.now()
|
||||
.plusSeconds(60)
|
||||
.truncatedTo(ChronoUnit.SECONDS);
|
||||
|
||||
Node node = Permission.builder()
|
||||
.permission("hello.world")
|
||||
.expiry(instant)
|
||||
.build();
|
||||
|
||||
assertEquals("hello.world", node.getKey());
|
||||
assertTrue(node.getValue());
|
||||
assertEquals(instant, node.getExpiry());
|
||||
assertNotNull(node.getExpiryDuration());
|
||||
assertFalse(node.hasExpired());
|
||||
assertTrue(node.hasExpiry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContext() {
|
||||
Node node = Permission.builder()
|
||||
.permission("hello.world")
|
||||
.withContext("hello", "123")
|
||||
.withContext("world", "456")
|
||||
.build();
|
||||
|
||||
ImmutableContextSet contexts = node.getContexts();
|
||||
ImmutableContextSet expected = new ImmutableContextSetImpl.BuilderImpl()
|
||||
.add("hello", "123")
|
||||
.add("world", "456")
|
||||
.build();
|
||||
|
||||
assertEquals(expected, contexts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadata() {
|
||||
NodeMetadataKey<UUID> key = NodeMetadataKey.of("test2", UUID.class);
|
||||
UUID randomUniqueId = UUID.randomUUID();
|
||||
|
||||
Node node = Permission.builder()
|
||||
.permission("hello.world")
|
||||
.withMetadata(key, randomUniqueId)
|
||||
.build();
|
||||
|
||||
assertEquals(Optional.of(randomUniqueId), node.getMetadata(key));
|
||||
assertEquals(randomUniqueId, node.metadata(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataFails() {
|
||||
NodeMetadataKey<String> key1 = NodeMetadataKey.of("test1", String.class);
|
||||
NodeMetadataKey<UUID> key2 = NodeMetadataKey.of("test2", UUID.class);
|
||||
NodeMetadataKey<UUID> key3 = NodeMetadataKey.of("test2", UUID.class);
|
||||
NodeMetadataKey<String> key4 = NodeMetadataKey.of("test2", String.class);
|
||||
UUID randomUniqueId = UUID.randomUUID();
|
||||
|
||||
Node node = Permission.builder()
|
||||
.permission("hello.world")
|
||||
.withMetadata(key2, randomUniqueId)
|
||||
.build();
|
||||
|
||||
assertEquals(Optional.of(randomUniqueId), node.getMetadata(key2));
|
||||
assertEquals(Optional.of(randomUniqueId), node.getMetadata(key3));
|
||||
assertEquals(randomUniqueId, node.metadata(key2));
|
||||
assertEquals(randomUniqueId, node.metadata(key3));
|
||||
|
||||
assertEquals(Optional.empty(), node.getMetadata(key1));
|
||||
assertEquals(Optional.empty(), node.getMetadata(key4));
|
||||
assertThrows(IllegalStateException.class, () -> node.metadata(key1));
|
||||
assertThrows(IllegalStateException.class, () -> node.metadata(key4));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.node;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.node.utils.ShorthandParser;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ShorthandParserTest {
|
||||
|
||||
private static Stream<Arguments> testParse() {
|
||||
return Stream.of(
|
||||
// numeric range
|
||||
Arguments.of("{2-4}", new String[]{"2", "3", "4"}),
|
||||
|
||||
// character range
|
||||
Arguments.of("{a-d}", new String[]{"a", "b", "c", "d"}),
|
||||
Arguments.of("{A-D}", new String[]{"A", "B", "C", "D"}),
|
||||
|
||||
// list
|
||||
Arguments.of("{aa,bb,cc}", new String[]{"aa", "bb", "cc"}),
|
||||
Arguments.of("{aa|bb|cc}", new String[]{"aa", "bb", "cc"}),
|
||||
Arguments.of("{aa,bb|cc}", new String[]{"aa", "bb", "cc"}),
|
||||
|
||||
// groups
|
||||
Arguments.of("he{y|llo} {1-2}", new String[]{"hey 1", "hey 2", "hello 1", "hello 2"}),
|
||||
Arguments.of("my.permission.{test,hi}", new String[]{"my.permission.test", "my.permission.hi"}),
|
||||
Arguments.of("my.permission.{a-c}", new String[]{"my.permission.a", "my.permission.b", "my.permission.c"}),
|
||||
|
||||
// groups - using () instead
|
||||
Arguments.of("he(y|llo) (1-2)", new String[]{"hey 1", "hey 2", "hello 1", "hello 2"}),
|
||||
Arguments.of("my.permission.(test,hi)", new String[]{"my.permission.test", "my.permission.hi"}),
|
||||
Arguments.of("my.permission.(a-c)", new String[]{"my.permission.a", "my.permission.b", "my.permission.c"})
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testParse(String shorthand, String[] expected) {
|
||||
Assertions.assertEquals(ImmutableSet.copyOf(expected), ShorthandParser.expandShorthand(shorthand));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.actionlog.LoggedAction;
|
||||
import me.lucko.luckperms.common.event.EventDispatcher;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.manager.group.GroupManager;
|
||||
import me.lucko.luckperms.common.model.manager.group.StandardGroupManager;
|
||||
import me.lucko.luckperms.common.node.types.Permission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.file.NonClosableConnection;
|
||||
|
||||
import net.luckperms.api.actionlog.Action;
|
||||
import net.luckperms.api.model.PlayerSaveResult;
|
||||
import net.luckperms.api.model.PlayerSaveResult.Outcome;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.types.PermissionNode;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.AdditionalAnswers.answer;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class SqlStorageTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
@Mock private LuckPermsBootstrap bootstrap;
|
||||
|
||||
private SqlStorage storage;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocksAndDatabase() throws Exception {
|
||||
lenient().when(this.plugin.getBootstrap()).thenReturn(this.bootstrap);
|
||||
lenient().when(this.bootstrap.getResourceStream(anyString()))
|
||||
.then(answer((String path) -> SqlStorageTest.class.getClassLoader().getResourceAsStream(path)));
|
||||
lenient().when(this.plugin.getEventDispatcher()).thenReturn(mock(EventDispatcher.class));
|
||||
|
||||
this.storage = new SqlStorage(this.plugin, new TestH2ConnectionFactory(), "luckperms_");
|
||||
this.storage.init();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void shutdownDatabase() {
|
||||
this.storage.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionLog() throws Exception {
|
||||
LoggedAction action = LoggedAction.build()
|
||||
.source(UUID.randomUUID())
|
||||
.sourceName("Test Source")
|
||||
.targetType(Action.Target.Type.USER)
|
||||
.target(UUID.randomUUID())
|
||||
.targetName("Test Target")
|
||||
.description("hello 123 hello 123")
|
||||
.build();
|
||||
|
||||
this.storage.logAction(action);
|
||||
|
||||
Log log = this.storage.getLog();
|
||||
assertEquals(1, log.getContent().size());
|
||||
assertEquals(action, log.getContent().first());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSavePlayerData() throws Exception {
|
||||
UUID uniqueId = UUID.randomUUID();
|
||||
|
||||
// clean insert
|
||||
PlayerSaveResult r1 = this.storage.savePlayerData(uniqueId, "Player1");
|
||||
assertEquals(ImmutableSet.of(Outcome.CLEAN_INSERT), r1.getOutcomes());
|
||||
assertNull(r1.getOtherUniqueIds());
|
||||
assertNull(r1.getPreviousUsername());
|
||||
|
||||
// no change expected
|
||||
PlayerSaveResult r2 = this.storage.savePlayerData(uniqueId, "Player1");
|
||||
assertEquals(ImmutableSet.of(Outcome.NO_CHANGE), r2.getOutcomes());
|
||||
assertNull(r2.getOtherUniqueIds());
|
||||
assertNull(r2.getPreviousUsername());
|
||||
|
||||
// changed username
|
||||
PlayerSaveResult r3 = this.storage.savePlayerData(uniqueId, "Player2");
|
||||
assertEquals(ImmutableSet.of(Outcome.USERNAME_UPDATED), r3.getOutcomes());
|
||||
assertNull(r3.getOtherUniqueIds());
|
||||
assertTrue("Player1".equalsIgnoreCase(r3.getPreviousUsername()));
|
||||
|
||||
// changed uuid
|
||||
UUID newUniqueId = UUID.randomUUID();
|
||||
PlayerSaveResult r4 = this.storage.savePlayerData(newUniqueId, "Player2");
|
||||
assertEquals(ImmutableSet.of(Outcome.CLEAN_INSERT, Outcome.OTHER_UNIQUE_IDS_PRESENT_FOR_USERNAME), r4.getOutcomes());
|
||||
assertNotNull(r4.getOtherUniqueIds());
|
||||
assertEquals(ImmutableSet.of(uniqueId), r4.getOtherUniqueIds());
|
||||
assertNull(r2.getPreviousUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPlayerUniqueIdAndName() throws Exception {
|
||||
UUID uniqueId = UUID.randomUUID();
|
||||
String username = "Player1";
|
||||
|
||||
this.storage.savePlayerData(uniqueId, username);
|
||||
|
||||
assertEquals(uniqueId, this.storage.getPlayerUniqueId("Player1"));
|
||||
assertTrue(username.equalsIgnoreCase(this.storage.getPlayerName(uniqueId)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPlayerUniqueIdAndNameNull() throws Exception {
|
||||
assertNull(this.storage.getPlayerUniqueId("Player1"));
|
||||
assertNull(this.storage.getPlayerName(UUID.randomUUID()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAndLoadGroup() throws Exception {
|
||||
StandardGroupManager groupManager = new StandardGroupManager(this.plugin);
|
||||
|
||||
//noinspection unchecked,rawtypes
|
||||
lenient().when(this.plugin.getGroupManager()).thenReturn((GroupManager) groupManager);
|
||||
|
||||
Group group = this.storage.createAndLoadGroup("test");
|
||||
|
||||
group.normalData().add(Permission.builder()
|
||||
.permission("test.1")
|
||||
.withContext("server", "test")
|
||||
.build()
|
||||
);
|
||||
group.normalData().add(Permission.builder()
|
||||
.permission("test.2")
|
||||
.withContext("world", "test")
|
||||
.build()
|
||||
);
|
||||
group.normalData().add(Permission.builder()
|
||||
.permission("test.3")
|
||||
.expiry(1, TimeUnit.HOURS)
|
||||
.withContext("server", "test")
|
||||
.withContext("world", "test")
|
||||
.withContext("hello", "test")
|
||||
.build()
|
||||
);
|
||||
|
||||
Set<Node> nodes = group.normalData().asSet();
|
||||
assertEquals(3, nodes.size());
|
||||
|
||||
this.storage.saveGroup(group);
|
||||
groupManager.unload("test");
|
||||
|
||||
Group loaded = this.storage.loadGroup("test").orElse(null);
|
||||
assertNotNull(loaded);
|
||||
assertNotSame(group, loaded);
|
||||
assertEquals(nodes, loaded.normalData().asSet());
|
||||
}
|
||||
|
||||
private static class TestH2ConnectionFactory implements ConnectionFactory {
|
||||
private final NonClosableConnection connection;
|
||||
|
||||
TestH2ConnectionFactory() throws SQLException {
|
||||
this.connection = new NonClosableConnection(
|
||||
DriverManager.getConnection("jdbc:h2:mem:test")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "H2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LuckPermsPlugin plugin) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<String, String> getStatementProcessor() {
|
||||
return s -> s.replace('\'', '`')
|
||||
.replace("LIKE", "ILIKE")
|
||||
.replace("value", "`value`")
|
||||
.replace("``value``", "`value`");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws Exception {
|
||||
this.connection.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.util;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import me.lucko.luckperms.common.util.Difference.ChangeType;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class DifferenceTest {
|
||||
|
||||
@Test
|
||||
public void testSimple() {
|
||||
Difference<String> diff = new Difference<>();
|
||||
assertTrue(diff.isEmpty());
|
||||
|
||||
diff.recordChange(ChangeType.ADD, "test1");
|
||||
diff.recordChange(ChangeType.REMOVE, "test2");
|
||||
diff.recordChange(ChangeType.ADD, "test3");
|
||||
|
||||
assertEquals(ImmutableSet.of("test1", "test3"), diff.getAdded());
|
||||
assertEquals(ImmutableSet.of("test2"), diff.getRemoved());
|
||||
|
||||
assertFalse(diff.isEmpty());
|
||||
assertEquals(3, diff.getChanges().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverride() {
|
||||
Difference<String> diff = new Difference<>();
|
||||
assertTrue(diff.isEmpty());
|
||||
|
||||
diff.recordChange(ChangeType.ADD, "test1");
|
||||
diff.recordChange(ChangeType.REMOVE, "test1");
|
||||
|
||||
assertTrue(diff.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMerge() {
|
||||
Difference<String> diff = new Difference<>();
|
||||
diff.recordChange(ChangeType.ADD, "test1");
|
||||
|
||||
Difference<String> diff2 = new Difference<>();
|
||||
diff2.recordChange(ChangeType.REMOVE, "test1");
|
||||
|
||||
assertEquals(1, diff.getChanges().size());
|
||||
assertEquals(1, diff2.getChanges().size());
|
||||
|
||||
Difference<String> returnedDiff = diff.mergeFrom(diff2);
|
||||
assertSame(diff, returnedDiff);
|
||||
|
||||
assertEquals(0, diff.getChanges().size());
|
||||
assertEquals(1, diff2.getChanges().size());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.util;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.renderer.TranslatableComponentRenderer;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import net.kyori.adventure.translation.TranslationRegistry;
|
||||
import net.kyori.adventure.util.UTF8ResourceBundleControl;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DurationFormatterTest {
|
||||
|
||||
private static TranslatableComponentRenderer<Locale> renderer;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupRenderer() {
|
||||
TranslationRegistry registry = TranslationRegistry.create(Key.key("luckperms", "test"));
|
||||
|
||||
ResourceBundle bundle = ResourceBundle.getBundle("luckperms", Locale.ENGLISH, UTF8ResourceBundleControl.get());
|
||||
registry.registerAll(Locale.ENGLISH, bundle, false);
|
||||
|
||||
renderer = TranslatableComponentRenderer.usingTranslationSource(registry);
|
||||
}
|
||||
|
||||
private static String render(Component component) {
|
||||
return PlainTextComponentSerializer.plainText().serialize(renderer.render(component, Locale.ENGLISH));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testSimple() {
|
||||
Duration years = ChronoUnit.YEARS.getDuration();
|
||||
Duration months = ChronoUnit.MONTHS.getDuration();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of("1 year", years.multipliedBy(1)),
|
||||
Arguments.of("2 years", years.multipliedBy(2)),
|
||||
Arguments.of("3 years", years.multipliedBy(3)),
|
||||
Arguments.of("15 years", years.multipliedBy(15)),
|
||||
Arguments.of("1 month", months.multipliedBy(1)),
|
||||
Arguments.of("2 months", months.multipliedBy(2)),
|
||||
Arguments.of("1 week", Duration.ofDays(7)),
|
||||
Arguments.of("2 weeks", Duration.ofDays(7 * 2)),
|
||||
Arguments.of("1 day", Duration.ofDays(1)),
|
||||
Arguments.of("2 days", Duration.ofDays(2)),
|
||||
Arguments.of("1 hour", Duration.ofHours(1)),
|
||||
Arguments.of("2 hours", Duration.ofHours(2)),
|
||||
Arguments.of("15 hours", Duration.ofHours(15)),
|
||||
Arguments.of("1 minute", Duration.ofMinutes(1)),
|
||||
Arguments.of("2 minutes", Duration.ofMinutes(2)),
|
||||
Arguments.of("15 minutes", Duration.ofMinutes(15)),
|
||||
Arguments.of("1 second", Duration.ofSeconds(1)),
|
||||
Arguments.of("2 seconds", Duration.ofSeconds(2)),
|
||||
Arguments.of("15 seconds", Duration.ofSeconds(15)),
|
||||
Arguments.of("0 seconds", Duration.ZERO)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testSimple(String expected, Duration input) {
|
||||
assertEquals(expected, render(DurationFormatter.LONG.format(input)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormats() {
|
||||
Duration duration = ChronoUnit.YEARS.getDuration().multipliedBy(5)
|
||||
.plus(ChronoUnit.MONTHS.getDuration().multipliedBy(4))
|
||||
.plus(ChronoUnit.WEEKS.getDuration().multipliedBy(3))
|
||||
.plusDays(2)
|
||||
.plusHours(1)
|
||||
.plusMinutes(6)
|
||||
.plusSeconds(7);
|
||||
|
||||
assertEquals("5y 4mo 3w 2d 1h 6m 7s", render(DurationFormatter.CONCISE.format(duration)));
|
||||
assertEquals("5y 4mo 3w", render(DurationFormatter.CONCISE_LOW_ACCURACY.format(duration)));
|
||||
assertEquals("5 years 4 months 3 weeks 2 days 1 hour 6 minutes 7 seconds", render(DurationFormatter.LONG.format(duration)));
|
||||
}
|
||||
|
||||
}
|
@ -25,82 +25,100 @@
|
||||
|
||||
package me.lucko.luckperms.common.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class DurationParserTest {
|
||||
|
||||
private static void test(Duration expected, String input) {
|
||||
private static Stream<Arguments> testSimple() {
|
||||
Duration years = ChronoUnit.YEARS.getDuration();
|
||||
Duration months = ChronoUnit.MONTHS.getDuration();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of("2y", years.multipliedBy(2)),
|
||||
Arguments.of("3year", years.multipliedBy(3)),
|
||||
Arguments.of("4years", years.multipliedBy(4)),
|
||||
Arguments.of("2 y", years.multipliedBy(2)),
|
||||
Arguments.of("3 year", years.multipliedBy(3)),
|
||||
Arguments.of("4 years", years.multipliedBy(4)),
|
||||
|
||||
Arguments.of("2mo", months.multipliedBy(2)),
|
||||
Arguments.of("3month", months.multipliedBy(3)),
|
||||
Arguments.of("4months", months.multipliedBy(4)),
|
||||
Arguments.of("2 mo", months.multipliedBy(2)),
|
||||
Arguments.of("3 month", months.multipliedBy(3)),
|
||||
Arguments.of("4 months", months.multipliedBy(4)),
|
||||
|
||||
Arguments.of("2w", Duration.ofDays(7 * 2)),
|
||||
Arguments.of("3week", Duration.ofDays(7 * 3)),
|
||||
Arguments.of("4weeks", Duration.ofDays(7 * 4)),
|
||||
Arguments.of("2 w", Duration.ofDays(7 * 2)),
|
||||
Arguments.of("3 week", Duration.ofDays(7 * 3)),
|
||||
Arguments.of("4 weeks", Duration.ofDays(7 * 4)),
|
||||
|
||||
Arguments.of("2d", Duration.ofDays(2)),
|
||||
Arguments.of("3day", Duration.ofDays(3)),
|
||||
Arguments.of("4days", Duration.ofDays(4)),
|
||||
Arguments.of("2 d", Duration.ofDays(2)),
|
||||
Arguments.of("3 day", Duration.ofDays(3)),
|
||||
Arguments.of("4 days", Duration.ofDays(4)),
|
||||
|
||||
Arguments.of("2h", Duration.ofHours(2)),
|
||||
Arguments.of("3hour", Duration.ofHours(3)),
|
||||
Arguments.of("4hours", Duration.ofHours(4)),
|
||||
Arguments.of("2 h", Duration.ofHours(2)),
|
||||
Arguments.of("3 hour", Duration.ofHours(3)),
|
||||
Arguments.of("4 hours", Duration.ofHours(4)),
|
||||
|
||||
Arguments.of("2m", Duration.ofMinutes(2)),
|
||||
Arguments.of("3min", Duration.ofMinutes(3)),
|
||||
Arguments.of("4mins", Duration.ofMinutes(4)),
|
||||
Arguments.of("5minute", Duration.ofMinutes(5)),
|
||||
Arguments.of("6minutes", Duration.ofMinutes(6)),
|
||||
Arguments.of("2 m", Duration.ofMinutes(2)),
|
||||
Arguments.of("3 min", Duration.ofMinutes(3)),
|
||||
Arguments.of("4 mins", Duration.ofMinutes(4)),
|
||||
Arguments.of("5 minute", Duration.ofMinutes(5)),
|
||||
Arguments.of("6 minutes", Duration.ofMinutes(6)),
|
||||
|
||||
Arguments.of("2s", Duration.ofSeconds(2)),
|
||||
Arguments.of("3sec", Duration.ofSeconds(3)),
|
||||
Arguments.of("4secs", Duration.ofSeconds(4)),
|
||||
Arguments.of("5second", Duration.ofSeconds(5)),
|
||||
Arguments.of("6seconds", Duration.ofSeconds(6)),
|
||||
Arguments.of("2 s", Duration.ofSeconds(2)),
|
||||
Arguments.of("3 sec", Duration.ofSeconds(3)),
|
||||
Arguments.of("4 secs", Duration.ofSeconds(4)),
|
||||
Arguments.of("5 second", Duration.ofSeconds(5)),
|
||||
Arguments.of("6 seconds", Duration.ofSeconds(6))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testSimple(String input, Duration expected) {
|
||||
assertEquals(expected, DurationParser.parseDuration(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(2), "2y");
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(3), "3year");
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(4), "4years");
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(2), "2 y");
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(3), "3 year");
|
||||
test(ChronoUnit.YEARS.getDuration().multipliedBy(4), "4 years");
|
||||
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(2), "2mo");
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(3), "3month");
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(4), "4months");
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(2), "2 mo");
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(3), "3 month");
|
||||
test(ChronoUnit.MONTHS.getDuration().multipliedBy(4), "4 months");
|
||||
|
||||
test(Duration.ofDays(7 * 2), "2w");
|
||||
test(Duration.ofDays(7 * 3), "3week");
|
||||
test(Duration.ofDays(7 * 4), "4weeks");
|
||||
test(Duration.ofDays(7 * 2), "2 w");
|
||||
test(Duration.ofDays(7 * 3), "3 week");
|
||||
test(Duration.ofDays(7 * 4), "4 weeks");
|
||||
|
||||
test(Duration.ofDays(2), "2d");
|
||||
test(Duration.ofDays(3), "3day");
|
||||
test(Duration.ofDays(4), "4days");
|
||||
test(Duration.ofDays(2), "2 d");
|
||||
test(Duration.ofDays(3), "3 day");
|
||||
test(Duration.ofDays(4), "4 days");
|
||||
|
||||
test(Duration.ofHours(2), "2h");
|
||||
test(Duration.ofHours(3), "3hour");
|
||||
test(Duration.ofHours(4), "4hours");
|
||||
test(Duration.ofHours(2), "2 h");
|
||||
test(Duration.ofHours(3), "3 hour");
|
||||
test(Duration.ofHours(4), "4 hours");
|
||||
|
||||
test(Duration.ofMinutes(2), "2m");
|
||||
test(Duration.ofMinutes(3), "3min");
|
||||
test(Duration.ofMinutes(4), "4mins");
|
||||
test(Duration.ofMinutes(5), "5minute");
|
||||
test(Duration.ofMinutes(6), "6minutes");
|
||||
test(Duration.ofMinutes(2), "2 m");
|
||||
test(Duration.ofMinutes(3), "3 min");
|
||||
test(Duration.ofMinutes(4), "4 mins");
|
||||
test(Duration.ofMinutes(5), "5 minute");
|
||||
test(Duration.ofMinutes(6), "6 minutes");
|
||||
|
||||
test(Duration.ofSeconds(2), "2s");
|
||||
test(Duration.ofSeconds(3), "3sec");
|
||||
test(Duration.ofSeconds(4), "4secs");
|
||||
test(Duration.ofSeconds(5), "5second");
|
||||
test(Duration.ofSeconds(6), "6seconds");
|
||||
test(Duration.ofSeconds(2), "2 s");
|
||||
test(Duration.ofSeconds(3), "3 sec");
|
||||
test(Duration.ofSeconds(4), "4 secs");
|
||||
test(Duration.ofSeconds(5), "5 second");
|
||||
test(Duration.ofSeconds(6), "6 seconds");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCombined() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"5y 4mo 3w 2d 1h 6m 7s",
|
||||
"5y4mo3w2d1h6m7s",
|
||||
"5 years 4 months 3 weeks 2 days 1 hour 6 minutes 7 seconds",
|
||||
"5y, 4mo, 3w, 2d, 1h, 6m, 7s",
|
||||
"5y,4mo,3w,2d,1h,6m,7s",
|
||||
"5 years, 4 months, 3 weeks, 2 days, 1 hour, 6 minutes, 7 seconds"
|
||||
})
|
||||
public void testCombined(String input) {
|
||||
Duration expected = ChronoUnit.YEARS.getDuration().multipliedBy(5)
|
||||
.plus(ChronoUnit.MONTHS.getDuration().multipliedBy(4))
|
||||
.plus(ChronoUnit.WEEKS.getDuration().multipliedBy(3))
|
||||
@ -109,20 +127,17 @@ public class DurationParserTest {
|
||||
.plusMinutes(6)
|
||||
.plusSeconds(7);
|
||||
|
||||
test(expected, "5y 4mo 3w 2d 1h 6m 7s");
|
||||
test(expected, "5y4mo3w2d1h6m7s");
|
||||
test(expected, "5 years 4 months 3 weeks 2 days 1 hour 6 minutes 7 seconds");
|
||||
|
||||
test(expected, "5y, 4mo, 3w, 2d, 1h, 6m, 7s");
|
||||
test(expected, "5y,4mo,3w,2d,1h,6m,7s");
|
||||
test(expected, "5 years, 4 months, 3 weeks, 2 days, 1 hour, 6 minutes, 7 seconds");
|
||||
assertEquals(expected, DurationParser.parseDuration(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFail() {
|
||||
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("definitely not a duration"));
|
||||
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("still 1 not a duration"));
|
||||
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("still 1s not a duration"));
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"definitely not a duration",
|
||||
"still 1 not a duration",
|
||||
"still 1s not a duration"
|
||||
})
|
||||
public void testFail(String input) {
|
||||
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration(input));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
public class EnumNamerTest {
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
public void testSimple() {
|
||||
EnumNamer<TestEnum> namer = new EnumNamer<>(
|
||||
TestEnum.class,
|
||||
ImmutableMap.of(TestEnum.THING, "hi"),
|
||||
|
@ -36,12 +36,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
public class IteratorsTest {
|
||||
|
||||
@Test
|
||||
void testDivideEmpty() {
|
||||
public void testDivideEmpty() {
|
||||
assertEquals(ImmutableList.of(), Iterators.divideIterable(ImmutableList.of(), 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDivideSimple() {
|
||||
public void testDivideSimple() {
|
||||
List<List<String>> expected = ImmutableList.of(
|
||||
ImmutableList.of("one", "two"),
|
||||
ImmutableList.of("three", "four"),
|
||||
@ -57,7 +57,7 @@ public class IteratorsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDivideBoundary() {
|
||||
public void testDivideBoundary() {
|
||||
List<List<String>> expected = ImmutableList.of(
|
||||
ImmutableList.of("one", "two"),
|
||||
ImmutableList.of("three", "four")
|
||||
|
@ -27,44 +27,79 @@ package me.lucko.luckperms.common.util;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class PaginatedTest {
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
Paginated<String> paginated = new Paginated<>(ImmutableList.of("one", "two", "three", "four", "five"));
|
||||
assertEquals(3, paginated.getMaxPages(2));
|
||||
assertEquals(1, paginated.getMaxPages(5));
|
||||
assertEquals(1, paginated.getMaxPages(6));
|
||||
private static final Paginated<String> EXAMPLE_PAGE = new Paginated<>(ImmutableList.of("one", "two", "three", "four", "five"));
|
||||
|
||||
List<Paginated.Entry<String>> page1 = paginated.getPage(1, 2);
|
||||
assertEquals(2, page1.size());
|
||||
assertEquals("one", page1.get(0).value());
|
||||
assertEquals(1, page1.get(0).position());
|
||||
assertEquals("two", page1.get(1).value());
|
||||
assertEquals(2, page1.get(1).position());
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"3, 2",
|
||||
"1, 5",
|
||||
"1, 6"
|
||||
})
|
||||
public void testMaxPages(int expected, int entriesPerPage) {
|
||||
assertEquals(expected, EXAMPLE_PAGE.getMaxPages(entriesPerPage));
|
||||
}
|
||||
|
||||
List<Paginated.Entry<String>> page2 = paginated.getPage(2, 2);
|
||||
assertEquals(2, page2.size());
|
||||
assertEquals("three", page2.get(0).value());
|
||||
assertEquals(3, page2.get(0).position());
|
||||
assertEquals("four", page2.get(1).value());
|
||||
assertEquals(4, page2.get(1).position());
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"1, 2",
|
||||
"2, 2",
|
||||
"3, 1"
|
||||
})
|
||||
public void testPageSize(int pageNo, int expectedSize) {
|
||||
List<Paginated.Entry<String>> page = EXAMPLE_PAGE.getPage(pageNo, 2);
|
||||
assertEquals(expectedSize, page.size());
|
||||
}
|
||||
|
||||
List<Paginated.Entry<String>> page3 = paginated.getPage(3, 2);
|
||||
assertEquals(1, page3.size());
|
||||
assertEquals("five", page3.get(0).value());
|
||||
assertEquals(5, page3.get(0).position());
|
||||
private static Stream<Arguments> testPageContent() {
|
||||
return Stream.of(
|
||||
Arguments.of(1, ImmutableList.of(
|
||||
new Paginated.Entry<>(1, "one"),
|
||||
new Paginated.Entry<>(2, "two")
|
||||
)),
|
||||
Arguments.of(2, ImmutableList.of(
|
||||
new Paginated.Entry<>(3, "three"),
|
||||
new Paginated.Entry<>(4, "four")
|
||||
)),
|
||||
Arguments.of(3, ImmutableList.of(
|
||||
new Paginated.Entry<>(5, "five")
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> paginated.getPage(4, 2));
|
||||
assertThrows(IllegalArgumentException.class, () -> paginated.getPage(0, 2));
|
||||
assertThrows(IllegalArgumentException.class, () -> paginated.getPage(-1, 2));
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPageContent(int pageNo, List<Paginated.Entry<String>> expectedContent) {
|
||||
assertEquals(expectedContent, EXAMPLE_PAGE.getPage(pageNo, 2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"4, 2",
|
||||
})
|
||||
public void testFailState(int pageNo, int pageSize) {
|
||||
assertThrows(IllegalStateException.class, () -> EXAMPLE_PAGE.getPage(pageNo, pageSize));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"0, 2",
|
||||
"-1, 2"
|
||||
})
|
||||
public void testFailArgument(int pageNo, int pageSize) {
|
||||
assertThrows(IllegalArgumentException.class, () -> EXAMPLE_PAGE.getPage(pageNo, pageSize));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.util;
|
||||
|
||||
import me.lucko.luckperms.common.event.EventDispatcher;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.AdditionalAnswers.returnsSecondArg;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UniqueIdTypeTest {
|
||||
|
||||
@Mock private LuckPermsPlugin plugin;
|
||||
@Mock private EventDispatcher dispatcher;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() {
|
||||
when(this.plugin.getEventDispatcher()).thenReturn(this.dispatcher);
|
||||
when(this.dispatcher.dispatchUniqueIdDetermineType(any(), anyString())).then(returnsSecondArg());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"797a99ba-c040-4f04-8cfc-6b01a4890d2f, authenticated",
|
||||
"5d41402a-bc4b-3a76-b971-9d911017c592, unauthenticated",
|
||||
"cfa4fcb1-a786-23fc-b956-33914c7bb373, npc",
|
||||
"00000000-0000-0000-0000-000000000000, unknown"
|
||||
})
|
||||
public void testParse(UUID uuid, String expectedType) {
|
||||
UniqueIdType uniqueIdType = UniqueIdType.determineType(uuid, this.plugin);
|
||||
assertEquals(expectedType, uniqueIdType.getType());
|
||||
}
|
||||
|
||||
}
|
@ -26,28 +26,35 @@
|
||||
package me.lucko.luckperms.common.verbose;
|
||||
|
||||
import me.lucko.luckperms.common.verbose.expression.BooleanExpressionCompiler;
|
||||
import me.lucko.luckperms.common.verbose.expression.BooleanExpressionCompiler.VariableEvaluator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BooleanExpressionTest {
|
||||
|
||||
private static void test(String expression, boolean expected) {
|
||||
assertEquals(
|
||||
expected,
|
||||
BooleanExpressionCompiler.compile(expression).eval(var -> var.equals("true")),
|
||||
expression + " is not " + expected
|
||||
);
|
||||
private static final VariableEvaluator STRING_EVAL = var -> var.equals("true");
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"false & false | true",
|
||||
"true | false & false",
|
||||
"(true & ((true | false) & !(true & false)))"
|
||||
})
|
||||
public void testEvaluatesTrue(String expression) {
|
||||
assertTrue(BooleanExpressionCompiler.compile(expression).eval(STRING_EVAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBrackets() {
|
||||
test("false & false | true", true);
|
||||
test("false & (false | true)", false);
|
||||
test("true | false & false", true);
|
||||
test("(true | false) & false", false);
|
||||
test("(true & ((true | false) & !(true & false)))", true);
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"false & (false | true)",
|
||||
"(true | false) & false"
|
||||
})
|
||||
public void testEvaluatesFalse(String expression) {
|
||||
assertFalse(BooleanExpressionCompiler.compile(expression).eval(STRING_EVAL));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.verbose;
|
||||
|
||||
import me.lucko.luckperms.common.cacheddata.result.StringResult;
|
||||
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsImpl;
|
||||
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
|
||||
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
|
||||
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
|
||||
|
||||
import net.luckperms.api.util.Tristate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class VerboseFilterTest {
|
||||
|
||||
@Test
|
||||
public void testAcceptAll() {
|
||||
VerboseFilter filter = VerboseFilter.acceptAll();
|
||||
assertTrue(filter.isBlank());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"luckperms, true",
|
||||
"luckperms.user, true",
|
||||
"luckperms.group, false",
|
||||
"Player1, true",
|
||||
"Player2, false",
|
||||
"luckperms & Player1, true",
|
||||
"permission & luckperms & Player1, true",
|
||||
"permission & luckperms & Player1 & true, true",
|
||||
"luckperms & Player2, false",
|
||||
"luckperms | test, true"
|
||||
})
|
||||
public void testPermissionEvent(String expression, boolean expected) throws InvalidFilterException {
|
||||
VerboseFilter filter = VerboseFilter.compile(expression);
|
||||
assertFalse(filter.isBlank());
|
||||
|
||||
PermissionCheckEvent relevantEvent = new PermissionCheckEvent(
|
||||
CheckOrigin.INTERNAL,
|
||||
VerboseCheckTarget.of(VerboseCheckTarget.USER_TYPE, "Player1"),
|
||||
QueryOptionsImpl.DEFAULT_CONTEXTUAL,
|
||||
System.currentTimeMillis(),
|
||||
new Throwable(),
|
||||
"test",
|
||||
"luckperms.user.parent.info",
|
||||
TristateResult.forMonitoredResult(Tristate.TRUE)
|
||||
);
|
||||
|
||||
PermissionCheckEvent nonRelevantEvent = new PermissionCheckEvent(
|
||||
CheckOrigin.INTERNAL,
|
||||
VerboseCheckTarget.of(VerboseCheckTarget.USER_TYPE, "aaaaaaa"),
|
||||
QueryOptionsImpl.DEFAULT_CONTEXTUAL,
|
||||
System.currentTimeMillis(),
|
||||
new Throwable(),
|
||||
"test",
|
||||
"aaaaaaaaa",
|
||||
TristateResult.forMonitoredResult(Tristate.FALSE)
|
||||
);
|
||||
|
||||
assertEquals(expected, filter.evaluate(relevantEvent));
|
||||
assertFalse(filter.evaluate(nonRelevantEvent));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"nametags, true",
|
||||
"nametags.nametag, true",
|
||||
"nametags.other, false",
|
||||
"Player1, true",
|
||||
"Player2, false",
|
||||
"nametags & Player1, true",
|
||||
"meta & nametags & Player1, true",
|
||||
"meta & nametags & Player1 & admin, true",
|
||||
"nametags & Player2, false",
|
||||
"nametags | test, true"
|
||||
})
|
||||
public void testMetaEvent(String expression, boolean expected) throws InvalidFilterException {
|
||||
VerboseFilter filter = VerboseFilter.compile(expression);
|
||||
assertFalse(filter.isBlank());
|
||||
|
||||
MetaCheckEvent relevantEvent = new MetaCheckEvent(
|
||||
CheckOrigin.INTERNAL,
|
||||
VerboseCheckTarget.of(VerboseCheckTarget.USER_TYPE, "Player1"),
|
||||
QueryOptionsImpl.DEFAULT_CONTEXTUAL,
|
||||
System.currentTimeMillis(),
|
||||
new Throwable(),
|
||||
"test",
|
||||
"nametags.nametag",
|
||||
StringResult.of("ADMIN")
|
||||
);
|
||||
|
||||
MetaCheckEvent nonRelevantEvent = new MetaCheckEvent(
|
||||
CheckOrigin.INTERNAL,
|
||||
VerboseCheckTarget.of(VerboseCheckTarget.USER_TYPE, "aaaaaaa"),
|
||||
QueryOptionsImpl.DEFAULT_CONTEXTUAL,
|
||||
System.currentTimeMillis(),
|
||||
new Throwable(),
|
||||
"test",
|
||||
"aaaaaaaaa",
|
||||
StringResult.of("aaaaaa")
|
||||
);
|
||||
|
||||
assertEquals(expected, filter.evaluate(relevantEvent));
|
||||
assertFalse(filter.evaluate(nonRelevantEvent));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
mock-maker-inline
|
Loading…
Reference in New Issue
Block a user