From f4657a2bd7a7bec2bb5512e049755369d40573fd Mon Sep 17 00:00:00 2001 From: Atrius Date: Mon, 18 May 2026 02:36:23 -0400 Subject: [PATCH 1/4] test: implement ServerFunSpec infrastructure and fix AdvancementManager --- .../waystones/manager/AdvancementManager.kt | 6 +- .../waystones/event/DestroyEventTest.kt | 114 ++++++++++++++++ .../atrius/waystones/event/LinkEventTest.kt | 84 ++++++++++++ .../atrius/waystones/event/NameEventTest.kt | 124 ++++++++++++++++++ .../atrius/waystones/test/ServerFunSpec.kt | 12 +- .../atrius/waystones/test/TestServerMock.kt | 12 ++ src/test/resources/test-config.yml | 38 ++++++ 7 files changed, 387 insertions(+), 3 deletions(-) create mode 100644 src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt create mode 100644 src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt create mode 100644 src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt create mode 100644 src/test/kotlin/xyz/atrius/waystones/test/TestServerMock.kt create mode 100644 src/test/resources/test-config.yml diff --git a/src/main/kotlin/xyz/atrius/waystones/manager/AdvancementManager.kt b/src/main/kotlin/xyz/atrius/waystones/manager/AdvancementManager.kt index 1fbe26b..6a26831 100644 --- a/src/main/kotlin/xyz/atrius/waystones/manager/AdvancementManager.kt +++ b/src/main/kotlin/xyz/atrius/waystones/manager/AdvancementManager.kt @@ -62,8 +62,12 @@ class AdvancementManager( loadAdvancements() } - fun awardAdvancement(player: Player, adv: AdvancementProvider) = + fun awardAdvancement(player: Player, adv: AdvancementProvider) { + if (!enableAdvancements.value()) { + return + } awardAdvancement(player, plugin.server.getAdvancement(adv.namespacedKey())) + } fun awardAdvancement(player: Player, adv: SpigotAdvancement?) { if (adv == null || !enableAdvancements.value()) { diff --git a/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt new file mode 100644 index 0000000..0e60a88 --- /dev/null +++ b/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt @@ -0,0 +1,114 @@ +package xyz.atrius.waystones.event + +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.ExplosionResult +import org.bukkit.entity.TNTPrimed +import org.bukkit.event.block.BlockBreakEvent +import org.bukkit.event.block.BlockExplodeEvent +import org.bukkit.event.entity.EntityExplodeEvent +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.ItemMeta +import xyz.atrius.waystones.repository.WaystoneInfoRepository +import xyz.atrius.waystones.test.ServerFunSpec +import java.util.concurrent.TimeUnit + +class DestroyEventTest : ServerFunSpec({ + + test("Breaking a waystone removes it from the database") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag = ItemStack(Material.NAME_TAG) + nameTag.editMeta { it.displayName(Component.text("Test Waystone")) } + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + + val breakEvent = BlockBreakEvent(waystone, player) + server.pluginManager.callEvent(breakEvent) + + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } + + test("Breaking a non-waystone block does not affect the database") { + val world = createWorld("world") + val player = createPlayer() + val stone = placeBlock(world, 0, 64, 0, Material.STONE) + + val breakEvent = BlockBreakEvent(stone, player) + server.pluginManager.callEvent(breakEvent) + + breakEvent.isCancelled shouldBe false + } + + test("Breaking a lodestone without a database entry does not crash") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val breakEvent = BlockBreakEvent(waystone, player) + server.pluginManager.callEvent(breakEvent) + + breakEvent.isCancelled shouldBe false + } + + test("Destroying a waystone via block explosion removes it from the database") { + val world = createWorld("world") + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag = ItemStack(Material.NAME_TAG) + nameTag.editMeta { it.displayName(Component.text("Explosive Waystone")) } + val player = createPlayer() + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + + val explodeEvent = BlockExplodeEvent( + waystone, + waystone.state, + mutableListOf(waystone), + 4f, + ExplosionResult.DESTROY, + ) + server.pluginManager.callEvent(explodeEvent) + + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } + + test("Destroying a waystone via entity explosion removes it from the database") { + val world = createWorld("world") + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag = ItemStack(Material.NAME_TAG) + nameTag.editMeta { it.displayName(Component.text("TNT Waystone")) } + val player = createPlayer() + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + + val tnt = world.spawn(waystone.location, TNTPrimed::class.java) + val explodeEvent = EntityExplodeEvent( + tnt, + waystone.location, + mutableListOf(waystone), + 4f, + ExplosionResult.DESTROY, + ) + server.pluginManager.callEvent(explodeEvent) + + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } +}) diff --git a/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt new file mode 100644 index 0000000..8664123 --- /dev/null +++ b/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt @@ -0,0 +1,84 @@ +package xyz.atrius.waystones.event + +import io.kotest.assertions.nondeterministic.eventually +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import org.bukkit.Material +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.CompassMeta +import org.bukkit.persistence.PersistentDataType +import xyz.atrius.waystones.repository.WaystoneInfoRepository +import xyz.atrius.waystones.test.ServerFunSpec +import xyz.atrius.waystones.utility.toKey +import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.seconds + +class LinkEventTest : ServerFunSpec({ + + test("Linking a compass to a waystone creates a database entry") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 100, 64, 200) + + val compass = ItemStack(Material.COMPASS) + val meta = compass.itemMeta as CompassMeta + meta.persistentDataContainer.set("is_warp_key".toKey(), PersistentDataType.INTEGER, 1) + compass.itemMeta = meta + player.inventory.setItem(0, compass) + player.inventory.heldItemSlot = 0 + + simulateRightClick(player, waystone, compass) + + val repository = get() + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + } + } + + test("Linking a compass to a non-waystone block does nothing") { + val world = createWorld("world") + val player = createPlayer() + val stone = placeBlock(world, 0, 64, 0, Material.STONE) + + val compass = ItemStack(Material.COMPASS) + player.inventory.setItem(0, compass) + player.inventory.heldItemSlot = 0 + + simulateRightClick(player, stone, compass) + + val repository = get() + eventually(1.seconds) { + repository.getWaystone(stone.location).get(5, TimeUnit.SECONDS) shouldBe null + } + } + + test("Linking a non-compass item to a waystone does nothing") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val stick = ItemStack(Material.STICK) + player.inventory.setItem(0, stick) + player.inventory.heldItemSlot = 0 + + simulateRightClick(player, waystone, stick) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } + + test("Linking a compass without warp key marker does nothing") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val compass = ItemStack(Material.COMPASS) + player.inventory.setItem(0, compass) + player.inventory.heldItemSlot = 0 + + simulateRightClick(player, waystone, compass) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } +}) diff --git a/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt new file mode 100644 index 0000000..9567d79 --- /dev/null +++ b/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt @@ -0,0 +1,124 @@ +package xyz.atrius.waystones.event + +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.ItemMeta +import xyz.atrius.waystones.repository.WaystoneInfoRepository +import xyz.atrius.waystones.test.ServerFunSpec +import java.util.concurrent.TimeUnit + +class NameEventTest : ServerFunSpec({ + + test("Naming a waystone with a name tag persists to the database") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag = ItemStack(Material.NAME_TAG) + nameTag.editMeta { meta: ItemMeta -> + meta.displayName(Component.text("My Waystone")) + } + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + + simulateRightClick(player, waystone, nameTag) + + val repository = get() + val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) + info?.name shouldBe "My Waystone" + } + + test("Renaming a waystone updates the database entry") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag1 = ItemStack(Material.NAME_TAG) + nameTag1.editMeta { it.displayName(Component.text("First Name")) } + player.inventory.setItem(0, nameTag1) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag1) + + val nameTag2 = ItemStack(Material.NAME_TAG) + nameTag2.editMeta { it.displayName(Component.text("Second Name")) } + player.inventory.setItem(0, nameTag2) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag2) + + val repository = get() + val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) + info?.name shouldBe "Second Name" + } + + test("Using a non-name-tag item does not name the waystone") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val stick = ItemStack(Material.STICK) + player.inventory.setItem(0, stick) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, stick) + + val repository = get() + val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) + info?.name shouldBe null + } + + test("Naming a waystone with a name tag without display name does nothing") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag = ItemStack(Material.NAME_TAG) + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag) + + val repository = get() + val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) + info?.name shouldBe null + } + + test("Naming a non-lodestone block does nothing") { + val world = createWorld("world") + val player = createPlayer() + val stone = placeBlock(world, 0, 64, 0, Material.STONE) + + val nameTag = ItemStack(Material.NAME_TAG) + nameTag.editMeta { it.displayName(Component.text("My Stone")) } + player.inventory.setItem(0, nameTag) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, stone, nameTag) + + val repository = get() + val info = repository.getWaystone(stone.location).get(5, TimeUnit.SECONDS) + info?.name shouldBe null + } + + test("Naming a waystone with the same name is ignored") { + val world = createWorld("world") + val player = createPlayer() + val waystone = placeWaystone(world, 0, 64, 0) + + val nameTag1 = ItemStack(Material.NAME_TAG) + nameTag1.editMeta { it.displayName(Component.text("Same Name")) } + player.inventory.setItem(0, nameTag1) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag1) + + val repository = get() + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "Same Name" + + val nameTag2 = ItemStack(Material.NAME_TAG) + nameTag2.editMeta { it.displayName(Component.text("Same Name")) } + player.inventory.setItem(0, nameTag2) + player.inventory.heldItemSlot = 0 + simulateRightClick(player, waystone, nameTag2) + + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "Same Name" + } +}) diff --git a/src/test/kotlin/xyz/atrius/waystones/test/ServerFunSpec.kt b/src/test/kotlin/xyz/atrius/waystones/test/ServerFunSpec.kt index 071b7ed..2b4b161 100644 --- a/src/test/kotlin/xyz/atrius/waystones/test/ServerFunSpec.kt +++ b/src/test/kotlin/xyz/atrius/waystones/test/ServerFunSpec.kt @@ -12,6 +12,7 @@ import org.bukkit.entity.Player import org.bukkit.event.block.Action import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.inventory.ItemStack +import org.koin.core.context.stopKoin import org.mockbukkit.mockbukkit.MockBukkit import org.mockbukkit.mockbukkit.ServerMock import xyz.atrius.waystones.Waystones @@ -51,14 +52,21 @@ abstract class ServerFunSpec private constructor() : FunSpec() { extensions( object : SpecExtension { override suspend fun intercept(spec: Spec, execute: suspend (Spec) -> Unit) { - _server = MockBukkit.mock() - _plugin = MockBukkit.load(Waystones::class.java) + _server = MockBukkit.mock(TestServerMock()) + + // Load plugin with custom config + val configStream = javaClass.getResourceAsStream("/test-config.yml") + ?: throw IllegalStateException("test-config.yml not found") + _plugin = MockBukkit.loadWithConfig(Waystones::class.java, configStream.use { + org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(java.io.InputStreamReader(it)) + }) _koin = _plugin!!.getKoinApp().koin try { execute(spec) } finally { MockBukkit.unmock() + stopKoin() } } } diff --git a/src/test/kotlin/xyz/atrius/waystones/test/TestServerMock.kt b/src/test/kotlin/xyz/atrius/waystones/test/TestServerMock.kt new file mode 100644 index 0000000..e6b7566 --- /dev/null +++ b/src/test/kotlin/xyz/atrius/waystones/test/TestServerMock.kt @@ -0,0 +1,12 @@ +package xyz.atrius.waystones.test + +import org.mockbukkit.mockbukkit.ServerMock + +/** + * Custom ServerMock that disables the AsyncCatcher by always reporting + * that we're on the main thread. This is necessary because Kotest runs + * tests in coroutines which may switch threads between suspensions. + */ +class TestServerMock : ServerMock() { + override fun isPrimaryThread(): Boolean = true +} diff --git a/src/test/resources/test-config.yml b/src/test/resources/test-config.yml new file mode 100644 index 0000000..7c8c479 --- /dev/null +++ b/src/test/resources/test-config.yml @@ -0,0 +1,38 @@ +fallback-locale: en +wait-time: 3.0 +damage-stops-warping: true +limit-distance: true +base-distance: 100 +max-boost: 150 +max-warp-size: 50 +jump-worlds: true +default-world-ratio: 1.0 +warp-animations: true +single-use: false +require-power: INTER_DIMENSION +power-cost: 1 +enable-portal-sickness: true +portal-sickness-chance: 5.0 +portal-sickness-warping: DAMAGE_ON_TELEPORT +portal-sickness-damage: 5.0 +relinkable-keys: true +enable-key-items: true +enable-advancements: false +show-compass-coordinates: true +key-recipe: + - AIR + - IRON_INGOT + - AIR + - IRON_INGOT + - REDSTONE_BLOCK + - IRON_INGOT + - AIR + - IRON_INGOT + - AIR +database: + type: sqlite + host: "localhost" + port: 3306 + username: "root" + password: "password" + database-name: "waystones" From 8c0d90109fa5a43767154ed9079a3496278e418b Mon Sep 17 00:00:00 2001 From: Atrius Date: Mon, 18 May 2026 02:36:24 -0400 Subject: [PATCH 2/4] test: add NameEvent integration tests --- .../atrius/waystones/event/NameEventTest.kt | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt index 9567d79..fa037a0 100644 --- a/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt +++ b/src/test/kotlin/xyz/atrius/waystones/event/NameEventTest.kt @@ -1,5 +1,6 @@ package xyz.atrius.waystones.event +import io.kotest.assertions.nondeterministic.eventually import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import net.kyori.adventure.text.Component @@ -9,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta import xyz.atrius.waystones.repository.WaystoneInfoRepository import xyz.atrius.waystones.test.ServerFunSpec import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.seconds class NameEventTest : ServerFunSpec({ @@ -27,8 +29,9 @@ class NameEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag) val repository = get() - val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) - info?.name shouldBe "My Waystone" + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "My Waystone" + } } test("Renaming a waystone updates the database entry") { @@ -49,8 +52,9 @@ class NameEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag2) val repository = get() - val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) - info?.name shouldBe "Second Name" + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "Second Name" + } } test("Using a non-name-tag item does not name the waystone") { @@ -64,8 +68,9 @@ class NameEventTest : ServerFunSpec({ simulateRightClick(player, waystone, stick) val repository = get() - val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) - info?.name shouldBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe null + } } test("Naming a waystone with a name tag without display name does nothing") { @@ -79,8 +84,9 @@ class NameEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag) val repository = get() - val info = repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) - info?.name shouldBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe null + } } test("Naming a non-lodestone block does nothing") { @@ -111,7 +117,9 @@ class NameEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag1) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "Same Name" + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS)?.name shouldBe "Same Name" + } val nameTag2 = ItemStack(Material.NAME_TAG) nameTag2.editMeta { it.displayName(Component.text("Same Name")) } From 3c5e713496f9b445276868079049ae66f31ebdcb Mon Sep 17 00:00:00 2001 From: Atrius Date: Mon, 18 May 2026 02:36:26 -0400 Subject: [PATCH 3/4] test: add LinkEvent integration tests --- .../kotlin/xyz/atrius/waystones/event/LinkEventTest.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt index 8664123..4f69e54 100644 --- a/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt +++ b/src/test/kotlin/xyz/atrius/waystones/event/LinkEventTest.kt @@ -64,7 +64,9 @@ class LinkEventTest : ServerFunSpec({ simulateRightClick(player, waystone, stick) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } } test("Linking a compass without warp key marker does nothing") { @@ -79,6 +81,8 @@ class LinkEventTest : ServerFunSpec({ simulateRightClick(player, waystone, compass) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } } }) From ffa514470cf9a4863388c61daac94cbf4ba4210d Mon Sep 17 00:00:00 2001 From: Atrius Date: Mon, 18 May 2026 02:36:27 -0400 Subject: [PATCH 4/4] test: add DestroyEvent integration tests --- .../waystones/event/DestroyEventTest.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt b/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt index 0e60a88..4b5755e 100644 --- a/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt +++ b/src/test/kotlin/xyz/atrius/waystones/event/DestroyEventTest.kt @@ -1,5 +1,6 @@ package xyz.atrius.waystones.event +import io.kotest.assertions.nondeterministic.eventually import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import net.kyori.adventure.text.Component @@ -10,10 +11,10 @@ import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockExplodeEvent import org.bukkit.event.entity.EntityExplodeEvent import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.ItemMeta import xyz.atrius.waystones.repository.WaystoneInfoRepository import xyz.atrius.waystones.test.ServerFunSpec import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.seconds class DestroyEventTest : ServerFunSpec({ @@ -29,12 +30,16 @@ class DestroyEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + } val breakEvent = BlockBreakEvent(waystone, player) server.pluginManager.callEvent(breakEvent) - - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } } test("Breaking a non-waystone block does not affect the database") { @@ -71,7 +76,9 @@ class DestroyEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + } val explodeEvent = BlockExplodeEvent( waystone, @@ -81,8 +88,10 @@ class DestroyEventTest : ServerFunSpec({ ExplosionResult.DESTROY, ) server.pluginManager.callEvent(explodeEvent) - - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } } test("Destroying a waystone via entity explosion removes it from the database") { @@ -97,7 +106,9 @@ class DestroyEventTest : ServerFunSpec({ simulateRightClick(player, waystone, nameTag) val repository = get() - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldNotBe null + } val tnt = world.spawn(waystone.location, TNTPrimed::class.java) val explodeEvent = EntityExplodeEvent( @@ -108,7 +119,9 @@ class DestroyEventTest : ServerFunSpec({ ExplosionResult.DESTROY, ) server.pluginManager.callEvent(explodeEvent) - - repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + + eventually(1.seconds) { + repository.getWaystone(waystone.location).get(5, TimeUnit.SECONDS) shouldBe null + } } })