diff --git a/src/main/java/games/dmg/leaf/LeafListener.java b/src/main/java/games/dmg/leaf/LeafListener.java index f4b773e..f690ab6 100644 --- a/src/main/java/games/dmg/leaf/LeafListener.java +++ b/src/main/java/games/dmg/leaf/LeafListener.java @@ -12,6 +12,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; /** Handles player lifecycle events that affect Leaf protection. */ public final class LeafListener implements Listener { @@ -38,6 +39,11 @@ public final class LeafListener implements Listener { } } + @EventHandler + public void onQuit(PlayerQuitEvent event) { + runtime.removePresentation(event.getPlayer()); + } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageEvent event) { if (event.isCancelled() || event.getFinalDamage() <= 0.0 diff --git a/src/test/java/games/dmg/leaf/LeafListenerLifecycleTest.java b/src/test/java/games/dmg/leaf/LeafListenerLifecycleTest.java new file mode 100644 index 0000000..a59b3b6 --- /dev/null +++ b/src/test/java/games/dmg/leaf/LeafListenerLifecycleTest.java @@ -0,0 +1,24 @@ +package games.dmg.leaf; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.time.Clock; +import java.util.logging.Logger; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerQuitEvent; +import org.junit.jupiter.api.Test; + +final class LeafListenerLifecycleTest { + @Test + void removesSessionOwnedPresentationWhenAPlayerQuits() { + LeafRuntime runtime = mock(LeafRuntime.class); + Player player = mock(Player.class); + PlayerQuitEvent event = mock(PlayerQuitEvent.class); + org.mockito.Mockito.when(event.getPlayer()).thenReturn(player); + + new LeafListener(runtime, Clock.systemUTC(), Logger.getAnonymousLogger()).onQuit(event); + + verify(runtime).removePresentation(player); + } +}