diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b9cf60c..825b18d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,21 +11,22 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: Set up JDK 16 - uses: actions/setup-java@v1 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: 16 + distribution: 'adopt' + java-version: 17 - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/pom.xml b/pom.xml index 41a680c..912a519 100644 --- a/pom.xml +++ b/pom.xml @@ -55,18 +55,18 @@ UTF-8 UTF-8 - 8 + 17 2.0.9 - 1.16.5-R0.1-SNAPSHOT - 1.16.2 + 1.20.3-R0.1-SNAPSHOT + 2.0.0-SNAPSHOT ${build.version}-SNAPSHOT -LOCAL - 1.11.0 + 1.12.0 BentoBoxWorld_addon-invSwitcher bentobox-world @@ -113,30 +113,6 @@ - - sonar - - https://sonarcloud.io - bentobox-world - - - - - org.sonarsource.scanner.maven - sonar-maven-plugin - 3.6.0.1398 - - - verify - - sonar - - - - - - - @@ -237,7 +213,34 @@ 3.0.0-M5 - --illegal-access=permit + ${argLine} + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.math=ALL-UNNAMED + --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.util.stream=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED + --add-opens + java.base/java.util.regex=ALL-UNNAMED + --add-opens + java.base/java.nio.channels.spi=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED + --add-opens java.base/java.net=ALL-UNNAMED + --add-opens + java.base/java.util.concurrent=ALL-UNNAMED + --add-opens java.base/sun.nio.fs=ALL-UNNAMED + --add-opens java.base/sun.nio.cs=ALL-UNNAMED + --add-opens java.base/java.nio.file=ALL-UNNAMED + --add-opens + java.base/java.nio.charset=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.logging/java.util.logging=ALL-UNNAMED + --add-opens java.base/java.lang.ref=ALL-UNNAMED + --add-opens java.base/java.util.jar=ALL-UNNAMED + --add-opens java.base/java.util.zip=ALL-UNNAMED @@ -280,30 +283,36 @@ org.jacoco jacoco-maven-plugin - 0.8.3 + 0.8.10 true **/*Names* + org/bukkit/Material* - pre-unit-test + prepare-agent prepare-agent - post-unit-test + report report + + + XML + + - \ No newline at end of file + diff --git a/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java b/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java index ecb6300..c5f279a 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java +++ b/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java @@ -15,12 +15,19 @@ import world.bentobox.bentobox.api.configuration.Config; import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; +/** + * Inventory switcher for worlds. Switches advancements too. + * + * @author tastybento + * + */ public class InvSwitcher extends Addon { + private Store store; private Settings settings; - private Config config = new Config<>(this, Settings.class); + private final Config config = new Config<>(this, Settings.class); private Set worlds = new HashSet<>(); @@ -75,7 +82,6 @@ public void onEnable() { if (this.getPlugin().getSettings().getDatabaseType().equals(DatabaseType.YAML)) { this.setState(State.DISABLED); this.logError("This addon is incompatible with YAML database. Please use another type, like JSON."); - return; } } diff --git a/src/main/java/com/wasteofplastic/invswitcher/Settings.java b/src/main/java/com/wasteofplastic/invswitcher/Settings.java index b808437..247e802 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/Settings.java +++ b/src/main/java/com/wasteofplastic/invswitcher/Settings.java @@ -30,13 +30,11 @@ public class Settings implements ConfigObject { private boolean gamemode = true; @ConfigEntry(path = "options.experience") private boolean experience = true; - @ConfigEntry(path = "options.location") - private boolean location = true; @ConfigEntry(path = "options.ender-chest") private boolean enderChest = true; @ConfigEntry(path = "options.statistics") private boolean statistics = true; - + /** * @return the worlds */ @@ -121,18 +119,6 @@ public boolean isExperience() { public void setExperience(boolean experience) { this.experience = experience; } - /** - * @return the location - */ - public boolean isLocation() { - return location; - } - /** - * @param location the location to set - */ - public void setLocation(boolean location) { - this.location = location; - } /** * @return the enderChest */ diff --git a/src/main/java/com/wasteofplastic/invswitcher/Store.java b/src/main/java/com/wasteofplastic/invswitcher/Store.java index 76370a1..d218f27 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/Store.java +++ b/src/main/java/com/wasteofplastic/invswitcher/Store.java @@ -24,11 +24,12 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -39,13 +40,15 @@ import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import com.wasteofplastic.invswitcher.dataObjects.InventoryStorage; +import com.wasteofplastic.invswitcher.dataobjects.InventoryStorage; import world.bentobox.bentobox.database.Database; +import world.bentobox.bentobox.util.Util; /** * Enables inventory switching between games. Handles food, experience and spawn points. @@ -53,6 +56,13 @@ * */ public class Store { + private static final CharSequence THE_END = "_the_end"; + private static final CharSequence NETHER = "_nether"; + @SuppressWarnings("deprecation") + private static final List BLOCKS = Arrays.stream(Material.values()).filter(Material::isBlock).filter(m -> !m.isLegacy()).toList(); + @SuppressWarnings("deprecation") + private static final List ITEMS = Arrays.stream(Material.values()).filter(Material::isItem).filter(m -> !m.isLegacy()).toList(); + private static final List LIVING_ENTITIES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).toList(); private final Database database; private final Map cache; private final InvSwitcher addon; @@ -72,7 +82,7 @@ public Store(InvSwitcher addon) { public boolean isWorldStored(Player player, World world) { // Get the store InventoryStorage store = getInv(player); - String overworldName = (world.getName().replace("_the_end", "")).replace("_nether", ""); + String overworldName = (world.getName().replace(THE_END, "")).replace(NETHER, ""); return store.isInventory(overworldName); } @@ -85,36 +95,18 @@ public void getInventory(Player player, World world) { // Get the store InventoryStorage store = getInv(player); - // Do not differentiate between world environments. Only the location is different - String worldName = world.getName(); - - String overworldName = (world.getName().replace("_the_end", "")).replace("_nether", ""); + // Do not differentiate between world environments. + String overworldName = Objects.requireNonNull(Util.getWorld(world)).getName(); // Inventory if (addon.getSettings().isInventory()) { player.getInventory().setContents(store.getInventory(overworldName).toArray(new ItemStack[0])); } if (addon.getSettings().isHealth()) { - // Health - double health = store.getHealth().getOrDefault(overworldName, player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); - - if (health > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { - health = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); - } - if (health < 0D) { - health = 0D; - } - player.setHealth(health); + setHeath(store, player, overworldName); } if (addon.getSettings().isFood()) { - // Food - int food = store.getFood().getOrDefault(overworldName, 20); - if (food > 20) { - food = 20; - } else if (food < 0) { - food = 0; - } - player.setFoodLevel(food); + setFood(store, player, overworldName); } if (addon.getSettings().isExperience()) { // Experience @@ -125,21 +117,7 @@ public void getInventory(Player player, World world) { player.setGameMode(store.getGameMode(overworldName)); } if (addon.getSettings().isAdvancements()) { - // Advancements - store.getAdvancements(overworldName).forEach((k, v) -> { - Iterator it = Bukkit.advancementIterator(); - while (it.hasNext()) { - Advancement a = it.next(); - if (a.getKey().toString().equals(k)) { - // Award - v.forEach(player.getAdvancementProgress(a)::awardCriteria); - } - } - }); - } - if (addon.getSettings().isLocation()) { - // Get Spawn Point - store.getLocation(worldName); + setAdvancements(store, player, overworldName); } if (addon.getSettings().isEnderChest()) { player.getEnderChest().setContents(store.getEnderChest(overworldName).toArray(new ItemStack[0])); @@ -149,6 +127,48 @@ public void getInventory(Player player, World world) { } } + private void setHeath(InventoryStorage store, Player player, String overworldName) { + // Health + double health = store.getHealth().getOrDefault(overworldName, player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); + + AttributeInstance attr = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attr != null && health > attr.getValue()) { + health = attr.getValue(); + } + if (health < 0D) { + health = 0D; + } + player.setHealth(health); + + } + + private void setFood(InventoryStorage store, Player player, String overworldName) { + // Food + int food = store.getFood().getOrDefault(overworldName, 20); + if (food > 20) { + food = 20; + } else if (food < 0) { + food = 0; + } + player.setFoodLevel(food); + + } + + private void setAdvancements(InventoryStorage store, Player player, String overworldName) { + // Advancements + store.getAdvancements(overworldName).forEach((k, v) -> { + Iterator it = Bukkit.advancementIterator(); + while (it.hasNext()) { + Advancement a = it.next(); + if (a.getKey().toString().equals(k)) { + // Award + v.forEach(player.getAdvancementProgress(a)::awardCriteria); + } + } + }); + + } + public void removeFromCache(Player player) { cache.remove(player.getUniqueId()); } @@ -196,7 +216,7 @@ public void storeAndSave(Player player, World world) { InventoryStorage store = getInv(player); // Do not differentiate between world environments String worldName = world.getName(); - String overworldName = (world.getName().replace("_the_end", "")).replace("_nether", ""); + String overworldName = (world.getName().replace(THE_END, "")).replace(NETHER, ""); if (addon.getSettings().isInventory()) { // Copy the player's items to the store List contents = Arrays.asList(player.getInventory().getContents()); @@ -211,9 +231,6 @@ public void storeAndSave(Player player, World world) { if (addon.getSettings().isExperience()) { store.setExp(overworldName, getTotalExperience(player)); } - if (addon.getSettings().isLocation()) { - store.setLocation(worldName, player.getLocation()); - } if (addon.getSettings().isGamemode()) { store.setGameMode(overworldName, player.getGameMode()); } @@ -240,48 +257,40 @@ public void storeAndSave(Player player, World world) { database.saveObjectAsync(store); } - @SuppressWarnings("deprecation") private void saveStats(InventoryStorage store, Player player, String worldName) { store.clearStats(worldName); // Statistics Arrays.stream(Statistic.values()).forEach(s -> { Map map; Map entMap; - switch(s.getType()) { - case BLOCK: - map = Arrays.stream(Material.values()).filter(Material::isBlock) - .filter(m -> !m.isLegacy()) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + switch (s.getType()) { + case BLOCK -> { + map = BLOCKS.stream().filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); if (!map.isEmpty()) { store.getBlockStats(worldName).put(s, map); } - case ITEM: - map = Arrays.stream(Material.values()).filter(Material::isItem) - .filter(m -> !m.isLegacy()) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + } + case ITEM -> { + map = ITEMS.stream().filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); if (!map.isEmpty()) { store.getItemStats(worldName).put(s, map); } - break; - case ENTITY: - entMap = Arrays.stream(EntityType.values()).filter(EntityType::isAlive) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + } + case ENTITY -> { + entMap = LIVING_ENTITIES.stream().filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); if (!entMap.isEmpty()) { store.getEntityStats(worldName).put(s, entMap); } - break; - case UNTYPED: + } + case UNTYPED -> { int sc = player.getStatistic(s); if (sc > 0) { store.getUntypedStats(worldName).put(s, sc); } - break; - default: - break; - + } } }); @@ -295,86 +304,73 @@ private void saveStats(InventoryStorage store, Player player, String worldName) */ private void getStats(InventoryStorage store, Player player, String worldName) { // Statistics - Arrays.stream(Statistic.values()).forEach(s -> { - switch(s.getType()) { - case BLOCK: - if (store.getBlockStats(worldName).containsKey(s)) { - for (Entry en : store.getBlockStats(worldName).get(s).entrySet()) { - player.setStatistic(s, en.getKey(), en.getValue()); - } - } - break; - case ITEM: - if (store.getItemStats(worldName).containsKey(s)) { - for (Entry en : store.getItemStats(worldName).get(s).entrySet()) { - player.setStatistic(s, en.getKey(), en.getValue()); - } - } - break; - case ENTITY: - if (store.getEntityStats(worldName).containsKey(s)) { - for (Entry en : store.getEntityStats(worldName).get(s).entrySet()) { - player.setStatistic(s, en.getKey(), en.getValue()); - } - } - break; - case UNTYPED: - if (store.getUntypedStats(worldName).containsKey(s)) { - player.setStatistic(s, store.getUntypedStats(worldName).get(s)); - } - break; - default: - break; + Arrays.stream(Statistic.values()).forEach(s -> getStat(s, store, player, worldName)); - } - }); + } + private void getStat(Statistic s, InventoryStorage store, Player player, String worldName) { + switch(s.getType()) { + case BLOCK -> store.getBlockStats(worldName).getOrDefault(s, Collections.emptyMap()).forEach((k,v) -> player.setStatistic(s, k, v)); + case ITEM -> store.getItemStats(worldName).getOrDefault(s, Collections.emptyMap()).forEach((k,v) -> player.setStatistic(s, k, v)); + case ENTITY -> store.getEntityStats(worldName).getOrDefault(s, Collections.emptyMap()).forEach((k,v) -> player.setStatistic(s, k, v)); + case UNTYPED -> { + if (store.getUntypedStats(worldName).containsKey(s)) { + player.setStatistic(s, store.getUntypedStats(worldName).get(s)); + } + } + } } - @SuppressWarnings("deprecation") private void clearPlayer(Player player) { - // Clear the player's inventory - player.getInventory().clear(); - setTotalExperience(player, 0); + if (this.addon.getSettings().isInventory()) + { + // Clear the player's inventory + player.getInventory().clear(); + } + + if (this.addon.getSettings().isExperience()) + { + // Reset experience + setTotalExperience(player, 0); + } + + if (this.addon.getSettings().isAdvancements()) + { + // Reset advancements + resetAdv(player); + } + + if (this.addon.getSettings().isEnderChest()) + { + // Reset enderchest + player.getEnderChest().clear(); + } + + if (this.addon.getSettings().isStatistics()) + { + // Reset Statistics + Arrays.stream(Statistic.values()).forEach(s -> + resetStats(player, s)); + } + } + + private void resetAdv(Player player) { Iterator it = Bukkit.advancementIterator(); - while (it.hasNext()) { + while (it.hasNext()) + { Advancement a = it.next(); AdvancementProgress p = player.getAdvancementProgress(a); p.getAwardedCriteria().forEach(p::revokeCriteria); } - player.getEnderChest().clear(); - // Statistics - Arrays.stream(Statistic.values()).forEach(s -> { - switch(s.getType()) { - case BLOCK: - for (Material m: Material.values()) { - if (m.isBlock() && !m.isLegacy()) { - player.setStatistic(s, m, 0); - } - } - case ITEM: - for (Material m: Material.values()) { - if (m.isItem() && !m.isLegacy()) { - player.setStatistic(s, m, 0); - } - } - break; - case ENTITY: - for (EntityType en: EntityType.values()) { - if (en.isAlive()) { - player.setStatistic(s, en, 0); - } - } - break; - case UNTYPED: - player.setStatistic(s, 0); - break; - default: - break; - - } + } - }); + private void resetStats(Player player, Statistic s) { + switch (s.getType()) { + case BLOCK -> BLOCKS.forEach(m -> player.setStatistic(s, m, 0)); + case ITEM -> ITEMS.forEach(m -> player.setStatistic(s, m, 0)); + case ENTITY -> LIVING_ENTITIES.forEach(en -> player.setStatistic(s, en, 0)); + case UNTYPED -> player.setStatistic(s, 0); + } } //new Exp Math from 1.8 diff --git a/src/main/java/com/wasteofplastic/invswitcher/dataObjects/InventoryStorage.java b/src/main/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorage.java similarity index 97% rename from src/main/java/com/wasteofplastic/invswitcher/dataObjects/InventoryStorage.java rename to src/main/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorage.java index ef0575c..48c2b8e 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/dataObjects/InventoryStorage.java +++ b/src/main/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorage.java @@ -1,4 +1,4 @@ -package com.wasteofplastic.invswitcher.dataObjects; +package com.wasteofplastic.invswitcher.dataobjects; import java.util.ArrayList; import java.util.Collections; @@ -174,12 +174,6 @@ public boolean isInventory(String overworldName) { return inventory != null && inventory.containsKey(overworldName); } - public void getLocation(String worldName) { - if (location != null) { - location.get(worldName); - } - } - public void setGameMode(String worldName, GameMode gameMode) { this.gameMode.put(worldName, gameMode); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index d180f1c..c8f9085 100755 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,6 +16,5 @@ options: advancements: true gamemode: true experience: true - location: true ender-chest: true statistics: true diff --git a/src/test/java/com/wasteofplastic/invswitcher/InvSwitcherTest.java b/src/test/java/com/wasteofplastic/invswitcher/InvSwitcherTest.java new file mode 100644 index 0000000..401bb08 --- /dev/null +++ b/src/test/java/com/wasteofplastic/invswitcher/InvSwitcherTest.java @@ -0,0 +1,237 @@ +package com.wasteofplastic.invswitcher; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import com.wasteofplastic.invswitcher.listeners.PlayerListener; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.Settings; +import world.bentobox.bentobox.api.addons.Addon.State; +import world.bentobox.bentobox.api.addons.AddonDescription; +import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; +import world.bentobox.bentobox.managers.AddonsManager; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BentoBox.class}) +public class InvSwitcherTest { + + private static File jFile; + @Mock + private BentoBox plugin; + @Mock + private AddonsManager am; + + @Mock + private Settings pluginSettings; + + private InvSwitcher addon; + + @Mock + private Logger logger; + @Mock + private World world; + + @BeforeClass + public static void beforeClass() throws IOException { + // Make the addon jar + jFile = new File("addon.jar"); + // Copy over config file from src folder + Path fromPath = Paths.get("src/main/resources/config.yml"); + Path path = Paths.get("config.yml"); + Files.copy(fromPath, path); + try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) { + //Added the new files to the jar. + try (FileInputStream fis = new FileInputStream(path.toFile())) { + byte[] buffer = new byte[1024]; + int bytesRead; + JarEntry entry = new JarEntry(path.toString()); + tempJarOutputStream.putNextEntry(entry); + while((bytesRead = fis.read(buffer)) != -1) { + tempJarOutputStream.write(buffer, 0, bytesRead); + } + } + } + } + + /** + */ + @Before + public void setUp() { + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); + + // The database type has to be created one line before the thenReturn() to work! + DatabaseType value = DatabaseType.YAML; + when(plugin.getSettings()).thenReturn(pluginSettings); + when(pluginSettings.getDatabaseType()).thenReturn(value); + + // Addon + addon = new InvSwitcher(); + File dataFolder = new File("addons/Level"); + addon.setDataFolder(dataFolder); + addon.setFile(jFile); + AddonDescription desc = new AddonDescription.Builder("bentobox", "InvSwitcher", "1.3").description("test").authors("tastybento").build(); + addon.setDescription(desc); + // Addons manager + when(plugin.getAddonsManager()).thenReturn(am); + + // Bukkit + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getWorld(anyString())).thenReturn(world); + + // World + when(world.getName()).thenReturn("bskyblock-world"); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + deleteAll(new File("database")); + } + + @AfterClass + public static void cleanUp() throws Exception { + deleteAll(new File("database")); + new File("addon.jar").delete(); + new File("config.yml").delete(); + deleteAll(new File("addons")); + } + + private static void deleteAll(File file) throws IOException { + if (file.exists()) { + Files.walk(file.toPath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#onEnable()}. + */ + @Test + public void testOnEnable() { + addon.onEnable(); + verify(plugin).logError("[InvSwitcher] This addon is incompatible with YAML database. Please use another type, like JSON."); + assertEquals(State.DISABLED, addon.getState()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#onDisable()}. + */ + @Test + public void testOnDisable() { + addon.onLoad(); + addon.getSettings().setWorlds(Set.of("bskyblock-world")); + addon.allLoaded(); + addon.onDisable(); + PowerMockito.verifyStatic(Bukkit.class); + Bukkit.getOnlinePlayers(); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#onLoad()}. + */ + @Test + public void testOnLoad() { + addon.onLoad(); + File file = new File("config.yml"); + assertTrue(file.exists()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#allLoaded()}. + */ + @Test + public void testAllLoaded() { + addon.onLoad(); + addon.getSettings().setWorlds(Set.of("bskyblock-world")); + addon.allLoaded(); + verify(plugin).log("[InvSwitcher] Hooking into the following worlds:"); + verify(plugin, times(3)).log("[InvSwitcher] bskyblock-world"); + verify(am).registerListener(eq(addon), any(PlayerListener.class)); + + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#allLoaded()}. + */ + @Test + public void testAllLoadedNoWorlds() { + addon.onLoad(); + addon.getSettings().setWorlds(Collections.emptySet()); + addon.allLoaded(); + verify(plugin).logWarning("[InvSwitcher] Did not hook into any worlds - disabling addon!"); + assertEquals(State.DISABLED, addon.getState()); + verify(plugin, never()).log("Hooking into the following worlds:"); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#getStore()}. + */ + @Test + public void testGetStore() { + assertNull(addon.getStore()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#getSettings()}. + */ + @Test + public void testGetSettings() { + assertNull(addon.getSettings()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.InvSwitcher#getWorlds()}. + */ + @Test + public void testGetWorlds() { + assertTrue(addon.getWorlds().isEmpty()); + } + +} diff --git a/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java b/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java index e341afc..c447828 100644 --- a/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java +++ b/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java @@ -1,7 +1,13 @@ package com.wasteofplastic.invswitcher; +import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -12,11 +18,13 @@ import java.util.Collections; import java.util.Comparator; import java.util.UUID; +import java.util.logging.Logger; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -25,6 +33,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; @@ -32,13 +42,14 @@ import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.Settings; import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; +import world.bentobox.bentobox.util.Util; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class}) +@PrepareForTest({Bukkit.class, Util.class}) public class StoreTest { @Mock @@ -48,10 +59,18 @@ public class StoreTest { @Mock private World world; + private Store s; private com.wasteofplastic.invswitcher.Settings sets; + @Mock + private Logger logger; + @Before public void setUp() { + // Bukkit + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); + + // BentoBox BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); Settings settings = mock(Settings.class); @@ -79,9 +98,20 @@ public void setUp() { World fromWorld = mock(World.class); when(fromWorld.getName()).thenReturn("from_the_end_nether"); + // Settings sets = new com.wasteofplastic.invswitcher.Settings(); when(addon.getSettings()).thenReturn(sets); when(addon.getWorlds()).thenReturn(Collections.singleton(world)); + + // Addon + when(addon.getLogger()).thenReturn(logger); + + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(world)).thenReturn(world); + when(Util.getWorld(fromWorld)).thenReturn(fromWorld); + + // Class under test + s = new Store(addon); } @After @@ -102,8 +132,17 @@ public void clear() throws IOException{ */ @Test public void testStore() { - new Store(addon); - verify(addon).getLogger(); + assertNotNull(s); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.Store#isWorldStored(org.bukkit.entity.Player, org.bukkit.World)}. + */ + @Test + public void testIsWorldStored() { + assertFalse(s.isWorldStored(player, world)); + s.storeInventory(player, world); + assertTrue(s.isWorldStored(player, world)); } /** @@ -111,7 +150,6 @@ public void testStore() { */ @Test public void testGetInventory() { - Store s = new Store(addon); s.getInventory(player, world); verify(player).setFoodLevel(20); verify(player).setHealth(18); @@ -120,13 +158,93 @@ public void testGetInventory() { } /** - * Test method for {@link Store#storeInventory(Player, World)}. + * Test method for {@link com.wasteofplastic.invswitcher.Store#removeFromCache(org.bukkit.entity.Player)}. + */ + @Test + public void testRemoveFromCache() { + testIsWorldStored(); + s.removeFromCache(player); + assertFalse(s.isWorldStored(player, world)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.Store#storeInventory(org.bukkit.entity.Player, org.bukkit.World)}. */ - /* - * TODO: Works in Eclipse, fails in MVN... @Test - public void testStoreInventoryPlayerWorldLocation() { - new Store(addon).storeInventory(player, world); + public void testStoreInventoryNothing() { + // Do not actually save anything + sets.setAdvancements(false); + sets.setEnderChest(false); + sets.setExperience(false); + sets.setFood(false); + sets.setGamemode(false); + sets.setHealth(false); + sets.setInventory(false); + sets.setStatistics(false); + s.storeInventory(player, world); + verify(player, never()).getInventory(); + verify(player, never()).getEnderChest(); + verify(player, never()).getFoodLevel(); + verify(player, never()).getExp(); + verify(player, never()).getLevel(); + verify(player, never()).getHealth(); + verify(player, never()).getGameMode(); + verify(player, never()).getAdvancementProgress(any()); + PowerMockito.verifyStatic(Bukkit.class, never()); + Bukkit.advancementIterator(); + // No Player clearing + verify(player, never()).setExp(anyFloat()); + verify(player, never()).setLevel(anyInt()); + verify(player, never()).setTotalExperience(anyInt()); + verify(player, never()).setStatistic(any(), any(EntityType.class), anyInt()); + verify(player, never()).setStatistic(any(), any(Material.class), anyInt()); + verify(player, never()).setStatistic(any(), anyInt()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.Store#storeInventory(org.bukkit.entity.Player, org.bukkit.World)}. */ + @Test + public void testStoreInventoryAll() { + // Do not actually save anything + sets.setAdvancements(true); + sets.setEnderChest(true); + sets.setExperience(true); + sets.setFood(true); + sets.setGamemode(true); + sets.setHealth(true); + sets.setInventory(true); + sets.setStatistics(true); + s.storeInventory(player, world); + verify(player, times(2)).getInventory(); + verify(player, times(2)).getEnderChest(); + verify(player).getFoodLevel(); + verify(player).getExp(); + verify(player, times(2)).getLevel(); + verify(player).getHealth(); + verify(player).getGameMode(); + PowerMockito.verifyStatic(Bukkit.class, times(2)); + Bukkit.advancementIterator(); + // Player clearing + verify(player).setExp(0); + verify(player).setLevel(0); + verify(player).setTotalExperience(0); + verify(player, atLeastOnce()).setStatistic(any(), any(EntityType.class), anyInt()); + verify(player, atLeastOnce()).setStatistic(any(), any(Material.class), anyInt()); + verify(player, atLeastOnce()).setStatistic(any(), anyInt()); + + + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.Store#saveOnlinePlayers()}. + */ + @Test + public void testSaveOnlinePlayers() { + s.saveOnlinePlayers(); + PowerMockito.verifyStatic(Bukkit.class); + Bukkit.getOnlinePlayers(); + } + } diff --git a/src/test/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorageTest.java b/src/test/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorageTest.java new file mode 100644 index 0000000..a0a39e8 --- /dev/null +++ b/src/test/java/com/wasteofplastic/invswitcher/dataobjects/InventoryStorageTest.java @@ -0,0 +1,375 @@ +package com.wasteofplastic.invswitcher.dataobjects; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * @author tastybentos + * + */ +@RunWith(PowerMockRunner.class) +public class InventoryStorageTest { + + private InventoryStorage is; + + /** + */ + @Before + public void setUp() { + is = new InventoryStorage(); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getUniqueId()}. + */ + @Test + public void testGetUniqueId() { + assertNull(is.getUniqueId()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setUniqueId(java.lang.String)}. + */ + @Test + public void testSetUniqueId() { + String uuid = UUID.randomUUID().toString(); + is.setUniqueId(uuid); + assertEquals(uuid, is.getUniqueId()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getInventory()}. + */ + @Test + public void testGetInventory() { + assertTrue(is.getInventory().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getHealth()}. + */ + @Test + public void testGetHealth() { + assertTrue(is.getHealth().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getFood()}. + */ + @Test + public void testGetFood() { + assertTrue(is.getFood().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getExp()}. + */ + @Test + public void testGetExp() { + assertTrue(is.getExp().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getLocation()}. + */ + @Test + public void testGetLocation() { + assertTrue(is.getLocation().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setInventory(java.util.Map)}. + */ + @Test + public void testSetInventoryMapOfStringListOfItemStack() { + ItemStack item = new ItemStack(Material.ACACIA_BOAT); + is.setInventory(Map.of("test", List.of(item))); + Map> map = is.getInventory(); + assertEquals(item, map.get("test").get(0)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setInventory(java.lang.String, java.util.List)}. + */ + @Test + public void testSetInventoryStringListOfItemStack() { + ItemStack item = new ItemStack(Material.ACACIA_BOAT); + is.setInventory("worldName", List.of(item)); + Map> map = is.getInventory(); + assertEquals(item, map.get("worldName").get(0)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setHealth(java.util.Map)}. + */ + @Test + public void testSetHealthMapOfStringDouble() { + Map map = Map.of("test", 234D); + is.setHealth(map); + assertEquals(234D, is.getHealth().get("test"), 0D); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setFood(java.util.Map)}. + */ + @Test + public void testSetFoodMapOfStringInteger() { + Map map = Map.of("test", 234); + is.setFood(map); + assertEquals(234, is.getFood().get("test").intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setExp(java.util.Map)}. + */ + @Test + public void testSetExpMapOfStringInteger() { + Map map = Map.of("test", 234); + is.setExp(map); + assertEquals(234, is.getExp().get("test").intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setLocation(java.util.Map)}. + */ + @Test + public void testSetLocationMapOfStringLocation() { + Location loc = mock(Location.class); + Map map = Map.of("test", loc); + is.setLocation(map); + assertEquals(loc, is.getLocation().get("test")); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setHealth(java.lang.String, double)}. + */ + @Test + public void testSetHealthStringDouble() { + is.setHealth("test", 10D); + assertEquals(10D, is.getHealth().get("test"), 0D); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setFood(java.lang.String, int)}. + */ + @Test + public void testSetFoodStringInt() { + is.setFood("test", 234); + assertEquals(234, is.getFood().get("test").intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setExp(java.lang.String, int)}. + */ + @Test + public void testSetExpStringInt() { + is.setExp("test", 234); + assertEquals(234, is.getExp().get("test").intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setLocation(java.lang.String, org.bukkit.Location)}. + */ + @Test + public void testSetLocationStringLocation() { + Location loc = mock(Location.class); + is.setLocation("test", loc); + assertEquals(loc, is.getLocation().get("test")); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getInventory(java.lang.String)}. + */ + @Test + public void testGetInventoryString() { + assertTrue(is.getInventory("test").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#isInventory(java.lang.String)}. + */ + @Test + public void testIsInventory() { + assertFalse(is.isInventory("test")); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setGameMode(java.lang.String, org.bukkit.GameMode)}. + */ + @Test + public void testSetGameMode() { + is.setGameMode("test", GameMode.ADVENTURE); + assertEquals(GameMode.ADVENTURE, is.getGameMode("test")); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getGameMode(java.lang.String)}. + */ + @Test + public void testGetGameMode() { + is.setGameMode("test2", GameMode.ADVENTURE); + assertEquals(GameMode.SURVIVAL, is.getGameMode("test")); + assertEquals(GameMode.ADVENTURE, is.getGameMode("test2")); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setAdvancement(java.lang.String, java.lang.String, java.util.List)}. + */ + @Test + public void testSetAdvancement() { + is.setAdvancement("word", "key", List.of("criteria", "cirt")); + assertTrue(is.getAdvancements("test").isEmpty()); + Map> r = is.getAdvancements("word"); + assertEquals("cirt", r.get("key").get(1)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#clearAdvancement(java.lang.String)}. + */ + @Test + public void testClearAdvancement() { + is.setAdvancement("word", "key", List.of("criteria", "cirt")); + assertFalse(is.getAdvancements("word").isEmpty()); + is.clearAdvancement("wowoow"); + assertFalse(is.getAdvancements("word").isEmpty()); + is.clearAdvancement("word"); + assertTrue(is.getAdvancements("word").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getAdvancements(java.lang.String)}. + */ + @Test + public void testGetAdvancements() { + assertTrue(is.getAdvancements("test").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getEnderChest(java.lang.String)}. + */ + @Test + public void testGetEnderChestString() { + assertTrue(is.getEnderChest("test").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setEnderChest(java.lang.String, java.util.List)}. + */ + @Test + public void testSetEnderChestStringListOfItemStack() { + ItemStack item = new ItemStack(Material.ACACIA_BOAT); + is.setEnderChest("worldName", List.of(item)); + Map> map = is.getEnderChest(); + assertEquals(item, map.get("worldName").get(0)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getEnderChest()}. + */ + @Test + public void testGetEnderChest() { + assertTrue(is.getEnderChest().isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setEnderChest(java.util.Map)}. + */ + @Test + public void testSetEnderChestMapOfStringListOfItemStack() { + ItemStack item = new ItemStack(Material.ACACIA_BOAT); + Map> map = Map.of("worldName", List.of(item)); + is.setEnderChest(map); + Map> map2 = is.getEnderChest(); + assertEquals(item, map2.get("worldName").get(0)); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#clearStats(java.lang.String)}. + */ + @Test + public void testClearStats() { + is.setBlockStats("test", Map.of(Statistic.MINE_BLOCK, Map.of(Material.STONE, 3000))); + is.setEntityStats("test", Map.of(Statistic.ENTITY_KILLED_BY, Map.of(EntityType.BEE, 4000))); + is.setItemStats("test", Map.of(Statistic.USE_ITEM, Map.of(Material.DIAMOND_AXE, 5000))); + is.setUntypedStats("test", Map.of(Statistic.ARMOR_CLEANED, 30)); + is.clearStats("test2"); + assertFalse(is.getBlockStats("test").isEmpty()); + assertFalse(is.getEntityStats("test").isEmpty()); + assertFalse(is.getItemStats("test").isEmpty()); + assertFalse(is.getUntypedStats("test").isEmpty()); + is.clearStats("test"); + assertTrue(is.getBlockStats("test").isEmpty()); + assertTrue(is.getEntityStats("test").isEmpty()); + assertTrue(is.getItemStats("test").isEmpty()); + assertTrue(is.getUntypedStats("test").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getUntypedStats(java.lang.String)}. + */ + @Test + public void testGetUntypedStats() { + assertTrue(is.getUntypedStats("test").isEmpty()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#setUntypedStats(java.lang.String, java.util.Map)}. + */ + @Test + public void testSetUntypedStats() { + assertTrue(is.getUntypedStats("test").isEmpty()); + is.setUntypedStats("test", Map.of(Statistic.ARMOR_CLEANED, 30)); + assertEquals(30, is.getUntypedStats("test").get(Statistic.ARMOR_CLEANED).intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getBlockStats(java.lang.String)}. + */ + @Test + public void testGetBlockStats() { + assertTrue(is.getBlockStats("test").isEmpty()); + is.setBlockStats("test", Map.of(Statistic.MINE_BLOCK, Map.of(Material.STONE, 3000))); + assertEquals(3000, is.getBlockStats("test").get(Statistic.MINE_BLOCK).get(Material.STONE).intValue()); + + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getItemStats(java.lang.String)}. + */ + @Test + public void testGetItemStats() { + assertTrue(is.getItemStats("test").isEmpty()); + is.setItemStats("test", Map.of(Statistic.MINE_BLOCK, Map.of(Material.STONE, 3000))); + assertEquals(3000, is.getItemStats("test").get(Statistic.MINE_BLOCK).get(Material.STONE).intValue()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.dataobjects.InventoryStorage#getEntityStats(java.lang.String)}. + */ + @Test + public void testGetEntityStats() { + assertTrue(is.getEntityStats("test").isEmpty()); + is.setEntityStats("test", Map.of(Statistic.MINE_BLOCK, Map.of(EntityType.BLAZE, 3000))); + assertEquals(3000, is.getEntityStats("test").get(Statistic.MINE_BLOCK).get(EntityType.BLAZE).intValue()); + + } + +} diff --git a/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java b/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java new file mode 100644 index 0000000..04ff43b --- /dev/null +++ b/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java @@ -0,0 +1,154 @@ +package com.wasteofplastic.invswitcher.listeners; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Set; + +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.wasteofplastic.invswitcher.InvSwitcher; +import com.wasteofplastic.invswitcher.Store; + +import world.bentobox.bentobox.util.Util; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(Util.class) +public class PlayerListenerTest { + + @Mock + private InvSwitcher addon; + private PlayerListener pl; + @Mock + private Store store; + @Mock + private Player player; + @Mock + private World world; + @Mock + private World notWorld; + + /** + */ + @Before + public void setUp() { + // Util + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.sameWorld(world, world)).thenReturn(true); + // Player + when(player.getWorld()).thenReturn(world); + // Addon + when(addon.getStore()).thenReturn(store); + when(addon.getWorlds()).thenReturn(Set.of(world)); + pl = new PlayerListener(addon); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#PlayerListener(com.wasteofplastic.invswitcher.InvSwitcher)}. + */ + @Test + public void testPlayerListener() { + assertNotNull(pl); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onWorldEnter(org.bukkit.event.player.PlayerChangedWorldEvent)}. + */ + @Test + public void testOnWorldEnterSameWorld() { + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(player, world); + pl.onWorldEnter(event); + verify(store, never()).storeInventory(any(), any()); + verify(store, never()).getInventory(any(), any()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onWorldEnter(org.bukkit.event.player.PlayerChangedWorldEvent)}. + */ + @Test + public void testOnWorldEnterDifferentWorld() { + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(player, notWorld); + pl.onWorldEnter(event); + verify(store).storeInventory(any(), any()); + verify(store).getInventory(any(), any()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}. + */ + @Test + public void testOnPlayerJoin() { + PlayerJoinEvent event = new PlayerJoinEvent(player, ""); + pl.onPlayerJoin(event); + // No storage yet + verify(store, never()).getInventory(any(), any()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}. + */ + @Test + public void testOnPlayerJoinNonHandledWorld() { + when(player.getWorld()).thenReturn(notWorld); + PlayerJoinEvent event = new PlayerJoinEvent(player, ""); + pl.onPlayerJoin(event); + // No storage yet + verify(store, never()).getInventory(any(), any()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}. + */ + @Test + public void testOnPlayerJoinWithStorage() { + testOnWorldEnterDifferentWorld(); + when(player.getWorld()).thenReturn(notWorld); + PlayerJoinEvent event = new PlayerJoinEvent(player, ""); + pl.onPlayerJoin(event); + // No storage yet + verify(store).getInventory(any(), any()); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. + */ + @Test + public void testOnPlayerQuit() { + PlayerQuitEvent event = new PlayerQuitEvent(player, ""); + pl.onPlayerQuit(event); + verify(store).storeAndSave(player, world); + verify(store).removeFromCache(player); + } + + /** + * Test method for {@link com.wasteofplastic.invswitcher.listeners.PlayerListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. + */ + @Test + public void testOnPlayerQuitNotCoveredWorld() { + when(player.getWorld()).thenReturn(notWorld); + PlayerQuitEvent event = new PlayerQuitEvent(player, ""); + pl.onPlayerQuit(event); + verify(store, never()).storeAndSave(player, world); + verify(store).removeFromCache(player); + } + +}