diff --git a/VotingPlugin/src/main/java/com/bencodez/votingplugin/user/SharedMysqlPointMutator.java b/VotingPlugin/src/main/java/com/bencodez/votingplugin/user/SharedMysqlPointMutator.java index c2680332d..c8107c2dc 100644 --- a/VotingPlugin/src/main/java/com/bencodez/votingplugin/user/SharedMysqlPointMutator.java +++ b/VotingPlugin/src/main/java/com/bencodez/votingplugin/user/SharedMysqlPointMutator.java @@ -20,7 +20,6 @@ import com.bencodez.simpleapi.sql.DataType; import com.bencodez.simpleapi.sql.data.DataValue; import com.bencodez.simpleapi.sql.data.DataValueInt; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.votingplugin.VotingPluginMain; import com.bencodez.votingplugin.util.BukkitCompletionScheduler; @@ -634,10 +633,10 @@ private void runTransferApprovalEntityTask(org.bukkit.entity.Player player, Runn BukkitCompletionScheduler.run(plugin, player, task, rejected); return; } - CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() + CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() .runAtEntityWithFallback(player, ignored -> task.run(), rejected); result.whenComplete((status, failure) -> { - if (failure != null || status != EntityTaskResult.SUCCESS) rejected.run(); + if (failure != null || !BukkitCompletionScheduler.isSuccessfulEntityTaskResult(status)) rejected.run(); }); } diff --git a/VotingPlugin/src/main/java/com/bencodez/votingplugin/util/BukkitCompletionScheduler.java b/VotingPlugin/src/main/java/com/bencodez/votingplugin/util/BukkitCompletionScheduler.java index 3d806c694..e7042a0d6 100644 --- a/VotingPlugin/src/main/java/com/bencodez/votingplugin/util/BukkitCompletionScheduler.java +++ b/VotingPlugin/src/main/java/com/bencodez/votingplugin/util/BukkitCompletionScheduler.java @@ -5,11 +5,19 @@ import org.bukkit.entity.Player; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.votingplugin.VotingPluginMain; /** Schedules exactly-once completion work with an entity-retirement fallback. */ public final class BukkitCompletionScheduler { + + /** + * Checks Folia's entity-task completion without depending on its relocated enum type. + * The enum is shaded by SimpleAPI, so naming it directly breaks Eclipse workspace + * resolution when SimpleAPI is open as a source project. + */ + public static boolean isSuccessfulEntityTaskResult(Object status) { + return status instanceof Enum result && "SUCCESS".equals(result.name()); + } private BukkitCompletionScheduler() { } @@ -49,12 +57,12 @@ public static void run(VotingPluginMain plugin, Player player, Runnable entityTa runLegacyEntity(plugin, player, entityOnce, fallback); return; } - CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() + CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() .runAtEntityWithFallback(player, ignored -> entityOnce.run(), fallback); result.whenComplete((status, failure) -> { // ENTITY_RETIRED invokes fallback itself. A scheduler that was already // retired returns SCHEDULER_RETIRED without invoking it. - if (failure != null || status != EntityTaskResult.SUCCESS) { + if (failure != null || !isSuccessfulEntityTaskResult(status)) { fallback.run(); } else if (!executed.get()) { // Compatibility with scheduler adapters that report admission but do diff --git a/VotingPlugin/src/main/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseService.java b/VotingPlugin/src/main/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseService.java index 93fdc964f..21bf19fbe 100644 --- a/VotingPlugin/src/main/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseService.java +++ b/VotingPlugin/src/main/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseService.java @@ -28,7 +28,6 @@ import com.bencodez.advancedcore.api.user.UserStorage; import com.bencodez.advancedcore.api.user.usercache.UserDataCache; import com.bencodez.advancedcore.api.user.userstorage.mysql.MySQL; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.sql.DataType; import com.bencodez.simpleapi.sql.mysql.DbType; import com.bencodez.votingplugin.VotingPluginMain; @@ -406,10 +405,10 @@ private void runPurchaseEntityTask(Player player, Runnable task, Runnable reject BukkitCompletionScheduler.run(plugin, player, task, rejected); return; } - CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() + CompletableFuture result = plugin.getBukkitScheduler().getFoliaLib().getImpl() .runAtEntityWithFallback(player, ignored -> task.run(), rejected); result.whenComplete((status, failure) -> { - if (failure != null || status != EntityTaskResult.SUCCESS) rejected.run(); + if (failure != null || !BukkitCompletionScheduler.isSuccessfulEntityTaskResult(status)) rejected.run(); }); } diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/commands/CommandLoaderSchedulingTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/commands/CommandLoaderSchedulingTest.java index 26d4fe01c..9112d2fde 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/commands/CommandLoaderSchedulingTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/commands/CommandLoaderSchedulingTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.commands; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -19,7 +20,6 @@ import com.bencodez.simpleapi.scheduler.BukkitScheduler; import com.bencodez.simpleapi.folialib.FoliaLib; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.folialib.impl.ServerImplementation; import com.bencodez.votingplugin.VotingPluginMain; import com.bencodez.votingplugin.config.Config; @@ -213,6 +213,6 @@ private static void configureEntityScheduler(BukkitScheduler scheduler) { when(scheduler.getFoliaLib()).thenReturn(folia); when(folia.getImpl()).thenReturn(entityScheduler); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS)); + .thenReturn(EntityTaskResultTestCompat.success()); } } diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/placeholders/PlaceHoldersWorkerSafetyTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/placeholders/PlaceHoldersWorkerSafetyTest.java index a2e6f2df0..1e97d049a 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/placeholders/PlaceHoldersWorkerSafetyTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/placeholders/PlaceHoldersWorkerSafetyTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.placeholders; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -34,7 +35,6 @@ import com.bencodez.advancedcore.api.user.AdvancedCoreUser; import com.bencodez.advancedcore.api.user.usercache.UserDataManager; import com.bencodez.simpleapi.folialib.FoliaLib; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.folialib.impl.ServerImplementation; import com.bencodez.simpleapi.scheduler.BukkitScheduler; import com.bencodez.votingplugin.VotingPluginMain; @@ -227,7 +227,7 @@ void retiredEntityFallsBackToOfflineWorkerUpdate() { when(entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) .thenAnswer(call -> { call.getArgument(2, Runnable.class).run(); - return CompletableFuture.completedFuture(EntityTaskResult.ENTITY_RETIRED); + return EntityTaskResultTestCompat.entityRetired(); }); doAnswer(call -> { call.getArgument(1, Runnable.class).run(); return null; }) .when(fixture.scheduler).runTask(eq(fixture.plugin), any(Runnable.class)); diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/backgroundtask/VotingPluginBackgroundTaskTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/backgroundtask/VotingPluginBackgroundTaskTest.java index a56cd286e..40102cd4e 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/backgroundtask/VotingPluginBackgroundTaskTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/backgroundtask/VotingPluginBackgroundTaskTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.tests.backgroundtask; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -99,8 +100,7 @@ public void retiredFoliaPlayerStillCompletesOnlineSnapshot() { when(scheduler.getFoliaLib()).thenReturn(folia); when(folia.getImpl()).thenReturn(implementation); when(implementation.runAtEntityWithFallback(eq(player), any(), any(Runnable.class))) - .thenReturn(java.util.concurrent.CompletableFuture.completedFuture( - com.bencodez.simpleapi.folialib.enums.EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); doAnswer(call -> { call.getArgument(1, Runnable.class).run(); return null; }) .when(scheduler).runTask(eq(plugin), any(Runnable.class)); java.util.concurrent.atomic.AtomicReference> result = diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/reminders/VoteRemindersManagerTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/reminders/VoteRemindersManagerTest.java index 716c51991..5c582cbe9 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/reminders/VoteRemindersManagerTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/reminders/VoteRemindersManagerTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.tests.reminders; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -33,7 +34,6 @@ import com.bencodez.simpleapi.time.ParsedDuration; import com.bencodez.simpleapi.scheduler.BukkitScheduler; import com.bencodez.simpleapi.folialib.FoliaLib; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.folialib.impl.ServerImplementation; import com.bencodez.advancedcore.api.rewards.RewardBuilder; import com.bencodez.votingplugin.VotingPluginMain; @@ -271,7 +271,7 @@ void reminderDeliveryReleasesReservationsWhenTheEntitySchedulerRetires() throws when(implementation.runAtEntityWithFallback(eq(player), any(), any(Runnable.class))) .thenAnswer(invocation -> { invocation.getArgument(2, Runnable.class).run(); - return CompletableFuture.completedFuture(EntityTaskResult.ENTITY_RETIRED); + return EntityTaskResultTestCompat.entityRetired(); }); org.mockito.Mockito.doAnswer(invocation -> { invocation.getArgument(1, Runnable.class).run(); diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/user/VotingPluginUserPointSchedulingTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/user/VotingPluginUserPointSchedulingTest.java index 55e8ccc00..923fcaf9f 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/user/VotingPluginUserPointSchedulingTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/user/VotingPluginUserPointSchedulingTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.user; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -52,7 +53,6 @@ import com.bencodez.simpleapi.sql.mysql.ConnectionManager; import com.bencodez.simpleapi.scheduler.BukkitScheduler; import com.bencodez.simpleapi.folialib.FoliaLib; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.folialib.impl.ServerImplementation; import com.bencodez.votingplugin.VotingPluginMain; import com.bencodez.votingplugin.events.PlayerReceivePointsEvent; @@ -803,7 +803,7 @@ void perServerPointAdditionFailsWithoutWritingWhenBukkitHandoffIsRejected() thro when(fixture.connection.prepareStatement(anyString())).thenReturn(schema, schema, schema, schema, lookup, claimInsert, releaseSelect, releaseDelete); when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); doThrow(new RejectedExecutionException("stopping")).when(fixture.scheduler) .runTask(eq(fixture.plugin), any(Runnable.class)); PluginManager pluginManager = mock(PluginManager.class); @@ -829,7 +829,7 @@ void perServerPointAdditionFailsWithoutWritingWhenBukkitHandoffIsRejected() thro @Test void retiredEntitySchedulerQueuesUnstartedHookReleaseWithoutJdbcOnCompletionLane() throws Exception { PointFixture fixture = pointFixture(); - CompletableFuture entityCompletion = new CompletableFuture<>(); + CompletableFuture entityCompletion = EntityTaskResultTestCompat.pending(); when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) .thenReturn(entityCompletion); PreparedStatement statement = fixture.statement; @@ -866,7 +866,7 @@ void retiredEntitySchedulerQueuesUnstartedHookReleaseWithoutJdbcOnCompletionLane com.bencodez.simpleapi.sql.mysql.ConnectionManager manager = fixture.sql.getConnectionManager(); org.mockito.Mockito.clearInvocations(fixture.persistence, manager, fixture.connection, statement); - entityCompletion.complete(EntityTaskResult.SCHEDULER_RETIRED); + EntityTaskResultTestCompat.completeSchedulerRetired(entityCompletion); ArgumentCaptor releaseWork = ArgumentCaptor.forClass(Runnable.class); verify(fixture.persistence).execute(releaseWork.capture()); @@ -883,7 +883,7 @@ void retiredEntitySchedulerQueuesUnstartedHookReleaseWithoutJdbcOnCompletionLane @Test void retiredEntitySchedulerRetainsClaimWhenNoDatabaseSafeReleaseWorkerAcceptsWork() throws Exception { PointFixture fixture = pointFixture(); - CompletableFuture entityCompletion = new CompletableFuture<>(); + CompletableFuture entityCompletion = EntityTaskResultTestCompat.pending(); when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) .thenReturn(entityCompletion); PreparedStatement statement = fixture.statement; @@ -923,7 +923,7 @@ void retiredEntitySchedulerRetainsClaimWhenNoDatabaseSafeReleaseWorkerAcceptsWor doThrow(new RejectedExecutionException("stopping")).when(fixture.persistence).execute(any(Runnable.class)); doThrow(new RejectedExecutionException("disabling")).when(fixture.scheduler) .runTaskAsynchronously(eq(fixture.plugin), any(Runnable.class)); - entityCompletion.complete(EntityTaskResult.SCHEDULER_RETIRED); + EntityTaskResultTestCompat.completeSchedulerRetired(entityCompletion); assertTrue(completion.isCompletedExceptionally()); verify(fixture.scheduler).runTaskAsynchronously(eq(fixture.plugin), any(Runnable.class)); @@ -1348,7 +1348,7 @@ void retiredApprovalSchedulerRefundsClaimedTransferBeforeTheHookCanRun() throws SagaFixture fixture = sagaFixture(true); configureRejectedSagaConnections(fixture); when(fixture.entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); AtomicReference result = new AtomicReference<>(); fixture.user.transferPoints(fixture.target, 10, result::set); @@ -1378,7 +1378,7 @@ void rejectedClaimedTransferCompensationUsesAsyncFallback() throws Exception { SagaFixture fixture = sagaFixture(true); configureRejectedSagaConnections(fixture); when(fixture.entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); AtomicReference result = new AtomicReference<>(); fixture.user.transferPoints(fixture.target, 10, result::set); @@ -1412,7 +1412,7 @@ void rejectedClaimedTransferRetainsDurableCompensationWhenBothFallbackSchedulers when(fixture.plugin.getDataFolder()).thenReturn(temporaryDirectory.toFile()); configureRejectedSagaConnections(fixture); when(fixture.entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); AtomicReference result = new AtomicReference<>(); fixture.user.transferPoints(fixture.target, 10, result::set); @@ -1446,7 +1446,7 @@ void failedClaimedTransferCompensationKeepsRecoveryMarkerWhenMysqlFenceAndRefund when(fixture.plugin.getDataFolder()).thenReturn(temporaryDirectory.toFile()); configureRejectedSagaConnections(fixture); when(fixture.entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); fixture.user.transferPoints(fixture.target, 10, ignored -> { }); ArgumentCaptor persistence = ArgumentCaptor.forClass(Runnable.class); @@ -1968,7 +1968,7 @@ private static ServerImplementation configureEntityScheduler(VotingPluginMain pl when(scheduler.getFoliaLib()).thenReturn(folia); when(folia.getImpl()).thenReturn(entityScheduler); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS)); + .thenReturn(EntityTaskResultTestCompat.success()); return entityScheduler; } diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/BukkitCompletionSchedulerTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/BukkitCompletionSchedulerTest.java index 4eb786f52..6c375803a 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/BukkitCompletionSchedulerTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/BukkitCompletionSchedulerTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.util; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -17,7 +18,6 @@ import org.junit.jupiter.api.Test; import com.bencodez.simpleapi.folialib.FoliaLib; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.simpleapi.folialib.impl.ServerImplementation; import com.bencodez.simpleapi.scheduler.BukkitScheduler; import com.bencodez.votingplugin.VotingPluginMain; @@ -29,7 +29,7 @@ void retiredEntityRunsCompletionOnceOnGlobalFallback() { when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) .thenAnswer(invocation -> { invocation.getArgument(2, Runnable.class).run(); - return CompletableFuture.completedFuture(EntityTaskResult.ENTITY_RETIRED); + return EntityTaskResultTestCompat.entityRetired(); }); AtomicInteger completions = new AtomicInteger(); @@ -43,7 +43,7 @@ void retiredEntityRunsCompletionOnceOnGlobalFallback() { void alreadyRetiredSchedulerRunsCompletionOnceOnGlobalFallback() { Fixture fixture = fixture(); when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); AtomicInteger completions = new AtomicInteger(); BukkitCompletionScheduler.run(fixture.plugin, fixture.player, completions::incrementAndGet); @@ -69,7 +69,7 @@ void missingSchedulerStatusRunsCompletionOnceOnGlobalFallback() { void rejectedEveryFallbackCallsRejectedOnlyWhenTaskNeverBegan() { Fixture fixture = fixture(); when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); doThrow(new RejectedExecutionException("stopping")).when(fixture.scheduler).runTask(eq(fixture.plugin), any(Runnable.class)); AtomicInteger completed = new AtomicInteger(); @@ -87,7 +87,7 @@ void retiredEntityRunsDistinctGlobalSafeFallback() { when(fixture.entityScheduler.runAtEntityWithFallback(eq(fixture.player), any(), any(Runnable.class))) .thenAnswer(invocation -> { invocation.getArgument(2, Runnable.class).run(); - return CompletableFuture.completedFuture(EntityTaskResult.ENTITY_RETIRED); + return EntityTaskResultTestCompat.entityRetired(); }); AtomicInteger entity = new AtomicInteger(); AtomicInteger fallback = new AtomicInteger(); diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/EntityTaskResultTestCompat.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/EntityTaskResultTestCompat.java new file mode 100644 index 000000000..339e8b02d --- /dev/null +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/util/EntityTaskResultTestCompat.java @@ -0,0 +1,45 @@ +package com.bencodez.votingplugin.util; + +import java.util.concurrent.CompletableFuture; + +/** + * Test statuses for code that intentionally treats Folia's shaded entity-task result + * as an opaque enum. Keeping tests independent of the relocated FoliaLib enum lets + * Eclipse resolve the project whether SimpleAPI comes from the workspace or Maven. + */ +public final class EntityTaskResultTestCompat { + + private enum Status { + SUCCESS, + ENTITY_RETIRED, + SCHEDULER_RETIRED + } + + private EntityTaskResultTestCompat() { + } + + @SuppressWarnings("rawtypes") + public static CompletableFuture success() { + return CompletableFuture.completedFuture(Status.SUCCESS); + } + + @SuppressWarnings("rawtypes") + public static CompletableFuture entityRetired() { + return CompletableFuture.completedFuture(Status.ENTITY_RETIRED); + } + + @SuppressWarnings("rawtypes") + public static CompletableFuture schedulerRetired() { + return CompletableFuture.completedFuture(Status.SCHEDULER_RETIRED); + } + + @SuppressWarnings("rawtypes") + public static CompletableFuture pending() { + return new CompletableFuture(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void completeSchedulerRetired(CompletableFuture future) { + future.complete(Status.SCHEDULER_RETIRED); + } +} diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseServiceTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseServiceTest.java index b167151eb..4df8983fe 100644 --- a/VotingPlugin/src/test/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseServiceTest.java +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/voteshop/service/VoteShopPurchaseServiceTest.java @@ -1,5 +1,6 @@ package com.bencodez.votingplugin.voteshop.service; +import com.bencodez.votingplugin.util.EntityTaskResultTestCompat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -54,7 +55,6 @@ import com.bencodez.advancedcore.api.user.userstorage.mysql.MySQL; import com.bencodez.advancedcore.api.rewards.RewardHandler; import com.bencodez.advancedcore.api.rewards.RewardOptions; -import com.bencodez.simpleapi.folialib.enums.EntityTaskResult; import com.bencodez.votingplugin.VotingPluginMain; import com.bencodez.votingplugin.user.SharedMysqlCacheReconciler; import com.bencodez.votingplugin.voteshop.shop.VoteShopDefinition; @@ -676,7 +676,7 @@ void sharedMysqlDebitIsRefundedWhenEntitySchedulerRetiresWithoutFallback() throw return null; }).when(scheduler).runTask(eq(plugin), any(Runnable.class), eq(player)); when(entityScheduler.runAtEntityWithFallback(org.mockito.ArgumentMatchers.eq(player), any(), - any(Runnable.class))).thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + any(Runnable.class))).thenReturn(EntityTaskResultTestCompat.schedulerRetired()); new VoteShopPurchaseService(plugin, definition).purchase(player, user, item, result -> { completionResult.set(result); completions.incrementAndGet(); @@ -745,7 +745,7 @@ void rejectedClaimedRewardQueuesDurableRefundAndFencesLateCallback() throws Exce @SuppressWarnings("rawtypes") ArgumentCaptor callback = ArgumentCaptor.forClass(java.util.function.Consumer.class); when(entityScheduler.runAtEntityWithFallback(any(), callback.capture(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); SharedMysqlPurchaseJournal journal = mock(SharedMysqlPurchaseJournal.class); when(journal.markCompensating("purchase-1")).thenReturn(true); when(journal.refundCompensatingReward("purchase-1")).thenReturn(false); @@ -811,7 +811,7 @@ void rejectedCompensationExecutorStillRunsTheDurableRefund() throws Exception { when(folia.getImpl()).thenReturn(entityScheduler); when(plugin.getTimer()).thenReturn(persistenceExecutor); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); org.mockito.Mockito.doThrow(new java.util.concurrent.RejectedExecutionException("stopping")) .when(persistenceExecutor).execute(any(Runnable.class)); SharedMysqlPurchaseJournal journal = mock(SharedMysqlPurchaseJournal.class); @@ -848,7 +848,7 @@ void synchronousAsyncClaimRejectionSchedulesCompensationOffTheEntityLane() throw @SuppressWarnings("rawtypes") java.util.function.Consumer callback = invocation.getArgument(1, java.util.function.Consumer.class); callback.accept(null); - return CompletableFuture.completedFuture(EntityTaskResult.SUCCESS); + return EntityTaskResultTestCompat.success(); }).when(entityScheduler).runAtEntityWithFallback(any(), any(), any(Runnable.class)); org.mockito.Mockito.doThrow(new java.util.concurrent.RejectedExecutionException("stopping")) .when(scheduler).runTaskAsynchronously(eq(plugin), any(Runnable.class)); @@ -906,7 +906,7 @@ void rejectedClaimedRewardSettlementUsesAsyncFallbackAndCompletes() throws Excep @SuppressWarnings("rawtypes") ArgumentCaptor rewardCallback = ArgumentCaptor.forClass(java.util.function.Consumer.class); when(entityScheduler.runAtEntityWithFallback(eq(player), rewardCallback.capture(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS)); + .thenReturn(EntityTaskResultTestCompat.success()); VotingPluginUser user = mock(VotingPluginUser.class); when(user.getPlayerName()).thenReturn("player"); @@ -967,8 +967,8 @@ void successfulRewardSettlesWhenPlayerRetiresBeforePresentation() throws Excepti @SuppressWarnings("rawtypes") ArgumentCaptor entityTask = ArgumentCaptor.forClass(java.util.function.Consumer.class); when(entityScheduler.runAtEntityWithFallback(eq(player), entityTask.capture(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS), - CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.success(), + EntityTaskResultTestCompat.schedulerRetired()); SharedMysqlPurchaseJournal journal = mock(SharedMysqlPurchaseJournal.class); when(journal.complete("purchase-1")).thenReturn(true); VoteShopPurchaseService.SharedPurchaseDebit debit = new VoteShopPurchaseService.SharedPurchaseDebit( @@ -1017,7 +1017,7 @@ void claimedRewardFailureCompletesCallerAndRetainsJournalForReconciliation() thr @SuppressWarnings("rawtypes") ArgumentCaptor rewardCallback = ArgumentCaptor.forClass(java.util.function.Consumer.class); when(entityScheduler.runAtEntityWithFallback(eq(player), rewardCallback.capture(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS)); + .thenReturn(EntityTaskResultTestCompat.success()); SharedMysqlPurchaseJournal journal = mock(SharedMysqlPurchaseJournal.class); VoteShopPurchaseService.SharedPurchaseDebit debit = new VoteShopPurchaseService.SharedPurchaseDebit( VoteShopPurchaseResult.SUCCESS, journal, "purchase-1", "Points", null); @@ -1161,7 +1161,7 @@ void rejectedCompensationSchedulersLeaveADurableRecoveryMarker(@TempDir Path tem when(plugin.getTimer()).thenReturn(persistenceExecutor); when(plugin.getDataFolder()).thenReturn(temporaryDirectory.toFile()); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); org.mockito.Mockito.doThrow(new java.util.concurrent.RejectedExecutionException("stopping")) .when(persistenceExecutor).execute(any(Runnable.class)); org.mockito.Mockito.doThrow(new java.util.concurrent.RejectedExecutionException("disabling")) @@ -1189,7 +1189,7 @@ void failedCompensationMarkerIsRetriedByPeriodicRecovery(@TempDir Path temporary com.bencodez.simpleapi.folialib.impl.ServerImplementation entityScheduler = plugin.getBukkitScheduler().getFoliaLib().getImpl(); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); SharedMysqlPurchaseJournal journal = mock(SharedMysqlPurchaseJournal.class); when(journal.markCompensating("purchase-1")) .thenThrow(new java.sql.SQLException("down")) @@ -1224,7 +1224,7 @@ private static VotingPluginMain mockPluginForCompensation(Path dataDirectory) { com.bencodez.simpleapi.folialib.impl.ServerImplementation entityScheduler = plugin.getBukkitScheduler().getFoliaLib().getImpl(); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SCHEDULER_RETIRED)); + .thenReturn(EntityTaskResultTestCompat.schedulerRetired()); return plugin; } @@ -1538,7 +1538,7 @@ void sharedPurchaseKeepsRewardConfigurationFromBeforeShopReload() throws Excepti when(scheduler.getFoliaLib()).thenReturn(folia); when(folia.getImpl()).thenReturn(entityScheduler); when(entityScheduler.runAtEntityWithFallback(any(), any(), any(Runnable.class))) - .thenReturn(CompletableFuture.completedFuture(EntityTaskResult.SUCCESS)); + .thenReturn(EntityTaskResultTestCompat.success()); VoteShopDefinition definition = mock(VoteShopDefinition.class); when(definition.isEnabled()).thenReturn(true); when(definition.getTitle()).thenReturn("Vote Shop");