diff --git a/src/main/java/us/tastybento/bskyblock/listeners/PanelListenerManager.java b/src/main/java/us/tastybento/bskyblock/listeners/PanelListenerManager.java index 937ef9ec0..eb8f485cc 100644 --- a/src/main/java/us/tastybento/bskyblock/listeners/PanelListenerManager.java +++ b/src/main/java/us/tastybento/bskyblock/listeners/PanelListenerManager.java @@ -14,6 +14,7 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.Inventory; import us.tastybento.bskyblock.api.panels.Panel; +import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.user.User; public class PanelListenerManager implements Listener { @@ -39,13 +40,11 @@ public class PanelListenerManager implements Listener { // Get the panel itself Panel panel = openPanels.get(user.getUniqueId()); // Check that they clicked on a specific item - for (int slot : panel.getItems().keySet()) { - if (slot == event.getRawSlot()) { - panel.getItems().get(slot).getClickHandler().ifPresent(handler -> - // Execute the handler's onClick method and optionally cancel the event if the handler returns true - event.setCancelled(handler.onClick(panel, user, event.getClick(), event.getSlot())) - ); - } + PanelItem pi = panel.getItems().get(event.getRawSlot()); + if (pi != null) { + pi.getClickHandler().ifPresent(handler -> + // Execute the handler's onClick method and optionally cancel the event if the handler returns true + event.setCancelled(handler.onClick(panel, user, event.getClick(), event.getSlot()))); } // If there is a listener, then run it. panel.getListener().ifPresent(l -> l.onInventoryClick(user, event)); diff --git a/src/test/java/us/tastybento/bskyblock/listeners/PanelListenerManagerTest.java b/src/test/java/us/tastybento/bskyblock/listeners/PanelListenerManagerTest.java new file mode 100644 index 000000000..d148c423d --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/listeners/PanelListenerManagerTest.java @@ -0,0 +1,222 @@ +/** + * + */ +package us.tastybento.bskyblock.listeners; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import us.tastybento.bskyblock.api.panels.Panel; +import us.tastybento.bskyblock.api.panels.PanelItem; +import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler; +import us.tastybento.bskyblock.api.panels.PanelListener; +import us.tastybento.bskyblock.api.user.User; + +/** + * Test class for PanelListenerManager.java + * @author tastybento + * + */ +public class PanelListenerManagerTest { + + private Player player; + private InventoryView view; + private SlotType type; + private ClickType click; + private InventoryAction inv; + private PanelListenerManager plm; + private UUID uuid; + private Panel panel; + private Panel wrongPanel; + private Inventory anotherInv; + private PanelListener pl; + private ClickHandler ch; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + uuid = UUID.randomUUID(); + player = mock(Player.class); + when(player.getUniqueId()).thenReturn(uuid); + view = mock(InventoryView.class); + when(view.getPlayer()).thenReturn(player); + + User.getInstance(player); + Inventory top = mock(Inventory.class); + when(top.getSize()).thenReturn(9); + when(view.getTopInventory()).thenReturn(top); + type = SlotType.CONTAINER; + click = ClickType.LEFT; + inv = InventoryAction.UNKNOWN; + + plm = new PanelListenerManager(); + + // Panel + panel = mock(Panel.class); + pl = mock(PanelListener.class); + Optional opl = Optional.of(pl); + when(panel.getListener()).thenReturn(opl); + when(panel.getInventory()).thenReturn(top); + when(top.getName()).thenReturn("name"); + Map map = new HashMap<>(); + PanelItem panelItem = mock(PanelItem.class); + ch = mock(ClickHandler.class); + //when(ch.onClick(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true); + Optional och = Optional.of(ch); + when(panelItem.getClickHandler()).thenReturn(och); + map.put(0, panelItem); + when(panel.getItems()).thenReturn(map); + + wrongPanel = mock(Panel.class); + anotherInv = mock(Inventory.class); + when(anotherInv.getName()).thenReturn("another_name"); + when(wrongPanel.getInventory()).thenReturn(anotherInv); + + // Clear the static panels + PanelListenerManager.getOpenPanels().clear(); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent)}. + */ + @Test + public void testOnInventoryClickOutside() { + SlotType type = SlotType.OUTSIDE; + InventoryClickEvent e = new InventoryClickEvent(view, type, 0, click, inv); + plm.onInventoryClick(e); + Mockito.verify(player).closeInventory(); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent)}. + */ + @Test + public void testOnInventoryClickNoOpenPanels() { + InventoryClickEvent e = new InventoryClickEvent(view, type, 0, click, inv); + plm.onInventoryClick(e); + // Nothing should happen + Mockito.verify(player, Mockito.never()).closeInventory(); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent)}. + */ + @Test + public void testOnInventoryClickOpenPanelsWrongPanel() { + PanelListenerManager.getOpenPanels().put(uuid, panel); + when(view.getTopInventory()).thenReturn(anotherInv); + InventoryClickEvent e = new InventoryClickEvent(view, type, 0, click, inv); + plm.onInventoryClick(e); + // Panel should be removed + assertTrue(PanelListenerManager.getOpenPanels().isEmpty()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent)}. + */ + @Test + public void testOnInventoryClickOpenPanelsRightPanelWrongSlot() { + PanelListenerManager.getOpenPanels().put(uuid, panel); + // Click on 1 instead of 0 + InventoryClickEvent e = new InventoryClickEvent(view, type, 1, click, inv); + plm.onInventoryClick(e); + assertTrue(e.isCancelled()); + Mockito.verify(pl).onInventoryClick(Mockito.any(), Mockito.any()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClick(org.bukkit.event.inventory.InventoryClickEvent)}. + */ + @Test + public void testOnInventoryClickOpenPanelsRightPanelRightSlot() { + PanelListenerManager.getOpenPanels().put(uuid, panel); + // Click on 0 + InventoryClickEvent e = new InventoryClickEvent(view, type, 0, click, inv); + plm.onInventoryClick(e); + // Check that the onClick is called + Mockito.verify(ch).onClick(Mockito.eq(panel), Mockito.any(User.class), Mockito.eq(click), Mockito.eq(0)); + Mockito.verify(pl).onInventoryClick(Mockito.any(), Mockito.any()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClose(org.bukkit.event.inventory.InventoryCloseEvent)}. + */ + @Test + public void testOnInventoryCloseNoPanels() { + // Add a panel for another player + PanelListenerManager.getOpenPanels().put(UUID.randomUUID(), panel); + // No panels for this player + InventoryCloseEvent event = new InventoryCloseEvent(view); + plm.onInventoryClose(event); + assertTrue(PanelListenerManager.getOpenPanels().size() == 1); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onInventoryClose(org.bukkit.event.inventory.InventoryCloseEvent)}. + */ + @Test + public void testOnInventoryClosePanels() { + // Add a panel for player + PanelListenerManager.getOpenPanels().put(uuid, panel); + InventoryCloseEvent event = new InventoryCloseEvent(view); + plm.onInventoryClose(event); + assertTrue(PanelListenerManager.getOpenPanels().isEmpty()); + Mockito.verify(pl).onInventoryClose(event); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#onLogOut(org.bukkit.event.player.PlayerQuitEvent)}. + */ + @Test + public void testOnLogOut() { + // Add a panel for player + PanelListenerManager.getOpenPanels().put(uuid, panel); + // Unknown player logs out + + Player unknown = mock(Player.class); + when(unknown.getUniqueId()).thenReturn(UUID.randomUUID()); + PlayerQuitEvent event = new PlayerQuitEvent(unknown, ""); + plm.onLogOut(event); + assertFalse(PanelListenerManager.getOpenPanels().isEmpty()); + + // Real log out + event = new PlayerQuitEvent(player, ""); + plm.onLogOut(event); + assertTrue(PanelListenerManager.getOpenPanels().isEmpty()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.PanelListenerManager#getOpenPanels()}. + */ + @Test + public void testGetOpenPanels() { + PanelListenerManager.getOpenPanels().put(uuid, panel); + assertEquals(panel, PanelListenerManager.getOpenPanels().get(uuid)); + } + +}