diff --git a/src/test/java/us/eunoians/mcrpg/ability/impl/swords/RageSpikeTest.java b/src/test/java/us/eunoians/mcrpg/ability/impl/swords/RageSpikeTest.java
index d8cc53570..4c57c1037 100644
--- a/src/test/java/us/eunoians/mcrpg/ability/impl/swords/RageSpikeTest.java
+++ b/src/test/java/us/eunoians/mcrpg/ability/impl/swords/RageSpikeTest.java
@@ -6,23 +6,25 @@
import dev.dejvokep.boostedyaml.route.Route;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import us.eunoians.mcrpg.McRPGBaseTest;
import us.eunoians.mcrpg.configuration.FileManager;
import us.eunoians.mcrpg.configuration.FileType;
+import us.eunoians.mcrpg.configuration.file.localization.LocalizationKey;
import us.eunoians.mcrpg.configuration.file.skill.SwordsConfigFile;
import us.eunoians.mcrpg.registry.manager.McRPGManagerKey;
+import us.eunoians.mcrpg.skill.impl.swords.Swords;
+import us.eunoians.mcrpg.util.McRPGMethods;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
- * Tests for {@link RageSpike} tier-dependent configuration value resolution.
- *
- * Verifies that {@code getDamage} and {@code getVelocity} correctly evaluate formulas
- * through the {@link com.diamonddagger590.mccore.parser.Parser} and handle plain
- * integer literals.
+ * Tests for {@link RageSpike} tier-dependent configuration value resolution,
+ * simple accessors, and route/key identity methods.
*/
class RageSpikeTest extends McRPGBaseTest {
@@ -40,50 +42,184 @@ void setUp() {
rageSpike = new RageSpike(mcRPG);
}
- @Test
- @DisplayName("Given a damage formula, when getDamage is called with a tier, then the formula is evaluated")
- void getDamage_evaluatesFormulaWithTier() {
- int tier = 4;
- Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
- Route damageAllTiers = Route.addTo(allTiersRoute, "damage");
- Route tierRoute = Route.addTo(
- Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "damage");
+ @Nested
+ @DisplayName("getDamage")
+ class GetDamage {
- when(swordsConfig.contains(tierRoute)).thenReturn(false);
- when(swordsConfig.getString(damageAllTiers)).thenReturn("2*tier");
+ @Test
+ @DisplayName("Given a damage formula in all-tiers, when getDamage is called, then the formula is evaluated with the tier variable")
+ void getDamage_evaluatesFormulaWithTier() {
+ int tier = 4;
+ Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
+ Route damageAllTiers = Route.addTo(allTiersRoute, "damage");
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "damage");
- // tier=4 → 2*4 = 8.0
- assertEquals(8.0, rageSpike.getDamage(tier), 0.001);
+ when(swordsConfig.contains(tierRoute)).thenReturn(false);
+ when(swordsConfig.getString(damageAllTiers)).thenReturn("2*tier");
+
+ assertEquals(8.0, rageSpike.getDamage(tier), 0.001);
+ }
+
+ @Test
+ @DisplayName("Given a plain integer literal in YAML, when getDamage is called, then it returns the literal value")
+ void getDamage_returnsLiteralValue_whenGivenPlainInteger() {
+ int tier = 1;
+ Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
+ Route damageAllTiers = Route.addTo(allTiersRoute, "damage");
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "damage");
+
+ when(swordsConfig.contains(tierRoute)).thenReturn(false);
+ when(swordsConfig.getString(damageAllTiers)).thenReturn("5");
+
+ assertEquals(5.0, rageSpike.getDamage(tier), 0.001);
+ }
+
+ @Test
+ @DisplayName("Given a tier-specific override, when getDamage is called, then the tier-specific value is used")
+ void getDamage_usesTierSpecificOverride_whenPresent() {
+ int tier = 3;
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "damage");
+
+ when(swordsConfig.contains(tierRoute)).thenReturn(true);
+ when(swordsConfig.getString(tierRoute)).thenReturn("12");
+
+ assertEquals(12.0, rageSpike.getDamage(tier), 0.001);
+ }
}
- @Test
- @DisplayName("Given a plain integer literal in YAML, when getDamage is called, then it returns the literal value")
- void getDamage_returnsLiteralValue_whenGivenPlainInteger() {
- int tier = 1;
- Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
- Route damageAllTiers = Route.addTo(allTiersRoute, "damage");
- Route tierRoute = Route.addTo(
- Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "damage");
+ @Nested
+ @DisplayName("getVelocity")
+ class GetVelocity {
+
+ @Test
+ @DisplayName("Given a velocity formula in all-tiers, when getVelocity is called, then the formula is evaluated")
+ void getVelocity_evaluatesFormulaWithTier() {
+ int tier = 4;
+ Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
+ Route velocityAllTiers = Route.addTo(allTiersRoute, "velocity");
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "velocity");
- when(swordsConfig.contains(tierRoute)).thenReturn(false);
- when(swordsConfig.getString(damageAllTiers)).thenReturn("5");
+ when(swordsConfig.contains(tierRoute)).thenReturn(false);
+ when(swordsConfig.getString(velocityAllTiers, "5")).thenReturn("tier+2");
- assertEquals(5.0, rageSpike.getDamage(tier), 0.001);
+ // tier=4 → 4+2 = 6, distinct from the default of 5
+ assertEquals(6, rageSpike.getVelocity(tier));
+ }
+
+ @Test
+ @DisplayName("Given a tier-specific override, when getVelocity is called, then the override is used")
+ void getVelocity_usesTierSpecificOverride_whenPresent() {
+ int tier = 2;
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "velocity");
+
+ when(swordsConfig.contains(tierRoute)).thenReturn(true);
+ when(swordsConfig.getString(tierRoute)).thenReturn("10");
+
+ assertEquals(10, rageSpike.getVelocity(tier));
+ }
+
+ @Test
+ @DisplayName("Given no config value, when getVelocity is called, then the default of 5 is used")
+ void getVelocity_usesDefault_whenNoConfigValue() {
+ int tier = 1;
+ Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
+ Route velocityAllTiers = Route.addTo(allTiersRoute, "velocity");
+ Route tierRoute = Route.addTo(
+ Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "velocity");
+
+ when(swordsConfig.contains(tierRoute)).thenReturn(false);
+ when(swordsConfig.getString(velocityAllTiers, "5")).thenReturn("5");
+
+ assertEquals(5, rageSpike.getVelocity(tier));
+ }
}
- @Test
- @DisplayName("Given a velocity formula, when getVelocity is called with a tier, then the formula is evaluated")
- void getVelocity_evaluatesFormulaWithTier() {
- int tier = 3;
- Route allTiersRoute = Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "all-tiers");
- Route velocityAllTiers = Route.addTo(allTiersRoute, "velocity");
- Route tierRoute = Route.addTo(
- Route.addTo(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, "tier-" + tier), "velocity");
+ @Nested
+ @DisplayName("getMaxVerticalVelocity")
+ class GetMaxVerticalVelocity {
+
+ @Test
+ @DisplayName("Given a configured max vertical velocity, when getMaxVerticalVelocity is called, then it returns the configured value")
+ void getMaxVerticalVelocity_returnsConfiguredValue() {
+ when(swordsConfig.getDouble(SwordsConfigFile.RAGE_SPIKE_MAX_VERTICAL_VELOCITY, 0.3)).thenReturn(0.5);
+
+ assertEquals(0.5, rageSpike.getMaxVerticalVelocity(), 0.001);
+ }
+
+ @Test
+ @DisplayName("Given no config value, when getMaxVerticalVelocity is called, then the default 0.3 is returned")
+ void getMaxVerticalVelocity_returnsDefault_whenNotConfigured() {
+ when(swordsConfig.getDouble(SwordsConfigFile.RAGE_SPIKE_MAX_VERTICAL_VELOCITY, 0.3)).thenReturn(0.3);
+
+ assertEquals(0.3, rageSpike.getMaxVerticalVelocity(), 0.001);
+ }
+ }
+
+ @Nested
+ @DisplayName("getMaxTier")
+ class GetMaxTier {
+
+ @Test
+ @DisplayName("Given a configured amount of tiers, when getMaxTier is called, then the configured value is returned")
+ void getMaxTier_returnsConfiguredValue() {
+ when(swordsConfig.getInt(SwordsConfigFile.RAGE_SPIKE_AMOUNT_OF_TIERS)).thenReturn(5);
+
+ assertEquals(5, rageSpike.getMaxTier());
+ }
+ }
+
+ @Nested
+ @DisplayName("Identity and routes")
+ class IdentityAndRoutes {
+
+ @Test
+ @DisplayName("getAbilityKey returns rage_spike key under mcrpg namespace")
+ void getAbilityKey_returnsRageSpikeKey() {
+ assertEquals(RageSpike.RAGE_SPIKE_KEY, rageSpike.getAbilityKey());
+ assertEquals("mcrpg", rageSpike.getAbilityKey().getNamespace());
+ assertEquals("rage_spike", rageSpike.getAbilityKey().getKey());
+ }
+
+ @Test
+ @DisplayName("getDatabaseName returns rage_spike")
+ void getDatabaseName_returnsRageSpike() {
+ assertEquals("rage_spike", rageSpike.getDatabaseName());
+ }
+
+ @Test
+ @DisplayName("getSkillKey returns Swords key")
+ void getSkillKey_returnsSwordsKey() {
+ assertEquals(Swords.SWORDS_KEY, rageSpike.getSkillKey());
+ }
+
+ @Test
+ @DisplayName("getAbilityEnabledRoute returns the rage spike enabled route")
+ void getAbilityEnabledRoute_returnsRageSpikeEnabledRoute() {
+ assertEquals(SwordsConfigFile.RAGE_SPIKE_ENABLED, rageSpike.getAbilityEnabledRoute());
+ }
+
+ @Test
+ @DisplayName("getDisplayItemRoute returns the rage spike display item header route")
+ void getDisplayItemRoute_returnsRageSpikeDisplayItemRoute() {
+ assertEquals(LocalizationKey.RAGE_SPIKE_DISPLAY_ITEM_HEADER, rageSpike.getDisplayItemRoute());
+ }
- when(swordsConfig.contains(tierRoute)).thenReturn(false);
- when(swordsConfig.getString(velocityAllTiers, "5")).thenReturn("tier+2");
+ @Test
+ @DisplayName("getAbilityTierConfigurationRoute returns the rage spike tier config header")
+ void getAbilityTierConfigurationRoute_returnsRageSpikeTierConfigHeader() {
+ assertEquals(SwordsConfigFile.RAGE_SPIKE_CONFIGURATION_HEADER, rageSpike.getAbilityTierConfigurationRoute());
+ }
- // tier=3 → 3+2 = 5
- assertEquals(5, rageSpike.getVelocity(tier));
+ @Test
+ @DisplayName("getYamlDocument returns the swords config from FileManager")
+ void getYamlDocument_returnsSwordsConfig() {
+ assertNotNull(rageSpike.getYamlDocument());
+ assertEquals(swordsConfig, rageSpike.getYamlDocument());
+ }
}
}
diff --git a/src/test/java/us/eunoians/mcrpg/quest/board/distribution/RewardDistributionGranterTest.java b/src/test/java/us/eunoians/mcrpg/quest/board/distribution/RewardDistributionGranterTest.java
index 0eb2acaa5..70442aec7 100644
--- a/src/test/java/us/eunoians/mcrpg/quest/board/distribution/RewardDistributionGranterTest.java
+++ b/src/test/java/us/eunoians/mcrpg/quest/board/distribution/RewardDistributionGranterTest.java
@@ -1,13 +1,23 @@
package us.eunoians.mcrpg.quest.board.distribution;
+import com.diamonddagger590.mccore.database.Database;
+import com.diamonddagger590.mccore.registry.RegistryAccess;
+import com.diamonddagger590.mccore.registry.RegistryKey;
+import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockbukkit.mockbukkit.entity.PlayerMock;
import us.eunoians.mcrpg.McRPGBaseTest;
+import us.eunoians.mcrpg.configuration.FileManager;
+import us.eunoians.mcrpg.configuration.FileType;
+import us.eunoians.mcrpg.configuration.file.MainConfigFile;
+import us.eunoians.mcrpg.database.McRPGDatabaseManager;
import us.eunoians.mcrpg.quest.reward.QuestRewardType;
+import us.eunoians.mcrpg.registry.manager.McRPGManagerKey;
import us.eunoians.mcrpg.util.McRPGMethods;
import java.util.ArrayList;
@@ -15,11 +25,17 @@
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
-public class RewardDistributionGranterTest extends McRPGBaseTest {
+class RewardDistributionGranterTest extends McRPGBaseTest {
private static final NamespacedKey QUEST_KEY = new NamespacedKey(McRPGMethods.getMcRPGNamespace(), "test_quest");
@@ -27,6 +43,7 @@ public class RewardDistributionGranterTest extends McRPGBaseTest {
@org.junit.jupiter.api.BeforeEach
void setUp() {
+ TrackingRewardType.GRANTED_TO.clear();
granter = new RewardDistributionGranter(mcRPG);
}
@@ -77,81 +94,142 @@ public void grant(@org.jetbrains.annotations.NotNull Player player) {
}
}
- @DisplayName("Online player receives reward immediately via grant()")
- @Test
- void onlinePlayer_rewardGrantedImmediately() {
- TrackingRewardType.GRANTED_TO.clear();
- PlayerMock player = server.addPlayer();
- UUID playerUUID = player.getUniqueId();
+ @Nested
+ @DisplayName("Online player grants")
+ class OnlinePlayerGrants {
- var reward = new TrackingRewardType(100);
- Map> resolved = Map.of(playerUUID, List.of(reward));
+ @DisplayName("Online player receives reward immediately via grant()")
+ @Test
+ void onlinePlayer_rewardGrantedImmediately() {
+ PlayerMock player = server.addPlayer();
+ UUID playerUUID = player.getUniqueId();
- granter.grant(resolved, QUEST_KEY);
+ var reward = new TrackingRewardType(100);
+ Map> resolved = Map.of(playerUUID, List.of(reward));
- assertEquals(1, TrackingRewardType.GRANTED_TO.size());
- assertEquals(playerUUID, TrackingRewardType.GRANTED_TO.get(0));
- }
+ granter.grant(resolved, QUEST_KEY);
- @DisplayName("Empty rewards map results in no-op")
- @Test
- void emptyRewardsMap_noOp() {
- TrackingRewardType.GRANTED_TO.clear();
- Map> resolved = Map.of();
+ assertEquals(1, TrackingRewardType.GRANTED_TO.size());
+ assertEquals(playerUUID, TrackingRewardType.GRANTED_TO.get(0));
+ }
- granter.grant(resolved, QUEST_KEY);
+ @DisplayName("Multiple rewards for one player are all granted")
+ @Test
+ void multipleRewards_allGranted() {
+ PlayerMock player = server.addPlayer();
+ UUID playerUUID = player.getUniqueId();
- assertTrue(TrackingRewardType.GRANTED_TO.isEmpty());
- }
+ var r1 = new TrackingRewardType(100);
+ var r2 = new TrackingRewardType(200);
+ var r3 = new TrackingRewardType(300);
+ Map> resolved = Map.of(playerUUID, List.of(r1, r2, r3));
- @DisplayName("Player with empty reward list results in no grant call")
- @Test
- void playerWithEmptyRewardList_noGrant() {
- TrackingRewardType.GRANTED_TO.clear();
- PlayerMock player = server.addPlayer();
+ granter.grant(resolved, QUEST_KEY);
- Map> resolved = Map.of(player.getUniqueId(), List.of());
+ assertEquals(3, TrackingRewardType.GRANTED_TO.size());
+ assertTrue(TrackingRewardType.GRANTED_TO.stream().allMatch(uuid -> uuid.equals(playerUUID)));
+ }
+
+ @DisplayName("Multiple online players each receive their own rewards")
+ @Test
+ void multipleOnlinePlayers_eachReceivesOwn() {
+ PlayerMock player1 = server.addPlayer();
+ PlayerMock player2 = server.addPlayer();
- granter.grant(resolved, QUEST_KEY);
+ var reward = new TrackingRewardType(500);
+ Map> resolved = Map.of(
+ player1.getUniqueId(), List.of(reward),
+ player2.getUniqueId(), List.of(reward)
+ );
- assertTrue(TrackingRewardType.GRANTED_TO.isEmpty());
+ granter.grant(resolved, QUEST_KEY);
+
+ assertEquals(2, TrackingRewardType.GRANTED_TO.size());
+ assertTrue(TrackingRewardType.GRANTED_TO.contains(player1.getUniqueId()));
+ assertTrue(TrackingRewardType.GRANTED_TO.contains(player2.getUniqueId()));
+ }
}
- @DisplayName("Multiple rewards for one player are all granted")
- @Test
- void multipleRewards_allGranted() {
- TrackingRewardType.GRANTED_TO.clear();
- PlayerMock player = server.addPlayer();
- UUID playerUUID = player.getUniqueId();
+ @Nested
+ @DisplayName("Edge cases")
+ class EdgeCases {
+
+ @DisplayName("Empty rewards map results in no-op")
+ @Test
+ void emptyRewardsMap_noOp() {
+ Map> resolved = Map.of();
- var r1 = new TrackingRewardType(100);
- var r2 = new TrackingRewardType(200);
- var r3 = new TrackingRewardType(300);
- Map> resolved = Map.of(playerUUID, List.of(r1, r2, r3));
+ granter.grant(resolved, QUEST_KEY);
- granter.grant(resolved, QUEST_KEY);
+ assertTrue(TrackingRewardType.GRANTED_TO.isEmpty());
+ }
- assertEquals(3, TrackingRewardType.GRANTED_TO.size());
- assertTrue(TrackingRewardType.GRANTED_TO.stream().allMatch(uuid -> uuid.equals(playerUUID)));
+ @DisplayName("Player with empty reward list results in no grant call")
+ @Test
+ void playerWithEmptyRewardList_noGrant() {
+ PlayerMock player = server.addPlayer();
+
+ Map> resolved = Map.of(player.getUniqueId(), List.of());
+
+ granter.grant(resolved, QUEST_KEY);
+
+ assertTrue(TrackingRewardType.GRANTED_TO.isEmpty());
+ }
}
- @DisplayName("Multiple online players each receive their own rewards")
- @Test
- void multipleOnlinePlayers_eachReceivesOwn() {
- TrackingRewardType.GRANTED_TO.clear();
- PlayerMock player1 = server.addPlayer();
- PlayerMock player2 = server.addPlayer();
+ @Nested
+ @DisplayName("Offline player path")
+ class OfflinePlayerPath {
+
+ private void registerMockDatabaseManager() {
+ FileManager fileManager = RegistryAccess.registryAccess()
+ .registry(RegistryKey.MANAGER)
+ .manager(McRPGManagerKey.FILE);
+ YamlDocument mainConfig = mock(YamlDocument.class);
+ when(fileManager.getFile(FileType.MAIN_CONFIG)).thenReturn(mainConfig);
+ when(mainConfig.getInt(MainConfigFile.QUEST_PENDING_REWARDS_EXPIRY_DAYS, 30)).thenReturn(30);
+
+ Database mockDatabase = mock(Database.class);
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
+ when(mockDatabase.getDatabaseExecutorService()).thenReturn(executor);
+
+ McRPGDatabaseManager mockDbManager = mock(McRPGDatabaseManager.class);
+ when(mockDbManager.getDatabase()).thenReturn(mockDatabase);
+ RegistryAccess.registryAccess().registry(RegistryKey.MANAGER).register(mockDbManager);
+ }
+
+ @Test
+ @DisplayName("Given an offline player UUID, when grant is called, then no immediate reward grant occurs")
+ void offlinePlayer_noImmediateGrant() {
+ registerMockDatabaseManager();
+ UUID offlinePlayerUUID = UUID.randomUUID();
- var reward = new TrackingRewardType(500);
- Map> resolved = Map.of(
- player1.getUniqueId(), List.of(reward),
- player2.getUniqueId(), List.of(reward)
- );
+ var reward = new TrackingRewardType(100);
+ Map> resolved = Map.of(offlinePlayerUUID, List.of(reward));
- granter.grant(resolved, QUEST_KEY);
+ granter.grant(resolved, QUEST_KEY);
- assertEquals(2, TrackingRewardType.GRANTED_TO.size());
- assertTrue(TrackingRewardType.GRANTED_TO.contains(player1.getUniqueId()));
- assertTrue(TrackingRewardType.GRANTED_TO.contains(player2.getUniqueId()));
+ assertTrue(TrackingRewardType.GRANTED_TO.isEmpty(),
+ "Offline player should not receive an immediate grant");
+ }
+
+ @Test
+ @DisplayName("Given a mix of online and offline players, when grant is called, then only the online player receives immediate grants")
+ void mixedOnlineOffline_onlyOnlineReceivesImmediateGrant() {
+ registerMockDatabaseManager();
+ PlayerMock onlinePlayer = server.addPlayer();
+ UUID offlinePlayerUUID = UUID.randomUUID();
+
+ var reward = new TrackingRewardType(100);
+ Map> resolved = Map.of(
+ onlinePlayer.getUniqueId(), List.of(reward),
+ offlinePlayerUUID, List.of(reward)
+ );
+
+ granter.grant(resolved, QUEST_KEY);
+
+ assertEquals(1, TrackingRewardType.GRANTED_TO.size());
+ assertEquals(onlinePlayer.getUniqueId(), TrackingRewardType.GRANTED_TO.get(0));
+ }
}
}
diff --git a/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/PermissionQuestScopeProviderTest.java b/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/PermissionQuestScopeProviderTest.java
index 53f1294a2..4f3c372cb 100644
--- a/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/PermissionQuestScopeProviderTest.java
+++ b/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/PermissionQuestScopeProviderTest.java
@@ -1,87 +1,283 @@
package us.eunoians.mcrpg.quest.impl.scope.impl;
import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
+import org.mockbukkit.mockbukkit.entity.PlayerMock;
import us.eunoians.mcrpg.McRPGBaseTest;
import us.eunoians.mcrpg.expansion.McRPGExpansion;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
class PermissionQuestScopeProviderTest extends McRPGBaseTest {
- @DisplayName("getKey returns permission_scope key")
- @Test
- void getKey_returnsPermissionScopeKey() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- assertEquals(PermissionQuestScope.PERMISSION_SCOPE_KEY, provider.getKey());
- assertEquals("mcrpg:permission_scope", provider.getKey().toString());
- }
+ @Nested
+ @DisplayName("Identity")
+ class Identity {
+
+ @DisplayName("getKey returns permission_scope key")
+ @Test
+ void getKey_returnsPermissionScopeKey() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ assertEquals(PermissionQuestScope.PERMISSION_SCOPE_KEY, provider.getKey());
+ assertEquals("mcrpg:permission_scope", provider.getKey().toString());
+ }
- @DisplayName("getExpansionKey returns McRPG expansion key")
- @Test
- void getExpansionKey_returnsMcRPGExpansionKey() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- assertTrue(provider.getExpansionKey().isPresent());
- assertEquals(McRPGExpansion.EXPANSION_KEY, provider.getExpansionKey().orElseThrow());
+ @DisplayName("getExpansionKey returns McRPG expansion key")
+ @Test
+ void getExpansionKey_returnsMcRPGExpansionKey() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ assertTrue(provider.getExpansionKey().isPresent());
+ assertEquals(McRPGExpansion.EXPANSION_KEY, provider.getExpansionKey().orElseThrow());
+ }
}
- @DisplayName("withPermissionNode returns this for chaining")
- @Test
- void withPermissionNode_returnsThisForChaining() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- PermissionQuestScopeProvider result = provider.withPermissionNode("mcrpg.quest.vip");
- assertEquals(provider, result);
+ @Nested
+ @DisplayName("withPermissionNode")
+ class WithPermissionNode {
+
+ @DisplayName("withPermissionNode returns this for chaining")
+ @Test
+ void withPermissionNode_returnsThisForChaining() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ PermissionQuestScopeProvider result = provider.withPermissionNode("mcrpg.quest.vip");
+ assertEquals(provider, result);
+ }
}
- @DisplayName("createNewScope returns scope with correct quest UUID and permission")
- @Test
- void createNewScope_returnsScope_withCorrectFields() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- provider.withPermissionNode("mcrpg.quest.test");
- UUID questUUID = UUID.randomUUID();
+ @Nested
+ @DisplayName("createNewScope")
+ class CreateNewScope {
- PermissionQuestScope scope = provider.createNewScope(questUUID);
+ @DisplayName("createNewScope returns scope with correct quest UUID and permission")
+ @Test
+ void createNewScope_returnsScope_withCorrectFields() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ provider.withPermissionNode("mcrpg.quest.test");
+ UUID questUUID = UUID.randomUUID();
- assertNotNull(scope);
- assertEquals(questUUID, scope.getQuestUUID());
- assertEquals("mcrpg.quest.test", scope.getPermissionNode().orElseThrow());
- }
+ PermissionQuestScope scope = provider.createNewScope(questUUID);
+
+ assertNotNull(scope);
+ assertEquals(questUUID, scope.getQuestUUID());
+ assertEquals("mcrpg.quest.test", scope.getPermissionNode().orElseThrow());
+ }
+
+ @DisplayName("createNewScope throws when permission not set")
+ @Test
+ void createNewScope_throwsIllegalStateException_whenPermissionNotSet() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ assertThrows(IllegalStateException.class, () -> provider.createNewScope(UUID.randomUUID()));
+ }
+
+ @DisplayName("createNewScope returns valid scope")
+ @Test
+ void createNewScope_returnsValidScope() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ provider.withPermissionNode("mcrpg.quest.test");
+
+ PermissionQuestScope scope = provider.createNewScope(UUID.randomUUID());
+
+ assertTrue(scope.isScopeValid());
+ }
+
+ @DisplayName("Each createNewScope call returns a distinct scope")
+ @Test
+ void createNewScope_returnsDistinctScopes() {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ provider.withPermissionNode("mcrpg.quest.test");
+ UUID questUUID1 = UUID.randomUUID();
+ UUID questUUID2 = UUID.randomUUID();
+
+ PermissionQuestScope scope1 = provider.createNewScope(questUUID1);
+ PermissionQuestScope scope2 = provider.createNewScope(questUUID2);
- @DisplayName("createNewScope throws when permission not set")
- @Test
- void createNewScope_throwsIllegalStateException_whenPermissionNotSet() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- assertThrows(IllegalStateException.class, () -> provider.createNewScope(UUID.randomUUID()));
+ assertEquals(questUUID1, scope1.getQuestUUID());
+ assertEquals(questUUID2, scope2.getQuestUUID());
+ }
}
- @DisplayName("createNewScope returns valid scope")
- @Test
- void createNewScope_returnsValidScope() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- provider.withPermissionNode("mcrpg.quest.test");
+ @Nested
+ @DisplayName("resolveActiveQuestUUIDs")
+ class ResolveActiveQuestUUIDs {
+
+ @Test
+ @DisplayName("Given active permission quests and an online player with matching permission, when resolveActiveQuestUUIDs is called, then matching quest UUIDs are returned")
+ void resolveActiveQuestUUIDs_returnsMatching_whenOnlinePlayerHasPermission() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ PlayerMock playerMock = server.addPlayer();
+ UUID playerUUID = playerMock.getUniqueId();
+ UUID questUUID = UUID.randomUUID();
+ String permNode = "mcrpg.quest.vip";
+
+ playerMock.addAttachment(mcRPG, permNode, true);
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true, false);
+ when(rs.getString("quest_uuid")).thenReturn(questUUID.toString());
+ when(rs.getString("permission_node")).thenReturn(permNode);
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
+
+ assertEquals(1, result.size());
+ assertEquals(questUUID, result.get(0));
+ }
+
+ @Test
+ @DisplayName("Given active permission quests and an online player without the permission, when resolveActiveQuestUUIDs is called, then empty list is returned")
+ void resolveActiveQuestUUIDs_returnsEmpty_whenOnlinePlayerLacksPermission() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ PlayerMock playerMock = server.addPlayer();
+ UUID playerUUID = playerMock.getUniqueId();
+ UUID questUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true, false);
+ when(rs.getString("quest_uuid")).thenReturn(questUUID.toString());
+ when(rs.getString("permission_node")).thenReturn("mcrpg.quest.vip");
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
+
+ assertTrue(result.isEmpty());
+ }
- PermissionQuestScope scope = provider.createNewScope(UUID.randomUUID());
+ @Test
+ @DisplayName("Given no active permission quests in the database, when resolveActiveQuestUUIDs is called, then empty list is returned")
+ void resolveActiveQuestUUIDs_returnsEmpty_whenNoActiveQuests() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ UUID playerUUID = UUID.randomUUID();
- assertTrue(scope.isScopeValid());
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(false);
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
+
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ @DisplayName("Given multiple active quests, when player has permission for only one, then only that quest UUID is returned")
+ void resolveActiveQuestUUIDs_filtersCorrectly_whenPlayerHasPartialPermissions() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ PlayerMock playerMock = server.addPlayer();
+ UUID playerUUID = playerMock.getUniqueId();
+ UUID questWithPerm = UUID.randomUUID();
+ UUID questWithoutPerm = UUID.randomUUID();
+
+ playerMock.addAttachment(mcRPG, "mcrpg.quest.vip", true);
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true, true, false);
+ when(rs.getString("quest_uuid")).thenReturn(questWithPerm.toString(), questWithoutPerm.toString());
+ when(rs.getString("permission_node")).thenReturn("mcrpg.quest.vip", "mcrpg.quest.admin");
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
+
+ assertEquals(1, result.size());
+ assertEquals(questWithPerm, result.get(0));
+ }
}
- @DisplayName("Each createNewScope call returns a distinct scope")
- @Test
- void createNewScope_returnsDistinctScopes() {
- PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
- provider.withPermissionNode("mcrpg.quest.test");
- UUID questUUID1 = UUID.randomUUID();
- UUID questUUID2 = UUID.randomUUID();
+ @Nested
+ @DisplayName("loadScope(Connection, UUID)")
+ class LoadScope {
+
+ @Test
+ @DisplayName("Given a stored permission scope, when loadScope is called, then the scope has the correct permission node")
+ void loadScope_returnsScopeWithPermission_whenStoredInDatabase() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+ String permNode = "mcrpg.quest.vip";
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true);
+ when(rs.getString("permission_node")).thenReturn(permNode);
+
+ PermissionQuestScope scope = provider.loadScope(connection, questUUID);
+
+ assertNotNull(scope);
+ assertEquals(questUUID, scope.getQuestUUID());
+ assertTrue(scope.getPermissionNode().isPresent());
+ assertEquals(permNode, scope.getPermissionNode().orElseThrow());
+ }
+
+ @Test
+ @DisplayName("Given a stored permission scope, when loadScope is called, then the quest UUID is passed to the DAO")
+ void loadScope_passesQuestUUIDToDAO() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true);
+ when(rs.getString("permission_node")).thenReturn("mcrpg.quest.test");
+
+ provider.loadScope(connection, questUUID);
+
+ verify(ps).setString(1, questUUID.toString());
+ }
+
+ @Test
+ @DisplayName("Given a loaded scope, when isScopeValid is called, then it returns true")
+ void loadScope_returnsValidScope() throws SQLException {
+ PermissionQuestScopeProvider provider = new PermissionQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true);
+ when(rs.getString("permission_node")).thenReturn("mcrpg.quest.test");
- PermissionQuestScope scope1 = provider.createNewScope(questUUID1);
- PermissionQuestScope scope2 = provider.createNewScope(questUUID2);
+ PermissionQuestScope scope = provider.loadScope(connection, questUUID);
- assertEquals(questUUID1, scope1.getQuestUUID());
- assertEquals(questUUID2, scope2.getQuestUUID());
+ assertTrue(scope.isScopeValid());
+ }
}
}
diff --git a/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/SinglePlayerQuestScopeProviderTest.java b/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/SinglePlayerQuestScopeProviderTest.java
index 6cdf36332..48e7f387a 100644
--- a/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/SinglePlayerQuestScopeProviderTest.java
+++ b/src/test/java/us/eunoians/mcrpg/quest/impl/scope/impl/SinglePlayerQuestScopeProviderTest.java
@@ -1,68 +1,187 @@
package us.eunoians.mcrpg.quest.impl.scope.impl;
import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import us.eunoians.mcrpg.McRPGBaseTest;
import us.eunoians.mcrpg.expansion.McRPGExpansion;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
class SinglePlayerQuestScopeProviderTest extends McRPGBaseTest {
- @DisplayName("getKey returns single_player_scope key")
- @Test
- void getKey_returnsSinglePlayerScopeKey() {
- SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
- assertEquals(SinglePlayerQuestScopeProvider.KEY, provider.getKey());
- assertEquals("mcrpg:single_player_scope", provider.getKey().toString());
- }
+ @Nested
+ @DisplayName("Identity")
+ class Identity {
+
+ @DisplayName("getKey returns single_player_scope key")
+ @Test
+ void getKey_returnsSinglePlayerScopeKey() {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ assertEquals(SinglePlayerQuestScopeProvider.KEY, provider.getKey());
+ assertEquals("mcrpg:single_player_scope", provider.getKey().toString());
+ }
- @DisplayName("getExpansionKey returns McRPG expansion key")
- @Test
- void getExpansionKey_returnsMcRPGExpansionKey() {
- SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
- assertTrue(provider.getExpansionKey().isPresent());
- assertEquals(McRPGExpansion.EXPANSION_KEY, provider.getExpansionKey().orElseThrow());
+ @DisplayName("getExpansionKey returns McRPG expansion key")
+ @Test
+ void getExpansionKey_returnsMcRPGExpansionKey() {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ assertTrue(provider.getExpansionKey().isPresent());
+ assertEquals(McRPGExpansion.EXPANSION_KEY, provider.getExpansionKey().orElseThrow());
+ }
}
- @DisplayName("createNewScope returns scope with correct quest UUID")
- @Test
- void createNewScope_returnsScope_withCorrectQuestUUID() {
- SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
- UUID questUUID = UUID.randomUUID();
+ @Nested
+ @DisplayName("createNewScope")
+ class CreateNewScope {
+
+ @DisplayName("createNewScope returns scope with correct quest UUID")
+ @Test
+ void createNewScope_returnsScope_withCorrectQuestUUID() {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+
+ SinglePlayerQuestScope scope = provider.createNewScope(questUUID);
+
+ assertNotNull(scope);
+ assertEquals(questUUID, scope.getQuestUUID());
+ }
+
+ @DisplayName("createNewScope returns invalid scope (no player set)")
+ @Test
+ void createNewScope_returnsInvalidScope() {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+
+ SinglePlayerQuestScope scope = provider.createNewScope(UUID.randomUUID());
- SinglePlayerQuestScope scope = provider.createNewScope(questUUID);
+ assertTrue(scope.getPlayerInScope().isEmpty());
+ assertTrue(scope.getCurrentPlayersInScope().isEmpty());
+ }
- assertNotNull(scope);
- assertEquals(questUUID, scope.getQuestUUID());
+ @DisplayName("Each createNewScope call returns a distinct scope")
+ @Test
+ void createNewScope_returnsDistinctScopes() {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID questUUID1 = UUID.randomUUID();
+ UUID questUUID2 = UUID.randomUUID();
+
+ SinglePlayerQuestScope scope1 = provider.createNewScope(questUUID1);
+ SinglePlayerQuestScope scope2 = provider.createNewScope(questUUID2);
+
+ assertEquals(questUUID1, scope1.getQuestUUID());
+ assertEquals(questUUID2, scope2.getQuestUUID());
+ }
}
- @DisplayName("createNewScope returns invalid scope (no player set)")
- @Test
- void createNewScope_returnsInvalidScope() {
- SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ @Nested
+ @DisplayName("resolveActiveQuestUUIDs")
+ class ResolveActiveQuestUUIDs {
+
+ @Test
+ @DisplayName("Given active quests in the database, when resolveActiveQuestUUIDs is called, then the quest UUIDs are returned")
+ void resolveActiveQuestUUIDs_returnsQuestUUIDs_whenActiveQuestsExist() throws SQLException {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID playerUUID = UUID.randomUUID();
+ UUID questUUID1 = UUID.randomUUID();
+ UUID questUUID2 = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true, true, false);
+ when(rs.getString("quest_uuid")).thenReturn(questUUID1.toString(), questUUID2.toString());
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
- SinglePlayerQuestScope scope = provider.createNewScope(UUID.randomUUID());
+ assertEquals(2, result.size());
+ assertTrue(result.contains(questUUID1));
+ assertTrue(result.contains(questUUID2));
+ verify(ps).setString(1, playerUUID.toString());
+ }
- assertTrue(scope.getPlayerInScope().isEmpty());
- assertTrue(scope.getCurrentPlayersInScope().isEmpty());
+ @Test
+ @DisplayName("Given no active quests, when resolveActiveQuestUUIDs is called, then an empty list is returned")
+ void resolveActiveQuestUUIDs_returnsEmptyList_whenNoActiveQuests() throws SQLException {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID playerUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(false);
+
+ List result = provider.resolveActiveQuestUUIDs(playerUUID, connection);
+
+ assertTrue(result.isEmpty());
+ }
}
- @DisplayName("Each createNewScope call returns a distinct scope")
- @Test
- void createNewScope_returnsDistinctScopes() {
- SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
- UUID questUUID1 = UUID.randomUUID();
- UUID questUUID2 = UUID.randomUUID();
+ @Nested
+ @DisplayName("loadScope(Connection, UUID)")
+ class LoadScope {
+
+ @Test
+ @DisplayName("Given a stored scope, when loadScope is called, then the scope has the correct player set")
+ void loadScope_returnsScopeWithPlayer_whenStoredInDatabase() throws SQLException {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+ UUID playerUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true);
+ when(rs.getString("player_uuid")).thenReturn(playerUUID.toString());
+
+ SinglePlayerQuestScope scope = provider.loadScope(connection, questUUID);
+
+ assertNotNull(scope);
+ assertEquals(questUUID, scope.getQuestUUID());
+ assertTrue(scope.getPlayerInScope().isPresent());
+ assertEquals(playerUUID, scope.getPlayerInScope().orElseThrow());
+ }
+
+ @Test
+ @DisplayName("Given a stored scope, when loadScope is called, then the quest UUID parameter is passed to the DAO")
+ void loadScope_passesQuestUUIDToDAO() throws SQLException {
+ SinglePlayerQuestScopeProvider provider = new SinglePlayerQuestScopeProvider();
+ UUID questUUID = UUID.randomUUID();
+ UUID playerUUID = UUID.randomUUID();
+
+ Connection connection = mock(Connection.class);
+ PreparedStatement ps = mock(PreparedStatement.class);
+ ResultSet rs = mock(ResultSet.class);
+
+ when(connection.prepareStatement(anyString())).thenReturn(ps);
+ when(ps.executeQuery()).thenReturn(rs);
+ when(rs.next()).thenReturn(true);
+ when(rs.getString("player_uuid")).thenReturn(playerUUID.toString());
- SinglePlayerQuestScope scope1 = provider.createNewScope(questUUID1);
- SinglePlayerQuestScope scope2 = provider.createNewScope(questUUID2);
+ provider.loadScope(connection, questUUID);
- assertEquals(questUUID1, scope1.getQuestUUID());
- assertEquals(questUUID2, scope2.getQuestUUID());
+ verify(ps).setString(1, questUUID.toString());
+ }
}
}