Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables permissions to set how many islands a play can create. #2201

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.eclipse.jdt.annotation.Nullable;

import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.user.User;
Expand Down Expand Up @@ -48,12 +49,11 @@ public boolean canExecute(User user, String label, List<String> args) {
if (island.isReserved()) {
return true;
}
// Get how many islands this player has
int num = this.getIslands().getNumberOfConcurrentIslands(user.getUniqueId(), getWorld());
int max = this.getIWM().getWorldSettings(getWorld()).getConcurrentIslands();
if (num < max) {
return true;
}
}
// Get how many islands this player has
int num = this.getIslands().getNumberOfConcurrentIslands(user.getUniqueId(), getWorld());
int max = user.getPermissionValue(this.getIWM().getAddon(getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.number", this.getIWM().getWorldSettings(getWorld()).getConcurrentIslands());
if (num >= max) {
// You cannot make an island
user.sendMessage("general.errors.you-cannot-make");
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import org.eclipse.jdt.annotation.Nullable;

import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent;
Expand Down Expand Up @@ -64,7 +65,9 @@ public boolean canExecute(User user, String label, List<String> args) {
return false;
}
// Check how many islands target has
if (getIslands().getNumberOfConcurrentIslands(targetUUID, getWorld()) >= this.getIWM().getWorldSettings(getWorld()).getConcurrentIslands()) {
int num = getIslands().getNumberOfConcurrentIslands(targetUUID, getWorld());
int max = user.getPermissionValue(this.getIWM().getAddon(getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.number", this.getIWM().getWorldSettings(getWorld()).getConcurrentIslands());
if (num >= max) {
// Too many
user.sendMessage("commands.island.team.setowner.errors.at-max");
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
Expand All @@ -13,6 +15,7 @@
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
Expand Down Expand Up @@ -106,15 +109,17 @@ public void setUp() throws Exception {
UUID uuid = UUID.randomUUID();
when(user.getUniqueId()).thenReturn(uuid);
when(user.getPlayer()).thenReturn(player);
when(user.hasPermission(Mockito.anyString())).thenReturn(true);
when(user.getTranslation(Mockito.any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
when(user.hasPermission(anyString())).thenReturn(true);
when(user.getTranslation(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Return the default value for perm questions by default
when(user.getPermissionValue(anyString(), anyInt())).thenAnswer((Answer<Integer>) inv -> inv.getArgument(1, Integer.class));
User.setPlugin(plugin);
// Set up user already
User.getInstance(player);

// Addon
GameModeAddon addon = mock(GameModeAddon.class);

when(addon.getPermissionPrefix()).thenReturn("bskyblock.");

// Parent command has no aliases
when(ic.getSubCommandAliases()).thenReturn(new HashMap<>());
Expand Down Expand Up @@ -144,10 +149,11 @@ public void setUp() throws Exception {
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(sch);

// IWM friendly name
// IWM
when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock");
when(ws.getConcurrentIslands()).thenReturn(1); // One island allowed
when(iwm.getWorldSettings(world)).thenReturn(ws);
when(iwm.getAddon(world)).thenReturn(Optional.of(addon));
when(plugin.getIWM()).thenReturn(iwm);

// NewIsland
Expand Down Expand Up @@ -209,27 +215,53 @@ public void testCanExecuteUserStringListOfStringHasIsland() {
verify(user).sendMessage("general.errors.you-cannot-make");
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testCanExecuteUserStringListOfStringZeroAllowed() {
when(ws.getConcurrentIslands()).thenReturn(0); // No islands allowed
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
verify(user).sendMessage("general.errors.you-cannot-make");

}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testCanExecuteUserStringListOfStringHasPerm() {
// Currently user has two islands
when(im.getNumberOfConcurrentIslands(user.getUniqueId(), world)).thenReturn(19);
// Perm
when(user.getPermissionValue(anyString(), anyInt())).thenReturn(20); // 20 allowed!
assertTrue(cc.canExecute(user, "", Collections.emptyList()));
verify(user, never()).sendMessage(anyString());
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testCanExecuteUserStringListOfStringHasIslandReserved() {
@Nullable
Island island = mock(Island.class);
when(im.getIsland(any(), Mockito.any(User.class))).thenReturn(island);
when(im.getIsland(any(), any(User.class))).thenReturn(island);
when(island.isReserved()).thenReturn(true);
assertTrue(cc.canExecute(user, "", Collections.emptyList()));
verify(user, never()).sendMessage("general.errors.already-have-island");

}



/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testCanExecuteUserStringListOfStringTooManyIslands() {
when(im.getPrimaryIsland(any(), Mockito.any(UUID.class))).thenReturn(null);
when(im.inTeam(any(), Mockito.any(UUID.class))).thenReturn(false);
when(im.getPrimaryIsland(any(), any(UUID.class))).thenReturn(null);
when(im.inTeam(any(), any(UUID.class))).thenReturn(false);
when(iwm.getMaxIslands(any())).thenReturn(100);
when(im.getIslandCount(any())).thenReturn(100L);
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
Expand All @@ -247,7 +279,7 @@ public void testExecuteUserStringListOfStringSuccess() throws Exception {
// Has permission
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);

assertTrue(cc.execute(user, "", Collections.singletonList("custom")));
assertTrue(cc.execute(user, "", List.of("custom")));
verify(builder).player(eq(user));
verify(builder).addon(any());
verify(builder).reason(eq(Reason.CREATE));
Expand All @@ -267,7 +299,7 @@ public void testExecuteUserStringListOfStringThrowException() throws Exception {
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);

when(builder.build()).thenThrow(new IOException("commands.island.create.unable-create-island"));
assertFalse(cc.execute(user, "", Collections.singletonList("custom")));
assertFalse(cc.execute(user, "", List.of("custom")));
verify(user).sendMessage("commands.island.create.creating-island");
verify(user).sendMessage("commands.island.create.unable-create-island");
verify(plugin).logError("Could not create island for player. commands.island.create.unable-create-island");
Expand All @@ -291,7 +323,7 @@ public void testExecuteUserStringListOfStringBundleNoPermission() {
*/
@Test
public void testExecuteUserStringListOfStringUnknownBundle() {
assertFalse(cc.execute(user, "", Collections.singletonList("custom")));
assertFalse(cc.execute(user, "", List.of("custom")));
verify(user).sendMessage(eq("commands.island.create.unknown-blueprint"));
verify(user, never()).sendMessage("commands.island.create.creating-island");
}
Expand Down Expand Up @@ -347,10 +379,9 @@ public void testExecuteUserStringListOfStringNoCooldown() {
*/
@Test
public void testExecuteUserStringListOfStringShowPanel() {
Map<String, BlueprintBundle> map = new HashMap<>();
map.put("bundle1", new BlueprintBundle());
map.put("bundle2", new BlueprintBundle());
map.put("bundle3", new BlueprintBundle());
Map<String, BlueprintBundle> map = Map.of("bundle1", new BlueprintBundle(),
"bundle2", new BlueprintBundle(),
"bundle3", new BlueprintBundle());
when(bpm.getBlueprintBundles(any())).thenReturn(map);
assertTrue(cc.execute(user, "", Collections.emptyList()));
// Panel is shown, not the creation message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
Expand All @@ -14,6 +15,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import org.bukkit.Bukkit;
Expand All @@ -29,6 +31,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
Expand Down Expand Up @@ -98,6 +101,8 @@ public void setUp() throws Exception {
when(user.getUniqueId()).thenReturn(uuid);
when(user.getPlayer()).thenReturn(player);
when(user.getName()).thenReturn("tastybento");
// Return the default value for perm questions by default
when(user.getPermissionValue(anyString(), anyInt())).thenAnswer((Answer<Integer>) inv -> inv.getArgument(1, Integer.class));

// Parent command has no aliases
ic = mock(CompositeCommand.class);
Expand Down Expand Up @@ -196,7 +201,7 @@ public void testCanExecuteUserStringListOfStringNotOwner() {
public void testCanExecuteUserStringListOfStringShowHelp() {
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
assertFalse(its.canExecute(user, "", Collections.emptyList()));
assertFalse(its.canExecute(user, "", List.of()));
verify(user).sendMessage("commands.help.header","[label]", null);
}

Expand All @@ -208,7 +213,7 @@ public void testCanExecuteUserStringListOfStringUnknownPlayer() {
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
when(pm.getUUID(anyString())).thenReturn(null);
assertFalse(its.canExecute(user, "", Collections.singletonList("tastybento")));
assertFalse(its.canExecute(user, "", List.of("tastybento")));
verify(user).sendMessage("general.errors.unknown-player", TextVariables.NAME, "tastybento");
}

Expand All @@ -220,7 +225,7 @@ public void testCanExecuteUserStringListOfStringSamePlayer() {
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
when(pm.getUUID(anyString())).thenReturn(uuid);
assertFalse(its.canExecute(user, "", Collections.singletonList("tastybento")));
assertFalse(its.canExecute(user, "", List.of("tastybento")));
verify(user).sendMessage("commands.island.team.setowner.errors.cant-transfer-to-yourself");
}

Expand All @@ -233,14 +238,14 @@ public void testCanExecuteUserStringListOfStringTargetAtMaxIslands() {
when(im.getOwner(any(), any())).thenReturn(uuid);
UUID target = UUID.randomUUID();
when(pm.getUUID(anyString())).thenReturn(target);
when(im.getMembers(any(), any())).thenReturn(Collections.singleton(target));
when(im.getMembers(any(), any())).thenReturn(Set.of(target));
@Nullable
Island island = mock(Island.class);
when(im.getIsland(any(), any(User.class))).thenReturn(island);

when(im.getNumberOfConcurrentIslands(target, world)).thenReturn(3);

assertFalse(its.canExecute(user, "", Collections.singletonList("tastybento")));
assertFalse(its.canExecute(user, "", List.of("tastybento")));
verify(user).sendMessage("commands.island.team.setowner.errors.at-max");
}

Expand All @@ -252,11 +257,50 @@ public void testCanExecuteUserStringListOfStringTargetNotInTeam() {
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
when(pm.getUUID(anyString())).thenReturn(UUID.randomUUID());
when(im.getMembers(any(), any())).thenReturn(Collections.singleton(uuid));
assertFalse(its.canExecute(user, "", Collections.singletonList("tastybento")));
when(im.getMembers(any(), any())).thenReturn(Set.of(uuid));
assertFalse(its.canExecute(user, "", List.of("tastybento")));
verify(user).sendMessage("commands.island.team.setowner.errors.target-is-not-member");
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringTooManyConcurrent() {
when(im.getNumberOfConcurrentIslands(any(), eq(world))).thenReturn(20);
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
UUID target = UUID.randomUUID();
when(pm.getUUID(anyString())).thenReturn(target);
when(im.getMembers(any(), any())).thenReturn(Set.of(target));
@Nullable
Island island = mock(Island.class);
when(im.getIsland(any(), any(User.class))).thenReturn(island);
assertFalse(its.canExecute(user, "", List.of("tastybento")));
verify(user).sendMessage("commands.island.team.setowner.errors.at-max");
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringHasManyConcurrentAndPerm() {
when(user.getPermissionValue(anyString(), anyInt())).thenReturn(40);
when(im.getNumberOfConcurrentIslands(any(), eq(world))).thenReturn(20);
when(im.inTeam(any(), any())).thenReturn(true);
when(im.getOwner(any(), any())).thenReturn(uuid);
UUID target = UUID.randomUUID();
when(pm.getUUID(anyString())).thenReturn(target);
when(im.getMembers(any(), any())).thenReturn(Set.of(target));
@Nullable
Island island = mock(Island.class);
when(im.getIsland(any(), any(User.class))).thenReturn(island);
assertTrue(its.canExecute(user, "", List.of("tastybento")));
assertTrue(its.execute(user, "", List.of("tastybento")));
verify(im).setOwner(any(), eq(user), eq(target));
verify(im).save(island);
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
Expand All @@ -266,12 +310,12 @@ public void testExecuteUserStringListOfStringSuccess() {
when(im.getOwner(any(), any())).thenReturn(uuid);
UUID target = UUID.randomUUID();
when(pm.getUUID(anyString())).thenReturn(target);
when(im.getMembers(any(), any())).thenReturn(Collections.singleton(target));
when(im.getMembers(any(), any())).thenReturn(Set.of(target));
@Nullable
Island island = mock(Island.class);
when(im.getIsland(any(), any(User.class))).thenReturn(island);
assertTrue(its.canExecute(user, "", Collections.singletonList("tastybento")));
assertTrue(its.execute(user, "", Collections.singletonList("tastybento")));
assertTrue(its.canExecute(user, "", List.of("tastybento")));
assertTrue(its.execute(user, "", List.of("tastybento")));
verify(im).setOwner(any(), eq(user), eq(target));
verify(im).save(island);
}
Expand All @@ -281,15 +325,15 @@ public void testExecuteUserStringListOfStringSuccess() {
*/
@Test
public void testTabCompleteUserStringListOfString() {
assertTrue(its.tabComplete(user, "", Collections.emptyList()).get().isEmpty());
assertTrue(its.tabComplete(user, "", List.of()).get().isEmpty());
}

/**
* Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testTabCompleteUserStringListOfStringUnknown() {
assertTrue(its.tabComplete(user, "ta", Collections.emptyList()).get().isEmpty());
assertTrue(its.tabComplete(user, "ta", List.of()).get().isEmpty());
}

/**
Expand All @@ -299,8 +343,8 @@ public void testTabCompleteUserStringListOfStringUnknown() {
public void testTabCompleteUserStringListOfStringMember() {
UUID target = UUID.randomUUID();
when(pm.getName(any())).thenReturn("tastybento");
when(im.getMembers(any(), any())).thenReturn(Collections.singleton(target));
assertEquals("tastybento", its.tabComplete(user, "", Collections.emptyList()).get().get(0));
when(im.getMembers(any(), any())).thenReturn(Set.of(target));
assertEquals("tastybento", its.tabComplete(user, "", List.of()).get().get(0));
}

}