Skip to content
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>1.26.2</build.version>
<build.version>1.26.3</build.version>
<!-- SonarCloud -->
<sonar.projectKey>BentoBoxWorld_AOneBlock</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/world/bentobox/aoneblock/panels/PhasesPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -539,13 +539,30 @@ private boolean canApplyPhase(OneBlockPhase phase)
{
return false;
}
if (!this.hasSetCountPermission())
{
return false;
}
if (phase.getBlockNumberValue() >= this.oneBlockIsland.getLifetime())
{
return false;
}
return !this.phaseRequirementsFail(phase, this.oneBlockIsland);
}

/**
* Checks that the player holds the permission of the setcount command that a phase
* click runs, so the "click to change" action is only offered when it can succeed.
*/
private boolean hasSetCountPermission()
{
String label = this.addon.getSettings().getSetCountCommand().split(" ")[0];
return this.addon.getPlayerCommand()
.flatMap(mainCommand -> mainCommand.getSubCommand(label))
.map(subCommand -> this.user.hasPermission(subCommand.getPermission()))
.orElse(true);
}

/**
* Builds the click handler for a phase button.
*/
Expand Down
79 changes: 79 additions & 0 deletions src/test/java/world/bentobox/aoneblock/panels/PhasesPanelTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import world.bentobox.bank.Bank;
import world.bentobox.bank.BankManager;
import world.bentobox.bank.data.Money;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.panels.TemplatedPanel;
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord;
import world.bentobox.bentobox.api.user.User;
Expand Down Expand Up @@ -554,6 +555,84 @@ void testCanApplyPhaseSuccess() throws Exception {
assertTrue(result);
}

/**
* Test canApplyPhase returns false when the player lacks the setcount command
* permission — the "click to change" action must not be offered.
*/
@Test
void testCanApplyPhaseNoSetCountPermission() throws Exception {
setUpAddonMocks();
Island testIsland = new Island();
testIsland.setOwner(uuid);
OneBlockIslands oneBlockIsland = new OneBlockIslands(testIsland.getUniqueId());
oneBlockIsland.setLifetime(100L);
oneBlockIsland.setLastPhaseChangeTime(System.currentTimeMillis());

User user = User.getInstance(mockPlayer);
when(im.getIsland(world, user)).thenReturn(testIsland);
when(blockListener.getIsland(testIsland)).thenReturn(oneBlockIsland);
when(oneBlockManager.getBlockProbs()).thenReturn(createBlockProbs());

// The setcount command exists and carries a permission the player does not have
CompositeCommand mainCommand = mock(CompositeCommand.class);
CompositeCommand setCountCommand = mock(CompositeCommand.class);
when(mainCommand.getSubCommand("setcount")).thenReturn(Optional.of(setCountCommand));
when(setCountCommand.getPermission()).thenReturn("aoneblock.island.setcount");
when(addon.getPlayerCommand()).thenReturn(Optional.of(mainCommand));
when(mockPlayer.hasPermission("aoneblock.island.setcount")).thenReturn(false);

Constructor<PhasesPanel> constructor = PhasesPanel.class.getDeclaredConstructor(AOneBlock.class, World.class, User.class);
constructor.setAccessible(true);
panel = constructor.newInstance(addon, world, user);

OneBlockPhase phase = createTestPhase("Plains");

Method method = PhasesPanel.class.getDeclaredMethod("canApplyPhase", OneBlockPhase.class);
method.setAccessible(true);

boolean result = (boolean) method.invoke(panel, phase);

assertFalse(result);
}

/**
* Test canApplyPhase returns true when the player holds the setcount permission.
*/
@Test
void testCanApplyPhaseWithSetCountPermission() throws Exception {
setUpAddonMocks();
Island testIsland = new Island();
testIsland.setOwner(uuid);
OneBlockIslands oneBlockIsland = new OneBlockIslands(testIsland.getUniqueId());
oneBlockIsland.setLifetime(100L);
oneBlockIsland.setLastPhaseChangeTime(System.currentTimeMillis());

User user = User.getInstance(mockPlayer);
when(im.getIsland(world, user)).thenReturn(testIsland);
when(blockListener.getIsland(testIsland)).thenReturn(oneBlockIsland);
when(oneBlockManager.getBlockProbs()).thenReturn(createBlockProbs());

CompositeCommand mainCommand = mock(CompositeCommand.class);
CompositeCommand setCountCommand = mock(CompositeCommand.class);
when(mainCommand.getSubCommand("setcount")).thenReturn(Optional.of(setCountCommand));
when(setCountCommand.getPermission()).thenReturn("aoneblock.island.setcount");
when(addon.getPlayerCommand()).thenReturn(Optional.of(mainCommand));
when(mockPlayer.hasPermission("aoneblock.island.setcount")).thenReturn(true);

Constructor<PhasesPanel> constructor = PhasesPanel.class.getDeclaredConstructor(AOneBlock.class, World.class, User.class);
constructor.setAccessible(true);
panel = constructor.newInstance(addon, world, user);

OneBlockPhase phase = createTestPhase("Plains");

Method method = PhasesPanel.class.getDeclaredMethod("canApplyPhase", OneBlockPhase.class);
method.setAccessible(true);

boolean result = (boolean) method.invoke(panel, phase);

assertTrue(result);
}

// =========================================================================
// Test phaseRequirementsFail
// =========================================================================
Expand Down
Loading