From 38bd555b2401298ac54e3695bc2201fed0d4f608 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 27 Oct 2019 18:24:46 -0700 Subject: [PATCH] Added ChallengesManager test class --- .../challenges/ChallengesManager.java | 350 ++++++------ .../challenges/database/object/Challenge.java | 9 +- .../database/object/ChallengesPlayerData.java | 538 +++++++++--------- .../challenges/ChallengesManagerTest.java | 489 +++++++++++++--- 4 files changed, 837 insertions(+), 549 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesManager.java b/src/main/java/world/bentobox/challenges/ChallengesManager.java index d922ae7..20baf2f 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesManager.java @@ -19,6 +19,7 @@ import java.util.stream.Collectors; import org.bukkit.Bukkit; import org.bukkit.World; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.user.User; @@ -142,7 +143,7 @@ public class ChallengesManager { // Sort by challenges level order numbers return Integer.compare(this.getLevel(o1.getLevel()).getOrder(), - this.getLevel(o2.getLevel()).getOrder()); + this.getLevel(o2.getLevel()).getOrder()); } } }; @@ -189,6 +190,7 @@ public class ChallengesManager */ public void load() { + this.addon.log("Loading challenges..."); this.challengeCacheData.clear(); this.levelCacheData.clear(); @@ -199,17 +201,15 @@ public class ChallengesManager } this.playerCacheData.clear(); + loadAndValidate(); + } - this.addon.log("Loading challenges..."); + private void loadAndValidate() { this.challengeDatabase.loadObjects().forEach(this::loadChallenge); this.levelDatabase.loadObjects().forEach(this::loadLevel); - // this validate challenge levels this.validateChallenges(); - - // It is not necessary to load all players in memory. -// this.playersDatabase.loadObjects().forEach(this::loadPlayerData); } @@ -218,24 +218,17 @@ public class ChallengesManager */ public void reload() { + this.addon.log("Reloading challenges..."); if (!this.playerCacheData.isEmpty()) { // store player data before cleaning. this.savePlayersData(); } + //this.challengeDatabase = new Database<>(addon, Challenge.class); + //this.levelDatabase = new Database<>(addon, ChallengeLevel.class); + //this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class); - this.addon.getLogger().info("Reloading challenges..."); - - this.challengeDatabase = new Database<>(addon, Challenge.class); - this.levelDatabase = new Database<>(addon, ChallengeLevel.class); - this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class); - - this.challengeDatabase.loadObjects().forEach(this::loadChallenge); - this.levelDatabase.loadObjects().forEach(this::loadLevel); - - this.validateChallenges(); - // It is not necessary to load all players in memory. -// this.playersDatabase.loadObjects().forEach(this::loadPlayerData); + loadAndValidate(); } @@ -261,9 +254,9 @@ public class ChallengesManager * @return - true if imported */ public boolean loadChallenge(@NonNull Challenge challenge, - boolean overwrite, - User user, - boolean silent) + boolean overwrite, + User user, + boolean silent) { if (this.challengeCacheData.containsKey(challenge.getUniqueId())) { @@ -272,7 +265,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-skipping", - "[value]", challenge.getFriendlyName()); + "[value]", challenge.getFriendlyName()); } return false; @@ -282,7 +275,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-overwriting", - "[value]", challenge.getFriendlyName()); + "[value]", challenge.getFriendlyName()); } } } @@ -291,7 +284,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-add", - "[value]", challenge.getFriendlyName()); + "[value]", challenge.getFriendlyName()); } } @@ -322,21 +315,21 @@ public class ChallengesManager * @return boolean that indicate about load status. */ public boolean loadLevel(@NonNull ChallengeLevel level, - boolean overwrite, - User user, - boolean silent) + boolean overwrite, + User user, + boolean silent) { if (!this.isValidLevel(level)) { if (user != null) { user.sendMessage("challenges.errors.load-error", - "[value]", level.getFriendlyName()); + "[value]", level.getFriendlyName()); } else { this.addon.logError( - "Challenge Level '" + level.getUniqueId() + "' is not valid and skipped"); + "Challenge Level '" + level.getUniqueId() + "' is not valid and skipped"); } return false; @@ -349,7 +342,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-skipping", - "[value]", level.getFriendlyName()); + "[value]", level.getFriendlyName()); } return false; @@ -359,7 +352,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-overwriting", - "[value]", level.getFriendlyName()); + "[value]", level.getFriendlyName()); } } } @@ -368,7 +361,7 @@ public class ChallengesManager if (!silent) { user.sendMessage("challenges.messages.load-add", - "[value]", level.getFriendlyName()); + "[value]", level.getFriendlyName()); } } @@ -435,7 +428,7 @@ public class ChallengesManager // If challenge's level is not found, then set it as free challenge. challenge.setLevel(FREE); this.addon.logWarning("Challenge's " + challenge.getUniqueId() + " level was not found in the database. " + - "To avoid any errors with missing level, challenge was added to the FREE level!"); + "To avoid any errors with missing level, challenge was added to the FREE level!"); } }); } @@ -666,13 +659,13 @@ public class ChallengesManager this.levelCacheData.remove(level.getUniqueId()); level.setUniqueId( - addonName + level.getUniqueId().substring(world.getName().length())); + addonName + level.getUniqueId().substring(world.getName().length())); Set challengesID = new HashSet<>(level.getChallenges()); level.getChallenges().clear(); challengesID.forEach(challenge -> - level.getChallenges().add(addonName + challenge.substring(world.getName().length()))); + level.getChallenges().add(addonName + challenge.substring(world.getName().length()))); this.levelDatabase.saveObject(level); this.levelCacheData.put(level.getUniqueId(), level); @@ -726,36 +719,36 @@ public class ChallengesManager { switch (challenge.getChallengeType()) { - case INVENTORY: - InventoryRequirements inventoryRequirements = new InventoryRequirements(); - inventoryRequirements.setRequiredItems(challenge.getRequiredItems()); - inventoryRequirements.setTakeItems(challenge.isTakeItems()); + case INVENTORY: + InventoryRequirements inventoryRequirements = new InventoryRequirements(); + inventoryRequirements.setRequiredItems(challenge.getRequiredItems()); + inventoryRequirements.setTakeItems(challenge.isTakeItems()); - inventoryRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); - challenge.setRequirements(inventoryRequirements); - break; - case ISLAND: - IslandRequirements islandRequirements = new IslandRequirements(); - islandRequirements.setRemoveBlocks(challenge.isRemoveBlocks()); - islandRequirements.setRemoveEntities(challenge.isRemoveEntities()); - islandRequirements.setRequiredBlocks(challenge.getRequiredBlocks()); - islandRequirements.setRequiredEntities(challenge.getRequiredEntities()); - islandRequirements.setSearchRadius(challenge.getSearchRadius()); + inventoryRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); + challenge.setRequirements(inventoryRequirements); + break; + case ISLAND: + IslandRequirements islandRequirements = new IslandRequirements(); + islandRequirements.setRemoveBlocks(challenge.isRemoveBlocks()); + islandRequirements.setRemoveEntities(challenge.isRemoveEntities()); + islandRequirements.setRequiredBlocks(challenge.getRequiredBlocks()); + islandRequirements.setRequiredEntities(challenge.getRequiredEntities()); + islandRequirements.setSearchRadius(challenge.getSearchRadius()); - islandRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); - challenge.setRequirements(islandRequirements); - break; - case OTHER: - OtherRequirements otherRequirements = new OtherRequirements(); - otherRequirements.setRequiredExperience(challenge.getRequiredExperience()); - otherRequirements.setRequiredIslandLevel(challenge.getRequiredIslandLevel()); - otherRequirements.setRequiredMoney(challenge.getRequiredMoney()); - otherRequirements.setTakeExperience(challenge.isTakeExperience()); - otherRequirements.setTakeMoney(challenge.isTakeMoney()); + islandRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); + challenge.setRequirements(islandRequirements); + break; + case OTHER: + OtherRequirements otherRequirements = new OtherRequirements(); + otherRequirements.setRequiredExperience(challenge.getRequiredExperience()); + otherRequirements.setRequiredIslandLevel(challenge.getRequiredIslandLevel()); + otherRequirements.setRequiredMoney(challenge.getRequiredMoney()); + otherRequirements.setTakeExperience(challenge.isTakeExperience()); + otherRequirements.setTakeMoney(challenge.isTakeMoney()); - otherRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); - challenge.setRequirements(otherRequirements); - break; + otherRequirements.setRequiredPermissions(challenge.getRequiredPermissions()); + challenge.setRequirements(otherRequirements); + break; } // This save should not involve any upgrades in other parts. @@ -1068,6 +1061,7 @@ public class ChallengesManager * @param gameMode - World Name where levels should be searched. * @return Level status - how many challenges still to do on which level */ + @NonNull private List getAllChallengeLevelStatus(String storageDataID, String gameMode) { this.addPlayerData(storageDataID); @@ -1095,15 +1089,14 @@ public class ChallengesManager doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count(); result.add(new LevelStatus( - level, - previousLevel, - challengesToDo, - level.getChallenges().size() == doneChallengeCount, - challengesToDo <= 0)); + level, + previousLevel, + challengesToDo, + level.getChallenges().size() == doneChallengeCount, + challengesToDo <= 0)); previousLevel = level; } - return result; } @@ -1115,6 +1108,7 @@ public class ChallengesManager * @param level Level which status must be calculated. * @return LevelStatus of given level. */ + @Nullable private LevelStatus getChallengeLevelStatus(@NonNull String storageDataID, World world, @NonNull ChallengeLevel level) { this.addPlayerData(storageDataID); @@ -1134,43 +1128,20 @@ public class ChallengesManager int challengesToDo = previousLevel == null ? 0 : (previousLevel.getChallenges().size() - level.getWaiverAmount()) - - (int) previousLevel.getChallenges().stream().filter(playerData::isChallengeDone).count(); + (int) previousLevel.getChallenges().stream().filter(playerData::isChallengeDone).count(); // As level already contains unique ids of challenges, just iterate through them. int doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count(); return new LevelStatus( - level, - previousLevel, - challengesToDo, - level.getChallenges().size() == doneChallengeCount, - challengesToDo <= 0); + level, + previousLevel, + challengesToDo, + level.getChallenges().size() == doneChallengeCount, + challengesToDo <= 0); } } - - /** - * Check is playerData can see given level. - * TODO: not an optimal way. Faster would be to check previous level challenges. - * @param storageDataID - playerData ID - * @param level - level - * @return true if level is unlocked - */ - private boolean isLevelUnlocked(@NonNull String storageDataID, - World world, - ChallengeLevel level) - { - this.addPlayerData(storageDataID); - - return this.islandWorldManager.getAddon(world).filter(gameMode -> - this.getAllChallengeLevelStatus(storageDataID, gameMode.getDescription().getName()). - stream(). - filter(LevelStatus::isUnlocked). - anyMatch(lv -> lv.getLevel().equals(level))). - isPresent(); - } - - /** * This method returns if given user has been already completed given level. * @param levelID Level that must be checked. @@ -1302,17 +1273,17 @@ public class ChallengesManager String storageID = this.getDataUniqueID(userID, Util.getWorld(world)); this.setChallengeComplete(storageID, challenge.getUniqueId(), completionCount); this.addLogEntry(storageID, new LogEntry.Builder("COMPLETE"). - data("user-id", userID.toString()). - data("challenge-id", challenge.getUniqueId()). - data("completion-count", Integer.toString(completionCount)). - build()); + data("user-id", userID.toString()). + data("challenge-id", challenge.getUniqueId()). + data("completion-count", Integer.toString(completionCount)). + build()); // Fire event that user completes challenge - Bukkit.getServer().getPluginManager().callEvent( - new ChallengeCompletedEvent(challenge.getUniqueId(), - userID, - false, - completionCount)); + Bukkit.getPluginManager().callEvent( + new ChallengeCompletedEvent(challenge.getUniqueId(), + userID, + false, + completionCount)); } @@ -1329,17 +1300,17 @@ public class ChallengesManager this.setChallengeComplete(storageID, challenge.getUniqueId()); this.addLogEntry(storageID, new LogEntry.Builder("COMPLETE"). - data("user-id", userID.toString()). - data("challenge-id", challenge.getUniqueId()). - data("admin-id", adminID == null ? "OP" : adminID.toString()). - build()); + data("user-id", userID.toString()). + data("challenge-id", challenge.getUniqueId()). + data("admin-id", adminID == null ? "OP" : adminID.toString()). + build()); // Fire event that admin completes user challenge - Bukkit.getServer().getPluginManager().callEvent( - new ChallengeCompletedEvent(challenge.getUniqueId(), - userID, - true, - 1)); + Bukkit.getPluginManager().callEvent( + new ChallengeCompletedEvent(challenge.getUniqueId(), + userID, + true, + 1)); } @@ -1355,17 +1326,17 @@ public class ChallengesManager this.resetChallenge(storageID, challenge.getUniqueId()); this.addLogEntry(storageID, new LogEntry.Builder("RESET"). - data("user-id", userID.toString()). - data("challenge-id", challenge.getUniqueId()). - data("admin-id", adminID == null ? "RESET" : adminID.toString()). - build()); + data("user-id", userID.toString()). + data("challenge-id", challenge.getUniqueId()). + data("admin-id", adminID == null ? "RESET" : adminID.toString()). + build()); // Fire event that admin resets user challenge - Bukkit.getServer().getPluginManager().callEvent( - new ChallengeResetEvent(challenge.getUniqueId(), - userID, - true, - "RESET")); + Bukkit.getPluginManager().callEvent( + new ChallengeResetEvent(challenge.getUniqueId(), + userID, + true, + "RESET")); } @@ -1393,16 +1364,16 @@ public class ChallengesManager this.islandWorldManager.getAddon(world).ifPresent(gameMode -> { this.resetAllChallenges(storageID, gameMode.getDescription().getName()); this.addLogEntry(storageID, new LogEntry.Builder("RESET_ALL"). - data("user-id", userID.toString()). - data("admin-id", adminID == null ? "ISLAND_RESET" : adminID.toString()). - build()); + data("user-id", userID.toString()). + data("admin-id", adminID == null ? "ISLAND_RESET" : adminID.toString()). + build()); // Fire event that admin resets user challenge - Bukkit.getServer().getPluginManager().callEvent( - new ChallengeResetAllEvent(gameMode.getDescription().getName(), - userID, - adminID != null, - adminID == null ? "ISLAND_RESET" : "RESET_ALL")); + Bukkit.getPluginManager().callEvent( + new ChallengeResetAllEvent(gameMode.getDescription().getName(), + userID, + adminID != null, + adminID == null ? "ISLAND_RESET" : "RESET_ALL")); }); } @@ -1454,11 +1425,19 @@ public class ChallengesManager * @param world World where level must be checked. * @param level Level that must be checked. * @param user User who need to be checked. - * @return true, if level is already completed. + * @return true, if level is unlocked. */ public boolean isLevelUnlocked(User user, World world, ChallengeLevel level) { - return this.isLevelUnlocked(this.getDataUniqueID(user, Util.getWorld(world)), world, level); + String storageDataID = this.getDataUniqueID(user, Util.getWorld(world)); + this.addPlayerData(storageDataID); + + return this.islandWorldManager.getAddon(world).filter(gameMode -> this.getAllChallengeLevelStatus(storageDataID, gameMode.getDescription().getName()). + stream(). + filter(LevelStatus::isUnlocked). + anyMatch(lv -> lv.getLevel().equals(level))). + isPresent(); + } @@ -1474,14 +1453,14 @@ public class ChallengesManager this.setLevelComplete(storageID, level.getUniqueId()); this.addLogEntry(storageID, new LogEntry.Builder("COMPLETE_LEVEL"). - data("user-id", user.getUniqueId().toString()). - data("level", level.getUniqueId()).build()); + data("user-id", user.getUniqueId().toString()). + data("level", level.getUniqueId()).build()); // Fire event that user completes level - Bukkit.getServer().getPluginManager().callEvent( - new LevelCompletedEvent(level.getUniqueId(), - user.getUniqueId(), - false)); + Bukkit.getPluginManager().callEvent( + new LevelCompletedEvent(level.getUniqueId(), + user.getUniqueId(), + false)); } @@ -1500,14 +1479,15 @@ public class ChallengesManager /** * This method returns LevelStatus object for given challenge level. + * @param uniqueId UUID of user who need to be validated. * @param world World where level must be validated. * @param level Level that must be validated. - * @param user User who need to be validated. * @return LevelStatus of given level. */ - public LevelStatus getChallengeLevelStatus(UUID user, World world, ChallengeLevel level) + @Nullable + public LevelStatus getChallengeLevelStatus(UUID uniqueId, World world, ChallengeLevel level) { - return this.getChallengeLevelStatus(this.getDataUniqueID(user, Util.getWorld(world)), world, level); + return this.getChallengeLevelStatus(this.getDataUniqueID(uniqueId, Util.getWorld(world)), world, level); } @@ -1518,13 +1498,14 @@ public class ChallengesManager * @param world - World where levels should be searched. * @return Level status - how many challenges still to do on which level */ + @NonNull public List getAllChallengeLevelStatus(User user, World world) { return this.islandWorldManager.getAddon(world).map(gameMode -> - this.getAllChallengeLevelStatus( + this.getAllChallengeLevelStatus( this.getDataUniqueID(user, Util.getWorld(world)), gameMode.getDescription().getName())). - orElse(Collections.emptyList()); + orElse(Collections.emptyList()); } @@ -1542,12 +1523,12 @@ public class ChallengesManager public List getAllChallengesNames(@NonNull World world) { return this.islandWorldManager.getAddon(world).map(gameMode -> - this.challengeCacheData.values().stream(). - filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())). - sorted(this.challengeComparator). - map(Challenge::getUniqueId). - collect(Collectors.toList())). - orElse(Collections.emptyList()); + this.challengeCacheData.values().stream(). + filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())). + sorted(this.challengeComparator). + map(Challenge::getUniqueId). + collect(Collectors.toList())). + orElse(Collections.emptyList()); } @@ -1560,11 +1541,11 @@ public class ChallengesManager public List getAllChallenges(@NonNull World world) { return this.islandWorldManager.getAddon(world).map(gameMode -> - this.challengeCacheData.values().stream(). - filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())). - sorted(this.challengeComparator). - collect(Collectors.toList())). - orElse(Collections.emptyList()); + this.challengeCacheData.values().stream(). + filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())). + sorted(this.challengeComparator). + collect(Collectors.toList())). + orElse(Collections.emptyList()); } @@ -1577,12 +1558,12 @@ public class ChallengesManager { // Free Challenges hides under FREE level. return this.islandWorldManager.getAddon(world).map(gameMode -> - this.challengeCacheData.values().stream(). - filter(challenge -> challenge.getLevel().equals(FREE) && - challenge.matchGameMode(gameMode.getDescription().getName())). - sorted(Comparator.comparing(Challenge::getOrder)). - collect(Collectors.toList())). - orElse(Collections.emptyList()); + this.challengeCacheData.values().stream(). + filter(challenge -> challenge.getLevel().equals(FREE) && + challenge.matchGameMode(gameMode.getDescription().getName())). + sorted(Comparator.comparing(Challenge::getOrder)). + collect(Collectors.toList())). + orElse(Collections.emptyList()); } @@ -1594,10 +1575,10 @@ public class ChallengesManager public List getLevelChallenges(ChallengeLevel level) { return level.getChallenges().stream(). - map(this::getChallenge). - filter(Objects::nonNull). - sorted(Comparator.comparing(Challenge::getOrder)). - collect(Collectors.toList()); + map(this::getChallenge). + filter(Objects::nonNull). + sorted(Comparator.comparing(Challenge::getOrder)). + collect(Collectors.toList()); } @@ -1607,6 +1588,7 @@ public class ChallengesManager * @param name - unique name of challenge * @return - challenge or null if it does not exist */ + @Nullable public Challenge getChallenge(String name) { if (this.challengeCacheData.containsKey(name)) @@ -1615,26 +1597,20 @@ public class ChallengesManager } else { - System.out.println("Checking database"); // check database. if (this.challengeDatabase.objectExists(name)) { - System.out.println("Exists"); Challenge challenge = this.challengeDatabase.loadObject(name); if (challenge != null) { - System.out.println("Loaded!"); this.challengeCacheData.put(name, challenge); return challenge; } else { - System.out.println("Error"); this.addon.logError("Tried to load NULL challenge object!"); } - } else { - System.out.println("Not exists"); } } @@ -1660,6 +1636,7 @@ public class ChallengesManager * @param requirements - requirements object, as it is not changeable anymore. * @return Challenge that is currently created. */ + @Nullable public Challenge createChallenge(String uniqueID, Challenge.ChallengeType type, Requirements requirements) { if (!this.containsChallenge(uniqueID)) @@ -1694,7 +1671,7 @@ public class ChallengesManager this.challengeDatabase.deleteObject(challenge); this.addon.getPlugin().getPlaceholdersManager(). - unregisterPlaceholder("challenges_challenge_repetition_count_" + challenge.getUniqueId()); + unregisterPlaceholder("challenges_challenge_repetition_count_" + challenge.getUniqueId()); } } @@ -1712,8 +1689,8 @@ public class ChallengesManager public List getLevels(@NonNull World world) { return this.islandWorldManager.getAddon(world).map(gameMode -> - this.getLevels(gameMode.getDescription().getName())). - orElse(Collections.emptyList()); + this.getLevels(gameMode.getDescription().getName())). + orElse(Collections.emptyList()); } @@ -1726,9 +1703,9 @@ public class ChallengesManager { // TODO: Probably need to check also database. return this.levelCacheData.values().stream(). - sorted(ChallengeLevel::compareTo). - filter(level -> level.matchGameMode(gameMode)). - collect(Collectors.toList()); + sorted(ChallengeLevel::compareTo). + filter(level -> level.matchGameMode(gameMode)). + collect(Collectors.toList()); } @@ -1738,6 +1715,7 @@ public class ChallengesManager * @param challenge - challenge which level must be returned. * @return - challenge level or null if it does not exist */ + @Nullable public ChallengeLevel getLevel(Challenge challenge) { if (!challenge.getLevel().equals(FREE)) @@ -1755,6 +1733,7 @@ public class ChallengesManager * @param name - unique name of challenge level * @return - challenge level or null if it does not exist */ + @Nullable public ChallengeLevel getLevel(String name) { if (this.levelCacheData.containsKey(name)) @@ -1822,7 +1801,7 @@ public class ChallengesManager /** * This method adds given challenge to given challenge level. * @param newChallenge Challenge who must change owner. - * @param newLevel Level who must add new challenge + * @param newLevel Level to add to - must exist already */ public void addChallengeToLevel(Challenge newChallenge, ChallengeLevel newLevel) { @@ -1838,7 +1817,7 @@ public class ChallengesManager { ChallengeLevel oldLevel = this.getLevel(newChallenge.getLevel()); - if (!oldLevel.equals(newLevel)) + if (oldLevel == null || !oldLevel.equals(newLevel)) { this.removeChallengeFromLevel(newChallenge, newLevel); newLevel.getChallenges().add(newChallenge.getUniqueId()); @@ -1873,6 +1852,7 @@ public class ChallengesManager * @param uniqueID - new ID for challenge level. * @return ChallengeLevel that is currently created. */ + @Nullable public ChallengeLevel createLevel(String uniqueID, World world) { if (!this.containsLevel(uniqueID)) @@ -1920,7 +1900,7 @@ public class ChallengesManager this.levelDatabase.deleteObject(challengeLevel); this.addon.getPlugin().getPlaceholdersManager(). - unregisterPlaceholder("challenges_completed_challenge_count_per_level_" + challengeLevel.getUniqueId()); + unregisterPlaceholder("challenges_completed_challenge_count_per_level_" + challengeLevel.getUniqueId()); } } @@ -1933,7 +1913,7 @@ public class ChallengesManager public boolean hasAnyChallengeData(@NonNull World world) { return this.islandWorldManager.getAddon(world).filter(gameMode -> - this.hasAnyChallengeData(gameMode.getDescription().getName())).isPresent(); + this.hasAnyChallengeData(gameMode.getDescription().getName())).isPresent(); } @@ -1945,8 +1925,8 @@ public class ChallengesManager public boolean hasAnyChallengeData(@NonNull String gameMode) { return this.challengeDatabase.loadObjects().stream().anyMatch( - challenge -> challenge.matchGameMode(gameMode)) || - this.levelDatabase.loadObjects().stream().anyMatch( - level -> level.matchGameMode(gameMode)); + challenge -> challenge.matchGameMode(gameMode)) || + this.levelDatabase.loadObjects().stream().anyMatch( + level -> level.matchGameMode(gameMode)); } } \ No newline at end of file diff --git a/src/main/java/world/bentobox/challenges/database/object/Challenge.java b/src/main/java/world/bentobox/challenges/database/object/Challenge.java index b532f52..cff291f 100644 --- a/src/main/java/world/bentobox/challenges/database/object/Challenge.java +++ b/src/main/java/world/bentobox/challenges/database/object/Challenge.java @@ -13,6 +13,7 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import org.eclipse.jdt.annotation.NonNull; import com.google.gson.annotations.Expose; import com.google.gson.annotations.JsonAdapter; @@ -717,7 +718,7 @@ public class Challenge implements DataObject * This method sets the level value. * @param level the level new value. */ - public void setLevel(String level) + public void setLevel(@NonNull String level) { this.level = level; } @@ -1050,7 +1051,7 @@ public class Challenge implements DataObject public boolean matchGameMode(String gameMode) { return gameMode != null && - this.uniqueId.regionMatches(true, 0, gameMode, 0, gameMode.length()); + this.uniqueId.regionMatches(true, 0, gameMode, 0, gameMode.length()); } @@ -1129,7 +1130,7 @@ public class Challenge implements DataObject clone.setRequirements(this.requirements.clone()); clone.setRewardText(this.rewardText); clone.setRewardItems(this.rewardItems.stream().map(ItemStack::clone). - collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size())))); + collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size())))); clone.setRewardExperience(this.rewardExperience); clone.setRewardMoney(this.rewardMoney); clone.setRewardCommands(new ArrayList<>(this.rewardCommands)); @@ -1138,7 +1139,7 @@ public class Challenge implements DataObject clone.setMaxTimes(this.maxTimes); clone.setRepeatExperienceReward(this.repeatExperienceReward); clone.setRepeatItemReward(this.repeatItemReward.stream().map(ItemStack::clone). - collect(Collectors.toCollection(() -> new ArrayList<>(this.repeatItemReward.size())))); + collect(Collectors.toCollection(() -> new ArrayList<>(this.repeatItemReward.size())))); clone.setRepeatMoneyReward(this.repeatMoneyReward); clone.setRepeatRewardCommands(new ArrayList<>(this.repeatRewardCommands)); } diff --git a/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java b/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java index 3f81b5b..db306a9 100644 --- a/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java +++ b/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java @@ -25,334 +25,334 @@ import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter; */ public class ChallengesPlayerData implements DataObject { - /** - * Constructor ChallengesPlayerData creates a new ChallengesPlayerData instance. - */ - public ChallengesPlayerData() - { - } + /** + * Constructor ChallengesPlayerData creates a new ChallengesPlayerData instance. + */ + public ChallengesPlayerData() + { + } - /** - * Creates a player data entry - * - * @param uniqueId - the player's UUID in string format - */ - public ChallengesPlayerData(String uniqueId) - { - this.uniqueId = uniqueId; - } + /** + * Creates a player data entry + * + * @param uniqueId - the player's UUID in string format + */ + public ChallengesPlayerData(String uniqueId) + { + this.uniqueId = uniqueId; + } -// --------------------------------------------------------------------- -// Section: Variables -// --------------------------------------------------------------------- + // --------------------------------------------------------------------- + // Section: Variables + // --------------------------------------------------------------------- - /** - * This variable stores each player UUID as string. - */ - @Expose - private String uniqueId = ""; + /** + * This variable stores each player UUID as string. + */ + @Expose + private String uniqueId = ""; - /** - * Challenge map, where key = unique challenge name and Value = number of times - * completed - */ - @Expose - private Map challengeStatus = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + /** + * Challenge map, where key = unique challenge name and Value = number of times + * completed + */ + @Expose + private Map challengeStatus = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - /** - * Map of challenges completion time where key is challenges unique id and value is - * timestamp when challenge was completed last time. - */ - @Expose - private Map challengesTimestamp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + /** + * Map of challenges completion time where key is challenges unique id and value is + * timestamp when challenge was completed last time. + */ + @Expose + private Map challengesTimestamp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - /** - * Set of Strings that contains all challenge levels that are completed. - */ - @Expose - private Set levelsDone = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + /** + * Set of Strings that contains all challenge levels that are completed. + */ + @Expose + private Set levelsDone = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - /** - * Stores history about challenge completion. - */ - @Adapter(LogEntryListAdapter.class) - @Expose - private List history = new LinkedList<>(); + /** + * Stores history about challenge completion. + */ + @Adapter(LogEntryListAdapter.class) + @Expose + private List history = new LinkedList<>(); -// --------------------------------------------------------------------- -// Section: Getters -// --------------------------------------------------------------------- + // --------------------------------------------------------------------- + // Section: Getters + // --------------------------------------------------------------------- - /** - * @return uniqueID - * @see DataObject#getUniqueId() - */ - @Override - public String getUniqueId() - { - return uniqueId; - } + /** + * @return uniqueID + * @see DataObject#getUniqueId() + */ + @Override + public String getUniqueId() + { + return uniqueId; + } - /** - * This method returns the challengeStatus value. - * @return the value of challengeStatus. - */ - public Map getChallengeStatus() - { - return challengeStatus; - } + /** + * This method returns the challengeStatus value. + * @return the value of challengeStatus. + */ + public Map getChallengeStatus() + { + return challengeStatus; + } - /** - * This method returns the challengesTimestamp value. - * @return the value of challengesTimestamp. - */ - public Map getChallengesTimestamp() - { - return challengesTimestamp; - } + /** + * This method returns the challengesTimestamp value. + * @return the value of challengesTimestamp. + */ + public Map getChallengesTimestamp() + { + return challengesTimestamp; + } - /** - * This method returns the levelsDone value. - * @return the value of levelsDone. - */ - public Set getLevelsDone() - { - return levelsDone; - } + /** + * This method returns the levelsDone value. + * @return the value of levelsDone. + */ + public Set getLevelsDone() + { + return levelsDone; + } - /** - * This method returns the history object. - * @return the history object. - */ - public List getHistory() - { - return history; - } + /** + * This method returns the history object. + * @return the history object. + */ + public List getHistory() + { + return history; + } -// --------------------------------------------------------------------- -// Section: Setters -// --------------------------------------------------------------------- + // --------------------------------------------------------------------- + // Section: Setters + // --------------------------------------------------------------------- - /** - * @param uniqueId - unique ID the uniqueId to set - * @see DataObject#setUniqueId(String) - */ - @Override - public void setUniqueId(String uniqueId) - { - this.uniqueId = uniqueId; - } + /** + * @param uniqueId - unique ID the uniqueId to set + * @see DataObject#setUniqueId(String) + */ + @Override + public void setUniqueId(String uniqueId) + { + this.uniqueId = uniqueId; + } - /** - * This method sets the challengeStatus value. - * @param challengeStatus the challengeStatus new value. - * - */ - public void setChallengeStatus(Map challengeStatus) - { - this.challengeStatus = challengeStatus; - } + /** + * This method sets the challengeStatus value. + * @param challengeStatus the challengeStatus new value. + * + */ + public void setChallengeStatus(Map challengeStatus) + { + this.challengeStatus = challengeStatus; + } - /** - * This method sets the challengesTimestamp value. - * @param challengesTimestamp the challengesTimestamp new value. - * - */ - public void setChallengesTimestamp(Map challengesTimestamp) - { - this.challengesTimestamp = challengesTimestamp; - } + /** + * This method sets the challengesTimestamp value. + * @param challengesTimestamp the challengesTimestamp new value. + * + */ + public void setChallengesTimestamp(Map challengesTimestamp) + { + this.challengesTimestamp = challengesTimestamp; + } - /** - * This method sets the levelsDone value. - * @param levelsDone the levelsDone new value. - * - */ - public void setLevelsDone(Set levelsDone) - { - this.levelsDone = levelsDone; - } + /** + * This method sets the levelsDone value. + * @param levelsDone the levelsDone new value. + * + */ + public void setLevelsDone(Set levelsDone) + { + this.levelsDone = levelsDone; + } - /** - * This method sets the history object value. - * @param history the history object new value. - */ - public void setHistory(List history) - { - this.history = history; - } + /** + * This method sets the history object value. + * @param history the history object new value. + */ + public void setHistory(List history) + { + this.history = history; + } -// --------------------------------------------------------------------- -// Section: Other Methods -// --------------------------------------------------------------------- + // --------------------------------------------------------------------- + // Section: Other Methods + // --------------------------------------------------------------------- - /** - * Resets all challenges and levels in GameMode for this player - * - * @param gameMode GameMode which challenges must be reset. - */ - public void reset(@NonNull String gameMode) - { - challengeStatus.keySet().removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); - challengesTimestamp.keySet().removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); - levelsDone.removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); - } + /** + * Resets all challenges and levels in GameMode for this player + * + * @param gameMode GameMode which challenges must be reset. + */ + public void reset(@NonNull String gameMode) + { + challengeStatus.keySet().removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); + challengesTimestamp.keySet().removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); + levelsDone.removeIf(n -> n.regionMatches(true, 0, gameMode, 0, gameMode.length())); + } - /** - * Mark a challenge as having been completed. Will increment the number of times and - * timestamp - * - * @param challengeName - unique challenge name - */ - public void setChallengeDone(@NonNull String challengeName) - { - this.addChallengeDone(challengeName, 1); - } + /** + * Mark a challenge as having been completed. Will increment the number of times and + * timestamp + * + * @param challengeName - unique challenge name + */ + public void setChallengeDone(@NonNull String challengeName) + { + this.addChallengeDone(challengeName, 1); + } - /** - * Mark a challenge as having been completed. Will increment the number of times and - * timestamp - * - * @param challengeName - unique challenge name - * @param times - how many new times should be added - */ - public void addChallengeDone(@NonNull String challengeName, int times) - { - int newTimes = challengeStatus.getOrDefault(challengeName, 0) + times; - challengeStatus.put(challengeName, newTimes); - challengesTimestamp.put(challengeName, System.currentTimeMillis()); - } + /** + * Mark a challenge as having been completed. Will increment the number of times and + * timestamp + * + * @param challengeName - unique challenge name + * @param times - how many new times should be added + */ + public void addChallengeDone(@NonNull String challengeName, int times) + { + int newTimes = challengeStatus.getOrDefault(challengeName, 0) + times; + challengeStatus.put(challengeName, newTimes); + challengesTimestamp.put(challengeName, System.currentTimeMillis()); + } - /** - * Set the number of times a challenge has been done - * - * @param challengeName - unique challenge name - * @param times - the number of times to set - */ - public void setChallengeTimes(@NonNull String challengeName, @NonNull int times) - { - challengeStatus.put(challengeName, times); - challengesTimestamp.put(challengeName, System.currentTimeMillis()); - } + /** + * Set the number of times a challenge has been done + * + * @param challengeName - unique challenge name + * @param times - the number of times to set + */ + public void setChallengeTimes(@NonNull String challengeName, @NonNull int times) + { + challengeStatus.put(challengeName, times); + challengesTimestamp.put(challengeName, System.currentTimeMillis()); + } - /** - * Check if a challenge has been done - * - * @param challengeName - unique challenge name - * @return true if done at least once - */ - public boolean isChallengeDone(@NonNull String challengeName) - { - return this.getTimes(challengeName) > 0; - } + /** + * Check if a challenge has been done + * + * @param challengeName - unique challenge name + * @return true if done at least once + */ + public boolean isChallengeDone(@NonNull String challengeName) + { + return this.getTimes(challengeName) > 0; + } - /** - * Check how many times a challenge has been done - * - * @param challengeName - unique challenge name - * @return - number of times - */ - public int getTimes(@NonNull String challengeName) - { - return challengeStatus.getOrDefault(challengeName, 0); - } + /** + * Check how many times a challenge has been done + * + * @param challengeName - unique challenge name + * @return - number of times + */ + public int getTimes(@NonNull String challengeName) + { + return challengeStatus.getOrDefault(challengeName, 0); + } - /** - * This method adds given level id to completed level set. - * @param uniqueId from ChallengeLevel object. - */ - public void addCompletedLevel(@NonNull String uniqueId) - { - this.levelsDone.add(uniqueId); - } + /** + * This method adds given level id to completed level set. + * @param uniqueId from ChallengeLevel object. + */ + public void addCompletedLevel(@NonNull String uniqueId) + { + this.levelsDone.add(uniqueId); + } - /** - * This method returns if given level is done. - * @param uniqueId of ChallengeLevel object. - * @return true if level is completed, otherwise false - */ - public boolean isLevelDone(@NonNull String uniqueId) - { - return !this.levelsDone.isEmpty() && this.levelsDone.contains(uniqueId); - } + /** + * This method returns if given level is done. + * @param uniqueId of ChallengeLevel object. + * @return true if level is completed, otherwise false + */ + public boolean isLevelDone(@NonNull String uniqueId) + { + return !this.levelsDone.isEmpty() && this.levelsDone.contains(uniqueId); + } - /** - * This method adds given LogEntry to history. - * - * @param entry of type LogEntry - */ - public void addHistoryRecord(@NonNull LogEntry entry) - { - this.history.add(entry); - } + /** + * This method adds given LogEntry to history. + * + * @param entry of type LogEntry + */ + public void addHistoryRecord(@NonNull LogEntry entry) + { + this.history.add(entry); + } - /** - * @see Object#hashCode() - * @return object hashCode value. - */ - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); - return result; - } + /** + * @see Object#hashCode() + * @return object hashCode value. + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); + return result; + } - /** - * @see java.lang.Object#equals(java.lang.Object) - * @param obj Other object. - * @return boolean that indicate if objects are equals. - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } + /** + * @see java.lang.Object#equals(java.lang.Object) + * @param obj Other object. + * @return boolean that indicate if objects are equals. + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } - if (!(obj instanceof ChallengesPlayerData)) - { - return false; - } + if (!(obj instanceof ChallengesPlayerData)) + { + return false; + } - ChallengesPlayerData other = (ChallengesPlayerData) obj; + ChallengesPlayerData other = (ChallengesPlayerData) obj; - if (uniqueId == null) - { - return other.uniqueId == null; - } - else - { - return uniqueId.equalsIgnoreCase(other.uniqueId); - } - } + if (uniqueId == null) + { + return other.uniqueId == null; + } + else + { + return uniqueId.equalsIgnoreCase(other.uniqueId); + } + } } \ No newline at end of file diff --git a/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java b/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java index c1f11da..0f2c19d 100644 --- a/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java +++ b/src/test/java/world/bentobox/challenges/ChallengesManagerTest.java @@ -1,12 +1,13 @@ package world.bentobox.challenges; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -22,8 +23,11 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.List; +import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; @@ -33,6 +37,8 @@ import org.bukkit.World; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.PluginManager; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -44,30 +50,42 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.addons.AddonDescription; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.PlaceholdersManager; +import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.config.Settings; import world.bentobox.challenges.database.object.Challenge; +import world.bentobox.challenges.database.object.Challenge.ChallengeType; import world.bentobox.challenges.database.object.ChallengeLevel; +import world.bentobox.challenges.events.ChallengeCompletedEvent; +import world.bentobox.challenges.events.ChallengeResetAllEvent; +import world.bentobox.challenges.events.ChallengeResetEvent; +import world.bentobox.challenges.events.LevelCompletedEvent; +import world.bentobox.challenges.utils.LevelStatus; /** * @author tastybento * */ +@SuppressWarnings("deprecation") @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class}) +@PrepareForTest({Bukkit.class, BentoBox.class, Util.class}) public class ChallengesManagerTest { + // Constants + private static final String GAME_MODE_NAME = "BSkyBlock"; + + // Mocks @Mock private ChallengesAddon addon; @Mock private Settings settings; @Mock private IslandWorldManager iwm; - - private ChallengesManager cm; - private File database; @Mock private Server server; @Mock @@ -76,30 +94,50 @@ public class ChallengesManagerTest { private ItemFactory itemFactory; @Mock private User user; - private String uuid; @Mock private World world; + @Mock + private GameModeAddon gameModeAddon; + @Mock + private PlaceholdersManager plhm; + + // Variable fields + private ChallengesManager cm; + private File database; + private String uuid; + private Challenge challenge; + private @NonNull ChallengeLevel level; + private UUID playerID = UUID.randomUUID(); + private String cName; + private String levelName; /** * @throws java.lang.Exception */ - @SuppressWarnings("deprecation") @Before public void setUp() throws Exception { // Set up plugin BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); when(addon.getPlugin()).thenReturn(plugin); + + // IWM when(plugin.getIWM()).thenReturn(iwm); when(iwm.inWorld(any(World.class))).thenReturn(true); - // Settings for Database + // Placeholders + when(plugin.getPlaceholdersManager()).thenReturn(plhm); + + // Settings for Database world.bentobox.bentobox.Settings s = mock(world.bentobox.bentobox.Settings.class); when(plugin.getSettings()).thenReturn(s); when(s.getDatabaseType()).thenReturn(DatabaseType.JSON); - // Settings + // Addon Settings when(addon.getChallengesSettings()).thenReturn(settings); + when(settings.isStoreHistory()).thenReturn(true); + when(settings.getLifeSpan()).thenReturn(10); + // Database database = new File("database"); tearDown(); @@ -117,6 +155,37 @@ public class ChallengesManagerTest { when(unsafe.getDataVersion()).thenReturn(777); when(Bukkit.getUnsafe()).thenReturn(unsafe); + // Challenge + challenge = new Challenge(); + uuid = UUID.randomUUID().toString(); + challenge.setUniqueId(GAME_MODE_NAME + "_" + uuid); + challenge.setFriendlyName("name"); + challenge.setLevel(GAME_MODE_NAME + "_novice"); + challenge.setDescription(Collections.singletonList("A description")); + + // Challenge Level + level = new ChallengeLevel(); + levelName = GAME_MODE_NAME + "_novice"; + level.setUniqueId(levelName); + level.setFriendlyName("Novice"); + + // User + when(user.getUniqueId()).thenReturn(playerID); + + // Util + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(any())).thenReturn(world); + + // Addon + AddonDescription desc = new AddonDescription.Builder("main", GAME_MODE_NAME, "1.0").build(); + when(gameModeAddon.getDescription()).thenReturn(desc); + Optional opAddon = Optional.of(gameModeAddon); + when(iwm.getAddon(any())).thenReturn(opAddon); + + // Challenge name + cName = GAME_MODE_NAME + "_" + uuid; + + // Class under test cm = new ChallengesManager(addon); } @@ -127,53 +196,139 @@ public class ChallengesManagerTest { public void tearDown() throws Exception { // Clean up JSON database // Clean up file system + if (database.exists()) { + Files.walk(database.toPath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } - if (database.exists()) { - Files.walk(database.toPath()) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); - } - } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#load()}. + * @throws InterruptedException */ @Test - public void testLoad() { + public void testLoad() throws InterruptedException { verify(addon).log("Loading challenges..."); verify(addon, never()).logError(anyString()); this.testSaveLevel(); this.testSaveChallenge(); cm.load(); - verify(addon, times(2)).log("Loading challenges..."); + verify(addon, times(2)).log("Loading challenges..."); verify(addon, never()).logError(anyString()); - assertTrue(cm.containsChallenge(uuid)); + assertTrue(cm.containsChallenge(cName)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#reload()}. + * @throws InterruptedException */ @Test - public void testReload() { - fail("Not yet implemented"); + public void testReload() throws InterruptedException { + cm.reload(); + verify(addon).log("Reloading challenges..."); + this.testSaveLevel(); + this.testSaveChallenge(); + cm.reload(); + verify(addon, times(2)).log("Reloading challenges..."); + verify(addon, never()).logError(anyString()); + assertTrue(cm.containsChallenge(cName)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#loadChallenge(world.bentobox.challenges.database.object.Challenge, boolean, world.bentobox.bentobox.api.user.User, boolean)}. */ @Test - public void testLoadChallenge() { - fail("Not yet implemented"); + public void testLoadChallengeNoOverwriteSilent() { + // load once + assertTrue(cm.loadChallenge(challenge, false, user, true)); + // load twice - no overwrite + assertFalse(cm.loadChallenge(challenge, false, user, true)); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadChallenge(world.bentobox.challenges.database.object.Challenge, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadChallengeNoOverwriteNotSilent() { + // load once + assertTrue(cm.loadChallenge(challenge, false, user, true)); + // load twice - no overwrite, not silent + assertFalse(cm.loadChallenge(challenge, false, user, false)); + verify(user).sendMessage("challenges.messages.load-skipping", "[value]", "name"); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadChallenge(world.bentobox.challenges.database.object.Challenge, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadChallengeOverwriteSilent() { + // load once + assertTrue(cm.loadChallenge(challenge, false, user, true)); + // overwrite + assertTrue(cm.loadChallenge(challenge, true, user, true)); + verify(user, never()).sendMessage(anyString(), anyString(), anyString()); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadChallenge(world.bentobox.challenges.database.object.Challenge, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadChallengeOverwriteNotSilent() { + // load once + assertTrue(cm.loadChallenge(challenge, false, user, true)); + // overwrite not silent + assertTrue(cm.loadChallenge(challenge, true, user, false)); + verify(user).sendMessage("challenges.messages.load-overwriting", "[value]", "name"); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#loadLevel(world.bentobox.challenges.database.object.ChallengeLevel, boolean, world.bentobox.bentobox.api.user.User, boolean)}. */ @Test - public void testLoadLevel() { - fail("Not yet implemented"); + public void testLoadLevelNoOverwriteSilent() { + // load once + assertTrue(cm.loadLevel(level, false, user, true)); + // load twice - no overwrite + assertFalse(cm.loadLevel(level, false, user, true)); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadLevel(world.bentobox.challenges.database.object.ChallengeLevel, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadLevelNoOverwriteNotSilent() { + // load once + assertTrue(cm.loadLevel(level, false, user, true)); + // load twice - no overwrite, not silent + assertFalse(cm.loadLevel(level, false, user, false)); + verify(user).sendMessage("challenges.messages.load-skipping", "[value]", "Novice"); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadLevel(world.bentobox.challenges.database.object.ChallengeLevel, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadLevelOverwriteSilent() { + // load once + assertTrue(cm.loadLevel(level, false, user, true)); + // overwrite + assertTrue(cm.loadLevel(level, true, user, true)); + verify(user, never()).sendMessage(anyString(), anyString(), anyString()); + } + + /** + * Test method for {@link world.bentobox.challenges.ChallengesManager#loadLevel(world.bentobox.challenges.database.object.ChallengeLevel, boolean, world.bentobox.bentobox.api.user.User, boolean)}. + */ + @Test + public void testLoadLevelOverwriteNotSilent() { + // load once + assertTrue(cm.loadLevel(level, false, user, true)); + // overwrite not silent + assertTrue(cm.loadLevel(level, true, user, false)); + verify(user).sendMessage("challenges.messages.load-overwriting", "[value]", "Novice"); } /** @@ -181,23 +336,62 @@ public class ChallengesManagerTest { */ @Test public void testRemoveFromCache() { - fail("Not yet implemented"); + cm.removeFromCache(playerID); + verify(settings).isStoreAsIslandData(); + // TODO there should be a test where isStoreAsIslandData returns true } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#wipeDatabase(boolean)}. + * @throws InterruptedException */ @Test - public void testWipeDatabase() { - fail("Not yet implemented"); + public void testWipeDatabase() throws InterruptedException { + // Create some database + this.testLoad(); + + // Verify file exists + File chDir = new File(database, "Challenge"); + File check = new File(chDir, cName + ".json"); + assertTrue(check.exists()); + + File lvDir = new File(database, "ChallengeLevel"); + File checkLv = new File(lvDir, levelName + ".json"); + assertTrue(checkLv.exists()); + + cm.setChallengeComplete(user, world, challenge, 20); + //cm.save(); + File plData = new File(database, "ChallengesPlayerData"); + File checkPd = new File(plData, playerID.toString() + ".json"); + assertTrue(checkPd.exists()); + + // Wipe it + cm.wipeDatabase(false); + + // Verify + assertFalse(check.exists()); + assertFalse(checkLv.exists()); + assertTrue(checkPd.exists()); + + cm.wipeDatabase(true); + assertFalse(checkPd.exists()); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#wipePlayers()}. + * @throws InterruptedException */ @Test - public void testWipePlayers() { - fail("Not yet implemented"); + public void testWipePlayers() throws InterruptedException { + this.testLoad(); + cm.setChallengeComplete(user, world, challenge, 20); + cm.save(); + File plData = new File(database, "ChallengesPlayerData"); + Arrays.stream(plData.listFiles()).map(f -> f.getName()).forEach(System.out::println); + File checkLv = new File(plData, playerID.toString() + ".json"); + assertTrue(checkLv.exists()); + cm.wipePlayers(); + assertFalse(checkLv.exists()); } /** @@ -205,7 +399,7 @@ public class ChallengesManagerTest { */ @Test public void testMigrateDatabase() { - fail("Not yet implemented"); + cm.migrateDatabase(user, world); } /** @@ -213,24 +407,21 @@ public class ChallengesManagerTest { */ @Test public void testSave() { - fail("Not yet implemented"); + cm.save(); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#saveChallenge(world.bentobox.challenges.database.object.Challenge)}. + * @throws InterruptedException */ @Test - public void testSaveChallenge() { - Challenge challenge = new Challenge(); - uuid = UUID.randomUUID().toString(); - challenge.setUniqueId(uuid); - challenge.setFriendlyName("name"); - challenge.setLevel("novice"); - challenge.setDescription(Collections.singletonList("A description")); + public void testSaveChallenge() throws InterruptedException { + // Async - may not happen quickly cm.saveChallenge(challenge); + Thread.sleep(500); File chDir = new File(database, "Challenge"); assertTrue(chDir.exists()); - File check = new File(chDir, uuid + ".json"); + File check = new File(chDir, cName + ".json"); assertTrue(check.exists()); // Remove icon becauseit has mockito meta in it removeLine(check); @@ -253,10 +444,8 @@ public class ChallengesManagerTest { } } } catch (FileNotFoundException e) { - // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -264,18 +453,17 @@ public class ChallengesManagerTest { } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#saveLevel(world.bentobox.challenges.database.object.ChallengeLevel)}. + * @throws InterruptedException */ @Test - public void testSaveLevel() { - ChallengeLevel level = new ChallengeLevel(); - level.setUniqueId("novice"); - level.setFriendlyName("name"); + public void testSaveLevel() throws InterruptedException { cm.saveLevel(level); + Thread.sleep(500); File chDir = new File(database, "ChallengeLevel"); assertTrue(chDir.exists()); - File check = new File(chDir, "novice.json"); + File check = new File(chDir, GAME_MODE_NAME + "_novice.json"); assertTrue(check.exists()); - // Remove icon becauseit has mockito meta in it + // Remove icon becauseit has mockito meta in it removeLine(check); } @@ -284,7 +472,7 @@ public class ChallengesManagerTest { */ @Test public void testIsChallengeCompleteUserWorldChallenge() { - fail("Not yet implemented"); + assertFalse(cm.isChallengeComplete(user, world, challenge)); } /** @@ -292,7 +480,7 @@ public class ChallengesManagerTest { */ @Test public void testIsChallengeCompleteUUIDWorldChallenge() { - fail("Not yet implemented"); + assertFalse(cm.isChallengeComplete(playerID, world, challenge)); } /** @@ -300,7 +488,7 @@ public class ChallengesManagerTest { */ @Test public void testIsChallengeCompleteUUIDWorldString() { - fail("Not yet implemented"); + assertFalse(cm.isChallengeComplete(playerID, world, "Novice")); } /** @@ -308,7 +496,9 @@ public class ChallengesManagerTest { */ @Test public void testSetChallengeCompleteUserWorldChallengeInt() { - fail("Not yet implemented"); + cm.setChallengeComplete(user, world, challenge, 3); + assertTrue(cm.isChallengeComplete(user, world, challenge)); + verify(pim).callEvent(any(ChallengeCompletedEvent.class)); } /** @@ -316,7 +506,9 @@ public class ChallengesManagerTest { */ @Test public void testSetChallengeCompleteUUIDWorldChallengeInt() { - fail("Not yet implemented"); + cm.setChallengeComplete(playerID, world, challenge, 3); + assertTrue(cm.isChallengeComplete(playerID, world, challenge)); + verify(pim).callEvent(any(ChallengeCompletedEvent.class)); } /** @@ -324,7 +516,10 @@ public class ChallengesManagerTest { */ @Test public void testSetChallengeCompleteUUIDWorldChallengeUUID() { - fail("Not yet implemented"); + UUID adminID = UUID.randomUUID(); + cm.setChallengeComplete(playerID, world, challenge, adminID); + assertTrue(cm.isChallengeComplete(playerID, world, challenge)); + verify(pim).callEvent(any(ChallengeCompletedEvent.class)); } /** @@ -332,7 +527,11 @@ public class ChallengesManagerTest { */ @Test public void testResetChallenge() { - fail("Not yet implemented"); + cm.setChallengeComplete(user, world, challenge, 3); + assertTrue(cm.isChallengeComplete(user, world, challenge)); + cm.resetChallenge(playerID, world, challenge, playerID); + assertFalse(cm.isChallengeComplete(user, world, challenge)); + verify(pim).callEvent(any(ChallengeResetEvent.class)); } /** @@ -340,7 +539,11 @@ public class ChallengesManagerTest { */ @Test public void testResetAllChallengesUserWorld() { - fail("Not yet implemented"); + cm.setChallengeComplete(user, world, challenge, 3); + assertTrue(cm.isChallengeComplete(user, world, challenge)); + cm.resetAllChallenges(user, world); + assertFalse(cm.isChallengeComplete(user, world, challenge)); + verify(pim).callEvent(any(ChallengeResetAllEvent.class)); } /** @@ -348,7 +551,11 @@ public class ChallengesManagerTest { */ @Test public void testResetAllChallengesUUIDWorldUUID() { - fail("Not yet implemented"); + cm.setChallengeComplete(user, world, challenge, 3); + assertTrue(cm.isChallengeComplete(user, world, challenge)); + cm.resetAllChallenges(playerID, world, playerID); + assertFalse(cm.isChallengeComplete(user, world, challenge)); + verify(pim).callEvent(any(ChallengeResetAllEvent.class)); } /** @@ -356,7 +563,9 @@ public class ChallengesManagerTest { */ @Test public void testGetChallengeTimesUserWorldChallenge() { - fail("Not yet implemented"); + assertEquals(0L, cm.getChallengeTimes(user, world, challenge)); + cm.setChallengeComplete(user, world, challenge, 6); + assertEquals(6L, cm.getChallengeTimes(user, world, challenge)); } /** @@ -364,7 +573,9 @@ public class ChallengesManagerTest { */ @Test public void testGetChallengeTimesUserWorldString() { - fail("Not yet implemented"); + assertEquals(0L, cm.getChallengeTimes(user, world, cName)); + cm.setChallengeComplete(user, world, challenge, 6); + assertEquals(6L, cm.getChallengeTimes(user, world, cName)); } /** @@ -372,7 +583,7 @@ public class ChallengesManagerTest { */ @Test public void testIsLevelCompleted() { - fail("Not yet implemented"); + assertFalse(cm.isLevelCompleted(user, world, level)); } /** @@ -380,7 +591,9 @@ public class ChallengesManagerTest { */ @Test public void testIsLevelUnlocked() { - fail("Not yet implemented"); + assertFalse(cm.isLevelUnlocked(user, world, level)); + this.testLoadLevelNoOverwriteSilent(); + assertTrue(cm.isLevelUnlocked(user, world, level)); } /** @@ -388,7 +601,10 @@ public class ChallengesManagerTest { */ @Test public void testSetLevelComplete() { - fail("Not yet implemented"); + assertFalse(cm.isLevelCompleted(user, world, level)); + cm.setLevelComplete(user, world, level); + assertTrue(cm.isLevelCompleted(user, world, level)); + verify(pim).callEvent(any(LevelCompletedEvent.class)); } /** @@ -396,7 +612,7 @@ public class ChallengesManagerTest { */ @Test public void testValidateLevelCompletion() { - fail("Not yet implemented"); + assertTrue(cm.validateLevelCompletion(user, world, level)); } /** @@ -404,7 +620,14 @@ public class ChallengesManagerTest { */ @Test public void testGetChallengeLevelStatus() { - fail("Not yet implemented"); + this.testLoadLevelNoOverwriteSilent(); + LevelStatus cls = cm.getChallengeLevelStatus(playerID, world, level); + assertTrue(cls.getNumberOfChallengesStillToDo() == 0); + assertEquals(level, cls.getLevel()); + assertTrue(cls.isComplete()); + assertTrue(cls.isUnlocked()); + assertEquals("BSkyBlock_novice", cls.getLevel().getUniqueId()); + } /** @@ -412,7 +635,15 @@ public class ChallengesManagerTest { */ @Test public void testGetAllChallengeLevelStatus() { - fail("Not yet implemented"); + this.testLoadLevelNoOverwriteSilent(); + List list = cm.getAllChallengeLevelStatus(user, world); + assertTrue(list.size() == 1); + LevelStatus cls = list.get(0); + assertTrue(cls.getNumberOfChallengesStillToDo() == 0); + assertEquals(level, cls.getLevel()); + assertTrue(cls.isComplete()); + assertTrue(cls.isUnlocked()); + assertEquals("BSkyBlock_novice", cls.getLevel().getUniqueId()); } /** @@ -420,7 +651,12 @@ public class ChallengesManagerTest { */ @Test public void testGetAllChallengesNames() { - fail("Not yet implemented"); + assertTrue(cm.getAllChallengesNames(world).isEmpty()); + cm.saveChallenge(challenge); + cm.loadChallenge(challenge, false, user, true); + List list = cm.getAllChallengesNames(world); + assertFalse(list.isEmpty()); + assertEquals(cName, list.get(0)); } /** @@ -428,7 +664,12 @@ public class ChallengesManagerTest { */ @Test public void testGetAllChallenges() { - fail("Not yet implemented"); + assertTrue(cm.getAllChallenges(world).isEmpty()); + cm.saveChallenge(challenge); + cm.loadChallenge(challenge, false, user, true); + List list = cm.getAllChallenges(world); + assertFalse(list.isEmpty()); + assertEquals(challenge, list.get(0)); } /** @@ -436,26 +677,50 @@ public class ChallengesManagerTest { */ @Test public void testGetFreeChallenges() { - fail("Not yet implemented"); + // Empty + assertTrue(cm.getFreeChallenges(world).isEmpty()); + // One normal + cm.saveChallenge(challenge); + cm.loadChallenge(challenge, false, user, true); + assertTrue(cm.getFreeChallenges(world).isEmpty()); + // One free + challenge.setLevel(""); + cm.saveChallenge(challenge); + cm.loadChallenge(challenge, false, user, true); + List list = cm.getFreeChallenges(world); + assertFalse(list.isEmpty()); + assertEquals(challenge, list.get(0)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#getLevelChallenges(world.bentobox.challenges.database.object.ChallengeLevel)}. + * @throws InterruptedException */ @Test - public void testGetLevelChallenges() { - fail("Not yet implemented"); + public void testGetLevelChallenges() throws InterruptedException { + assertTrue(cm.getLevelChallenges(level).isEmpty()); + // make some challenges + this.testSaveLevel(); + this.testSaveChallenge(); + level.setChallenges(Collections.singleton(challenge.getUniqueId())); + // Test again + List list = cm.getLevelChallenges(level); + assertFalse(list.isEmpty()); + assertEquals(challenge, list.get(0)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#getChallenge(java.lang.String)}. + * @throws InterruptedException */ @Test - public void testGetChallenge() { - assertNull(cm.getChallenge("name")); + public void testGetChallenge() throws InterruptedException { + assertNull(cm.getChallenge(cName)); this.testSaveLevel(); this.testSaveChallenge(); - assertNotNull(cm.getChallenge(uuid)); + Challenge ch = cm.getChallenge(cName); + assertNotNull(ch); + assertEquals(cName, ch.getUniqueId()); } /** @@ -471,15 +736,27 @@ public class ChallengesManagerTest { */ @Test public void testCreateChallenge() { - fail("Not yet implemented"); + @Nullable + Challenge ch = cm.createChallenge("newChal", ChallengeType.ISLAND, null); + assertEquals(ChallengeType.ISLAND, ch.getChallengeType()); + assertEquals("newChal", ch.getUniqueId()); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#deleteChallenge(world.bentobox.challenges.database.object.Challenge)}. + * @throws InterruptedException */ @Test - public void testDeleteChallenge() { - fail("Not yet implemented"); + public void testDeleteChallenge() throws InterruptedException { + this.testSaveLevel(); + this.testSaveChallenge(); + Challenge ch = cm.getChallenge(cName); + assertNotNull(ch); + assertEquals(cName, ch.getUniqueId()); + cm.deleteChallenge(challenge); + ch = cm.getChallenge(cName); + assertNull(ch); + verify(plhm).unregisterPlaceholder(eq("challenges_challenge_repetition_count_" + cName)); } /** @@ -487,7 +764,10 @@ public class ChallengesManagerTest { */ @Test public void testGetLevels() { - fail("Not yet implemented"); + this.testGetLevelString(); + List lvs = cm.getLevels(world); + assertFalse(lvs.isEmpty()); + assertEquals(level, lvs.get(0)); } /** @@ -495,7 +775,8 @@ public class ChallengesManagerTest { */ @Test public void testGetLevelChallenge() { - fail("Not yet implemented"); + this.testGetLevelString(); + assertEquals(level, cm.getLevel(challenge)); } /** @@ -503,7 +784,10 @@ public class ChallengesManagerTest { */ @Test public void testGetLevelString() { - fail("Not yet implemented"); + assertNull(cm.getLevel("dss")); + cm.saveLevel(level); + cm.loadLevel(level, false, user, true); + assertEquals(level, cm.getLevel(levelName)); } /** @@ -511,23 +795,33 @@ public class ChallengesManagerTest { */ @Test public void testContainsLevel() { - fail("Not yet implemented"); + this.testGetLevelString(); + assertFalse(cm.containsLevel("sdsd")); + assertTrue(cm.containsLevel(levelName)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#addChallengeToLevel(world.bentobox.challenges.database.object.Challenge, world.bentobox.challenges.database.object.ChallengeLevel)}. + * @throws InterruptedException */ @Test - public void testAddChallengeToLevel() { - fail("Not yet implemented"); + public void testAddChallengeToLevel() throws InterruptedException { + this.testLoad(); + cm.deleteChallenge(challenge); + assertFalse(cm.containsChallenge(cName)); + cm.addChallengeToLevel(challenge, level); + assertEquals(level, cm.getLevel(challenge)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#removeChallengeFromLevel(world.bentobox.challenges.database.object.Challenge, world.bentobox.challenges.database.object.ChallengeLevel)}. + * @throws InterruptedException */ @Test - public void testRemoveChallengeFromLevel() { - fail("Not yet implemented"); + public void testRemoveChallengeFromLevel() throws InterruptedException { + this.testAddChallengeToLevel(); + cm.removeChallengeFromLevel(challenge, level); + assertFalse(cm.containsChallenge(cName)); } /** @@ -535,31 +829,44 @@ public class ChallengesManagerTest { */ @Test public void testCreateLevel() { - fail("Not yet implemented"); + @Nullable + ChallengeLevel cl = cm.createLevel("Expert", world); + assertEquals("Expert", cl.getUniqueId()); + assertEquals(world.getName(), cl.getWorld()); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#deleteChallengeLevel(world.bentobox.challenges.database.object.ChallengeLevel)}. + * @throws InterruptedException */ @Test - public void testDeleteChallengeLevel() { - fail("Not yet implemented"); + public void testDeleteChallengeLevel() throws InterruptedException { + this.testAddChallengeToLevel(); + assertTrue(cm.containsLevel(levelName)); + cm.deleteChallengeLevel(level); + assertFalse(cm.containsLevel(levelName)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#hasAnyChallengeData(org.bukkit.World)}. + * @throws InterruptedException */ @Test - public void testHasAnyChallengeDataWorld() { - fail("Not yet implemented"); + public void testHasAnyChallengeDataWorld() throws InterruptedException { + assertFalse(cm.hasAnyChallengeData(world)); + this.testLoad(); + assertTrue(cm.hasAnyChallengeData(world)); } /** * Test method for {@link world.bentobox.challenges.ChallengesManager#hasAnyChallengeData(java.lang.String)}. + * @throws InterruptedException */ @Test - public void testHasAnyChallengeDataString() { - fail("Not yet implemented"); + public void testHasAnyChallengeDataString() throws InterruptedException { + assertFalse(cm.hasAnyChallengeData("BSkyBlock")); + this.testLoad(); + assertTrue(cm.hasAnyChallengeData("BSkyBlock")); } }