|
14 | 14 |
|
15 | 15 | import java.util.HashMap; |
16 | 16 | import java.util.Map; |
| 17 | +import java.util.Set; |
17 | 18 | import java.util.Optional; |
18 | 19 | import java.util.UUID; |
19 | 20 |
|
20 | 21 | import org.bukkit.ChatColor; |
| 22 | +import org.bukkit.Material; |
21 | 23 | import org.bukkit.entity.HumanEntity; |
22 | 24 | import org.bukkit.entity.Player; |
23 | 25 | import org.bukkit.event.inventory.ClickType; |
24 | 26 | import org.bukkit.event.inventory.InventoryAction; |
25 | 27 | import org.bukkit.event.inventory.InventoryClickEvent; |
26 | 28 | import org.bukkit.event.inventory.InventoryCloseEvent; |
| 29 | +import org.bukkit.event.inventory.InventoryDragEvent; |
27 | 30 | import org.bukkit.event.inventory.InventoryType; |
28 | 31 | import org.bukkit.event.inventory.InventoryType.SlotType; |
29 | 32 | import org.bukkit.event.player.PlayerQuitEvent; |
30 | 33 | import org.bukkit.inventory.Inventory; |
31 | 34 | import org.bukkit.inventory.InventoryView; |
32 | 35 | import org.bukkit.inventory.ItemStack; |
33 | 36 | import org.bukkit.inventory.MenuType; |
| 37 | +import org.bukkit.inventory.PlayerInventory; |
34 | 38 | import org.jetbrains.annotations.Nullable; |
35 | 39 | import org.junit.jupiter.api.AfterEach; |
36 | 40 | import org.junit.jupiter.api.BeforeEach; |
@@ -341,6 +345,111 @@ void testOnInventoryClickOpenPanelsRightPanelRightSlot() { |
341 | 345 | verify(pl).onInventoryClick(any(), any()); |
342 | 346 | } |
343 | 347 |
|
| 348 | + /** |
| 349 | + * A view whose raw slots 0-8 are the panel and 9 onwards are the player's inventory. |
| 350 | + */ |
| 351 | + class SplitView extends MyView { |
| 352 | + |
| 353 | + private final Inventory bottom = mock(PlayerInventory.class); |
| 354 | + private ItemStack cursor; |
| 355 | + |
| 356 | + SplitView() { |
| 357 | + super(ChatColor.RED + PANEL_NAME, panel.getInventory()); |
| 358 | + } |
| 359 | + |
| 360 | + @Override |
| 361 | + public Inventory getBottomInventory() { |
| 362 | + return bottom; |
| 363 | + } |
| 364 | + |
| 365 | + @Override |
| 366 | + public Inventory getInventory(int rawSlot) { |
| 367 | + return rawSlot < 9 ? getTopInventory() : bottom; |
| 368 | + } |
| 369 | + |
| 370 | + @Override |
| 371 | + public ItemStack getCursor() { |
| 372 | + return cursor; |
| 373 | + } |
| 374 | + |
| 375 | + @Override |
| 376 | + public void setCursor(ItemStack item) { |
| 377 | + cursor = item; |
| 378 | + } |
| 379 | + } |
| 380 | + |
| 381 | + private InventoryClickEvent clickPlayerInventory(InventoryAction action) { |
| 382 | + PanelListenerManager.getOpenPanels().put(uuid, panel); |
| 383 | + InventoryClickEvent e = new InventoryClickEvent(new SplitView(), type, 20, click, action); |
| 384 | + plm.onInventoryClick(e); |
| 385 | + return e; |
| 386 | + } |
| 387 | + |
| 388 | + @Test |
| 389 | + void testPlayerInventoryClickRoutedToListenerByDefault() { |
| 390 | + // A listener that has not opted in (e.g. an icon picker) still gets the click, cancelled |
| 391 | + InventoryClickEvent e = clickPlayerInventory(InventoryAction.PICKUP_ALL); |
| 392 | + assertTrue(e.isCancelled()); |
| 393 | + verify(pl).onInventoryClick(any(), eq(e)); |
| 394 | + } |
| 395 | + |
| 396 | + @Test |
| 397 | + void testPlayerInventoryClickAllowedWhenListenerOptsIn() { |
| 398 | + when(pl.allowsPlayerInventoryClicks()).thenReturn(true); |
| 399 | + InventoryClickEvent e = clickPlayerInventory(InventoryAction.PICKUP_ALL); |
| 400 | + assertFalse(e.isCancelled()); |
| 401 | + verify(pl, never()).onInventoryClick(any(), any()); |
| 402 | + verify(pl, never()).refreshPanel(); |
| 403 | + } |
| 404 | + |
| 405 | + @Test |
| 406 | + void testPlayerInventoryClickAllowedWithoutListener() { |
| 407 | + when(panel.getListener()).thenReturn(Optional.empty()); |
| 408 | + assertFalse(clickPlayerInventory(InventoryAction.DROP_ONE_SLOT).isCancelled()); |
| 409 | + assertFalse(clickPlayerInventory(InventoryAction.PICKUP_FROM_BUNDLE).isCancelled()); |
| 410 | + } |
| 411 | + |
| 412 | + @Test |
| 413 | + void testPlayerInventoryShiftAndDoubleClickBlocked() { |
| 414 | + when(panel.getListener()).thenReturn(Optional.empty()); |
| 415 | + assertTrue(clickPlayerInventory(InventoryAction.MOVE_TO_OTHER_INVENTORY).isCancelled()); |
| 416 | + assertTrue(clickPlayerInventory(InventoryAction.COLLECT_TO_CURSOR).isCancelled()); |
| 417 | + } |
| 418 | + |
| 419 | + @Test |
| 420 | + void testPanelClickWithCursorItemStaysCancelled() { |
| 421 | + PanelListenerManager.getOpenPanels().put(uuid, panel); |
| 422 | + // The handler asks for the click not to be cancelled |
| 423 | + when(ch.onClick(any(), any(), any(), any(Integer.class))).thenReturn(false); |
| 424 | + SplitView splitView = new SplitView(); |
| 425 | + ItemStack held = mock(ItemStack.class); |
| 426 | + when(held.getType()).thenReturn(Material.STONE); |
| 427 | + splitView.setCursor(held); |
| 428 | + InventoryClickEvent e = new InventoryClickEvent(splitView, type, 0, click, InventoryAction.PLACE_ALL); |
| 429 | + plm.onInventoryClick(e); |
| 430 | + verify(ch).onClick(eq(panel), any(User.class), eq(click), eq(0)); |
| 431 | + assertTrue(e.isCancelled()); |
| 432 | + } |
| 433 | + |
| 434 | + @Test |
| 435 | + void testDragIntoPanelCancelled() { |
| 436 | + PanelListenerManager.getOpenPanels().put(uuid, panel); |
| 437 | + InventoryDragEvent e = new InventoryDragEvent(new SplitView(), null, mock(ItemStack.class), false, |
| 438 | + Map.of(3, mock(ItemStack.class), 20, mock(ItemStack.class))); |
| 439 | + plm.onInventoryDrag(e); |
| 440 | + assertTrue(e.isCancelled()); |
| 441 | + } |
| 442 | + |
| 443 | + @Test |
| 444 | + void testDragWithinPlayerInventoryAllowed() { |
| 445 | + PanelListenerManager.getOpenPanels().put(uuid, panel); |
| 446 | + InventoryDragEvent e = new InventoryDragEvent(new SplitView(), null, mock(ItemStack.class), false, |
| 447 | + Map.of(20, mock(ItemStack.class), 21, mock(ItemStack.class))); |
| 448 | + plm.onInventoryDrag(e); |
| 449 | + assertFalse(e.isCancelled()); |
| 450 | + assertEquals(Set.of(20, 21), e.getRawSlots()); |
| 451 | + } |
| 452 | + |
344 | 453 | /** |
345 | 454 | * Test method for {@link world.bentobox.bentobox.listeners.PanelListenerManager#onInventoryClose(org.bukkit.event.inventory.InventoryCloseEvent)}. |
346 | 455 | */ |
|
0 commit comments