package world.bentobox.challenges.commands; import static org.junit.Assert.assertEquals; 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.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Collections; import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.meta.ItemMeta; import org.eclipse.jdt.annotation.NonNull; import org.junit.Before; import org.junit.Test; 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; import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.config.Settings; import world.bentobox.challenges.config.SettingsUtils.VisibilityMode; import world.bentobox.challenges.managers.ChallengesManager; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) @PrepareForTest({Bukkit.class, BentoBox.class, ChatColor.class, Util.class}) public class ChallengesCommandTest { @Mock private CompositeCommand ic; @Mock private User user; @Mock private IslandsManager im; @Mock private Island island; @Mock private ChallengesAddon addon; private ChallengesPlayerCommand cc; @Mock private World world; @Mock private ChallengesManager chm; @Mock private IslandWorldManager iwm; @Mock private GameModeAddon gameModeAddon; /** */ @Before public void setUp() { // Set up plugin BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); User.setPlugin(plugin); // Command manager CommandsManager cm = mock(CommandsManager.class); when(plugin.getCommandsManager()).thenReturn(cm); // Addon when(ic.getAddon()).thenReturn(addon); when(ic.getPermissionPrefix()).thenReturn("bskyblock."); when(ic.getLabel()).thenReturn("island"); when(ic.getTopLabel()).thenReturn("island"); when(ic.getWorld()).thenReturn(world); when(ic.getTopLabel()).thenReturn("bsb"); // IWM friendly name when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(iwm.inWorld(any(World.class))).thenReturn(true); Optional optionalAddon = Optional.of(gameModeAddon); when(iwm.getAddon(any())).thenReturn(optionalAddon); when(plugin.getIWM()).thenReturn(iwm); @NonNull WorldSettings ws = new TestWorldSetting(); when(iwm.getWorldSettings(any())).thenReturn(ws); // Game Mode Addon @NonNull Optional optionalAdmin = Optional.of(ic); when(gameModeAddon.getAdminCommand()).thenReturn(optionalAdmin); // World when(world.toString()).thenReturn("world"); // Player Player p = mock(Player.class); // Sometimes use Mockito.withSettings().verboseLogging() when(user.isOp()).thenReturn(false); UUID uuid = UUID.randomUUID(); when(user.getUniqueId()).thenReturn(uuid); when(user.getPlayer()).thenReturn(p); when(user.getName()).thenReturn("tastybento"); when(user.getPermissionValue(anyString(), anyInt())).thenReturn(-1); when(user.isPlayer()).thenReturn(true); when(user.getTranslationOrNothing(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); when(user.getWorld()).thenReturn(world); // Mock item factory (for itemstacks) PowerMockito.mockStatic(Bukkit.class); ItemFactory itemFactory = mock(ItemFactory.class); when(Bukkit.getItemFactory()).thenReturn(itemFactory); ItemMeta itemMeta = mock(ItemMeta.class); when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); // Addon when(addon.getChallengesManager()).thenReturn(chm); when(chm.getAllChallengeLevelStatus(any(), any())).thenReturn(Collections.emptyList()); // Challenges exist when(chm.hasAnyChallengeData(any(World.class))).thenReturn(true); // ChatColor PowerMockito.mockStatic(ChatColor.class); when(ChatColor.translateAlternateColorCodes(any(char.class), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); // Settings Settings settings = new Settings(); when(addon.getChallengesSettings()).thenReturn(settings); settings.setVisibilityMode(VisibilityMode.VISIBLE); // Island when(plugin.getIslands()).thenReturn(im); when(im.getIsland(any(), any(User.class))).thenReturn(island); // Default to player being on the island when(im.locationIsOnIsland(any(Player.class), any())).thenReturn(true); // Util PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); when(Util.sameWorld(any(), any())).thenReturn(true); // Command under test cc = new ChallengesPlayerCommand(addon, ic); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteWrongWorld() { when(iwm.inWorld(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(user).getTranslation(world, "general.errors.wrong-world"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteNoChallenges() { when(iwm.inWorld(any(World.class))).thenReturn(true); when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); verify(user).getTranslation(world, "challenges.errors.no-challenges"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteNoChallengesOp() { when(user.isOp()).thenReturn(true); when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteNoChallengesHasPerm() { when(user.hasPermission(anyString())).thenReturn(true); when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteNoAdminCommand() { when(gameModeAddon.getAdminCommand()).thenReturn(Optional.empty()); when(user.isOp()).thenReturn(true); when(chm.hasAnyChallengeData(any(World.class))).thenReturn(false); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(addon).logError("There are no challenges set up in world!"); verify(user).getTranslation(world, "challenges.errors.no-challenges-admin", "[command]", "bsb challenges"); verify(user, never()).getTranslation(world, "challenges.errors.no-challenges"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteNoIsland() { when(im.getIsland(any(), any(User.class))).thenReturn(null); assertFalse(cc.canExecute(user, "challenges", Collections.emptyList())); verify(user).getTranslation(world, "general.errors.no-island"); } /** * Test method for {@link ChallengesPlayerCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testCanExecuteSuccess() { assertTrue(cc.canExecute(user, "challenges", Collections.emptyList())); verify(user, never()).sendMessage(anyString()); } /** * Test method for {@link ChallengesPlayerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test public void testExecuteUserStringListOfStringUser() { assertTrue(cc.execute(user, "challenges", Collections.emptyList())); } /** * Test method for {@link ChallengesPlayerCommand#setup()}. */ @Test public void testSetup() { assertEquals("bskyblock.challenges", cc.getPermission()); assertEquals("challenges.commands.user.main.parameters", cc.getParameters()); assertEquals("challenges.commands.user.main.description", cc.getDescription()); assertTrue(cc.isOnlyPlayer()); // CompleteChallengeCommand assertEquals(1, cc.getSubCommands(true).size()); } }