diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3951cba --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,84 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Build & test + +Maven project, Java 21. Default goal is `clean package`. + +- Build the addon jar: `mvn clean package` (output in `target/`, named `StrangerRealms-${build.version}-SNAPSHOT-LOCAL.jar` locally) +- Run all tests: `mvn test` +- Run a single test class: `mvn test -Dtest=StrangerRealmsTest` +- Run a single test method: `mvn test -Dtest=StrangerRealmsTest#methodName` +- Skip tests during a build: `mvn package -DskipTests` + +Surefire is preconfigured with the `--add-opens` flags required by MockBukkit on JDK 21 — don't run tests outside Maven without replicating them. JaCoCo runs on the `test` phase and writes an XML report to `target/site/jacoco/`. + +Versioning is driven by Maven properties: `build.version` (in `pom.xml`) sets the release version, and the `master` / `ci` profiles flip `-SNAPSHOT` and `-bNNN` build numbers automatically from Jenkins env vars. Bump `build.version` in `pom.xml` to cut a new release. CI runs on Jenkins at codemc.org (see `pom.xml` ``) and on GitHub Actions (`.github/workflows/build.yml`). + +## Architecture + +StrangerRealms targets Paper **1.21.11** / BentoBox **3.10.0-SNAPSHOT**. The `mock-bukkit` snapshot tracks the latest Paper API, so bumping Paper here when MockBukkit moves is part of routine maintenance. + +StrangerRealms is a **BentoBox GameModeAddon** — it does not run as a standalone Bukkit/Paper plugin. The runtime entry point Paper sees is `StrangerRealmsPladdon` (a `Pladdon`), which constructs and returns the real addon, `StrangerRealms`. `plugin.yml` points Paper at the Pladdon; `addon.yml` points BentoBox at `StrangerRealms`. When changing entry points or lifecycle, both files matter. + +### Addon lifecycle (StrangerRealms.java) + +BentoBox calls these in order — keep work in the right phase: + +1. `onLoad()` — load `Settings` from `config.yml`, construct the `NetherChunkMaker` (it's needed during world creation), and register player/admin command trees (`ClaimCommand`, `UnclaimCommand`, `SpawnCommand`, `WorldBorderCommand`). +2. `createWorlds()` — creates the overworld, nether (Upside Down), and end via `WorldCreator`. The nether uses the custom `NetherChunks` ChunkGenerator + `NetherBiomeProvider`. If `Bukkit.getWorld(worldName + "_nether")` is missing at this point the chunks database is cleared — i.e., deleting the nether world folder forces full regeneration. +3. `onEnable()` — registers listeners (`PlayerListener`, `NetherChunkMaker`, `TeamListener`, `NetherRedstoneListener`), registers the Warped Compass recipe, and ensures a spawn `Island` exists. +4. `allLoaded()` — persists settings. + +`Settings` implements BentoBox's `WorldSettings`, so it doubles as the world configuration object returned from `getWorldSettings()`. It is serialized via `@ConfigEntry` annotations and stored at `addons/StrangerRealms/config.yml`. Adding a new option means adding a field + annotations here, not editing `config.yml` directly (the file is regenerated from the class). + +### Domain vocabulary + +In user-facing strings and commands the unit of ownership is a **claim**, but in code (and in BentoBox APIs) it is an **`Island`**. They are the same thing — `ClaimCommand` reuses BentoBox's island-create flow and even pulls locale keys from the core "island" namespace. Don't try to rename `Island` to `Claim` in code; treat them as synonyms. + +### Upside Down generation (generator/) + +The nether is a darkened, distressed mirror of the Overworld, generated lazily: + +- `NetherChunks` (ChunkGenerator) lays down the base terrain — a sculk-laced deep-dark floor below `NETHER_FLOOR`. Above that, the chunk is mostly air. +- `NetherBiomeProvider` assigns biomes; `NetherChunkMaker.BIOME_MAPPING` maps overworld biomes → crimson/warped/basalt variants. +- `NetherChunkMaker` (Listener) is the interesting piece: on `ChunkLoadEvent` in the nether world, it copies the corresponding overworld chunk's blocks into the nether chunk (with attrition / corruption controlled by `Settings.attrition`). The set of chunks it has already processed is persisted via `NetherChunksMade` (a BentoBox `DataObject` table named `StrangerChunks`) so generation only happens once per chunk. +- The **Warped Compass** (recipe registered in `StrangerRealms#registerWarpedCompassRecipe`) is consumed during nether portal travel to force re-generation of surrounding chunks — that is, to clear them from `NetherChunksMade` so they get rebuilt from the current overworld state. +- `NetherRedstoneListener` is the "Glimmer": with probability `Settings.redstoneChance`, button/lever interactions in the Upside Down replay at the same coordinates in the overworld. + +### Border system (border/) + +StrangerRealms ships its own world-border implementation and **conflicts with BentoBox's `Border` addon** — `onEnable()` warns if `Border` is loaded. There are two strategies behind the `BorderShower` interface: + +- `ShowBarrier` — custom client-side barrier-block visualisation. +- `ShowWorldBorder` — uses the vanilla world-border packet. + +`PerPlayerBorderProxy` is the entry point used by the rest of the addon; it currently fans calls out to *both* strategies (so each player sees both). Per-player border *type* selection (`BorderType` enum) is the intended extension point if you need to vary by player. + +The world border size is dynamic: `StrangerRealms#getBorderSize()` returns `barrierIncreaseBlocks × onlinePlayers` unless `manualBorderSize` is set. Shrinks are animated gradually via a Bukkit scheduled task at `barrierReductionSpeed` seconds per block — there is at most one such task; calling `getBorderSize()` again replaces it. + +### Resources packaged into the jar (pom.xml ``) + +- `src/main/resources/config.yml`, `addon.yml`, `plugin.yml` — filtered (Maven replaces `${...}` placeholders). +- `src/main/resources/locales/*.yml` → `./locales/` — **not filtered**. ~22 translations live here. +- `src/main/resources/blueprints/*.{blu,json}` → `./blueprints/` — BentoBox blueprint bundle for new claim layouts. +- `src/main/resources/structures/*.nbt` → `./structures/` — directory may not exist yet; the resource entry is preconfigured. + +## Testing patterns + +Tests use JUnit 5 + Mockito + MockBukkit. Two reusable base classes live in `src/test/java/world/bentobox/stranger/`: + +- `CommonTestSetup` — sets up `MockBukkit.mock()`, a static `Bukkit` mock, a mocked `BentoBox` plugin (injected via `WhiteBox` reflection into `BentoBox.instance`), and a mocked `IslandsManager` / `IslandWorldManager` with one default island. Extend this for most listener/command tests. +- `RanksManagerTestSetup` — adds rank-manager setup on top of `CommonTestSetup`. +- `WhiteBox` — utility for setting private static fields (e.g., the BentoBox singleton). +- `TestWorldSettings` — minimal `WorldSettings` returned from `iwm.getWorldSettings()`. + +Always call `super.setUp()` / `super.tearDown()` from subclasses — the base class is responsible for closing the static `Bukkit` mock and calling `MockBukkit.unmock()`, and forgetting either causes test interference and leaked database directories. + +`StrangerRealmsTest` exercises full addon loading; it builds a temporary `addon.jar` from `src/main/resources/config.yml` and feeds it through BentoBox's addon manager. Use it as the reference pattern when you need to test addon-level wiring rather than a single class. + +## Companion addons & integration notes + +- **Do not** install BentoBox's `Border` addon alongside this — they fight. `InvSwitcher` is recommended (warned about on enable if missing). Real users typically also run `Warps`. +- Spigot NMS is a required repository (``) — it's used for world regeneration. Don't remove it from `pom.xml`. diff --git a/pom.xml b/pom.xml index 9bf4650..16016cd 100644 --- a/pom.xml +++ b/pom.xml @@ -52,16 +52,18 @@ UTF-8 21 - 2.0.9 + 5.10.2 + 5.11.0 + v1.21-SNAPSHOT - 1.21.10-R0.1-SNAPSHOT + 1.21.11-R0.1-SNAPSHOT 3.10.0-SNAPSHOT ${build.version}-SNAPSHOT -LOCAL - 1.0.3 + 1.0.4 bentobox-world @@ -108,6 +110,10 @@ + + jitpack.io + https://jitpack.io + papermc https://repo.papermc.io/repository/maven-public/ @@ -136,32 +142,46 @@ - + - io.papermc.paper - paper-api - ${paper.version} - provided - - + com.github.MockBukkit + MockBukkit + ${mock-bukkit.version} + test + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.mockito + mockito-junit-jupiter + 5.11.0 + test + org.mockito mockito-core - 3.11.1 - test - - - org.powermock - powermock-module-junit4 - ${powermock.version} + ${mockito.version} test + - org.powermock - powermock-api-mockito2 - ${powermock.version} - test + io.papermc.paper + paper-api + ${paper.version} + provided + world.bentobox bentobox @@ -246,7 +266,6 @@ - ${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 diff --git a/src/main/java/world/bentobox/stranger/StrangerRealms.java b/src/main/java/world/bentobox/stranger/StrangerRealms.java index 5b1ccd2..118edca 100644 --- a/src/main/java/world/bentobox/stranger/StrangerRealms.java +++ b/src/main/java/world/bentobox/stranger/StrangerRealms.java @@ -133,7 +133,7 @@ private boolean loadSettings() { public void onEnable() { // Check for recommended addons if (this.getPlugin().getAddonsManager().getAddonByName("Border").isPresent()) { - this.logWarning("StrangerRealms has its own Border, so do not use Border in the Crowdbound world."); + this.logWarning("StrangerRealms has its own Border, so do not use Border addon."); } if (this.getPlugin().getAddonsManager().getAddonByName("InvSwitcher").isEmpty()) { this.logWarning("StrangerRealms recommends the InvSwitcher addon."); @@ -164,6 +164,7 @@ public void onEnable() { @Override public void onDisable() { + // Nothing to do } @Override @@ -290,7 +291,7 @@ public double getBorderSize() { Math.max(getSettings().getBarrierIncreaseBlocks(), (this.getSettings().getBarrierIncreaseBlocks() * Bukkit.getServer().getOnlinePlayers().size())); if (newBorderSize < borderSize) { // End any current task to replace it - task.cancel(); + cancelBorderTask(); // Trigger gradual reduction of border task = Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { if (borderSize > newBorderSize) { diff --git a/src/test/java/world/bentobox/stranger/CommonTestSetup.java b/src/test/java/world/bentobox/stranger/CommonTestSetup.java new file mode 100644 index 0000000..76597a8 --- /dev/null +++ b/src/test/java/world/bentobox/stranger/CommonTestSetup.java @@ -0,0 +1,341 @@ +package world.bentobox.stranger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Player.Spigot; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.PluginManager; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; + +import com.google.common.collect.ImmutableSet; + +import net.md_5.bungee.api.chat.TextComponent; +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.configuration.WorldSettings; +import world.bentobox.bentobox.api.user.Notifier; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.database.objects.Players; +import world.bentobox.bentobox.managers.BlueprintsManager; +import world.bentobox.bentobox.managers.FlagsManager; +import world.bentobox.bentobox.managers.HooksManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.LocalesManager; +import world.bentobox.bentobox.managers.PlaceholdersManager; +import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.bentobox.util.Util; + +/** + * Common items for testing. Don't forget to use super.setUp()! + *

+ * Sets up BentoBox plugin, pluginManager and ItemFactory. + * Location, world, playersManager and player. + * IWM, Addon and WorldSettings. IslandManager with one + * island with protection and nothing allowed by default. + * Owner of island is player with same UUID. + * Locales, placeholders. + * @author tastybento + * + */ +public abstract class CommonTestSetup { + + protected UUID uuid = UUID.randomUUID(); + + @Mock + protected Player mockPlayer; + @Mock + protected PluginManager pim; + @Mock + protected ItemFactory itemFactory; + @Mock + protected Location location; + @Mock + protected World world; + @Mock + protected IslandWorldManager iwm; + @Mock + protected IslandsManager im; + @Mock + protected Island island; + @Mock + protected BentoBox plugin; + @Mock + protected PlayerInventory inv; + @Mock + protected Notifier notifier; + @Mock + protected FlagsManager fm; + @Mock + protected Spigot spigot; + @Mock + protected HooksManager hooksManager; + @Mock + protected BlueprintsManager bm; + + protected ServerMock server; + + protected MockedStatic mockedBukkit; + protected MockedStatic mockedUtil; + + protected AutoCloseable closeable; + + @Mock + protected BukkitScheduler sch; + @Mock + protected LocalesManager lm; + + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + // Processes the @Mock annotations and initializes the field + closeable = MockitoAnnotations.openMocks(this); + server = MockBukkit.mock(); + // Bukkit + // Set up plugin + WhiteBox.setInternalState(BentoBox.class, "instance", plugin); + + // Register the static mock + mockedBukkit = Mockito.mockStatic(Bukkit.class, Mockito.RETURNS_DEEP_STUBS); + mockedBukkit.when(Bukkit::getMinecraftVersion).thenReturn("1.21.10"); + mockedBukkit.when(Bukkit::getBukkitVersion).thenReturn(""); + mockedBukkit.when(Bukkit::getPluginManager).thenReturn(pim); + mockedBukkit.when(Bukkit::getItemFactory).thenReturn(itemFactory); + mockedBukkit.when(Bukkit::getServer).thenReturn(server); + // Location + when(location.getWorld()).thenReturn(world); + when(location.getBlockX()).thenReturn(0); + when(location.getBlockY()).thenReturn(0); + when(location.getBlockZ()).thenReturn(0); + when(location.toVector()).thenReturn(new Vector(0,0,0)); + when(location.clone()).thenReturn(location); // Paper + + // Players Manager and meta data + PlayersManager pm = mock(PlayersManager.class); + when(plugin.getPlayers()).thenReturn(pm); + Players players = mock(Players.class); + when(players.getMetaData()).thenReturn(Optional.empty()); + when(pm.getPlayer(any(UUID.class))).thenReturn(players); + + // Player + when(mockPlayer.getUniqueId()).thenReturn(uuid); + when(mockPlayer.getLocation()).thenReturn(location); + when(mockPlayer.getWorld()).thenReturn(world); + when(mockPlayer.getName()).thenReturn("tastybento"); + when(mockPlayer.getInventory()).thenReturn(inv); + when(mockPlayer.spigot()).thenReturn(spigot); + when(mockPlayer.getType()).thenReturn(EntityType.PLAYER); + when(mockPlayer.getWorld()).thenReturn(world); + + User.setPlugin(plugin); + User.clearUsers(); + User.getInstance(mockPlayer); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.inWorld(any(Location.class))).thenReturn(true); + when(iwm.inWorld(any(World.class))).thenReturn(true); + when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); + // Addon + when(iwm.getAddon(any())).thenReturn(Optional.empty()); + + // World Settings + WorldSettings worldSet = new TestWorldSettings(); + when(iwm.getWorldSettings(any())).thenReturn(worldSet); + + // Island Manager + when(plugin.getIslands()).thenReturn(im); + Optional optionalIsland = Optional.of(island); + when(im.getProtectedIslandAt(any())).thenReturn(optionalIsland); + + // Island - nothing is allowed by default + when(island.isAllowed(any())).thenReturn(false); + when(island.isAllowed(any(User.class), any())).thenReturn(false); + when(island.getOwner()).thenReturn(uuid); + when(island.getMemberSet()).thenReturn(ImmutableSet.of(uuid)); + + // Enable reporting from Flags class + MetadataValue mdv = new FixedMetadataValue(plugin, "_why_debug"); + when(mockPlayer.getMetadata(anyString())).thenReturn(Collections.singletonList(mdv)); + + // Locales & Placeholders + when(lm.get(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + PlaceholdersManager phm = mock(PlaceholdersManager.class); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(plugin.getLocalesManager()).thenReturn(lm); + // Notifier + when(plugin.getNotifier()).thenReturn(notifier); + + // Fake players + //Settings settings = new Settings(); + //when(plugin.getSettings()).thenReturn(settings); + + //Util + mockedUtil = Mockito.mockStatic(Util.class, Mockito.CALLS_REAL_METHODS); + mockedUtil.when(() -> Util.getWorld(any())).thenReturn(mock(World.class)); + Util.setPlugin(plugin); + + // Util + mockedUtil.when(() -> Util.findFirstMatchingEnum(any(), any())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + //mockedUtil.when(() -> translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + + // Server & Scheduler + mockedBukkit.when(() -> Bukkit.getScheduler()).thenReturn(sch); + + // Hooks + when(hooksManager.getHook(anyString())).thenReturn(Optional.empty()); + when(plugin.getHooks()).thenReturn(hooksManager); + + // Blueprints Manager + when(plugin.getBlueprintsManager()).thenReturn(bm); + + // Namespace + when(plugin.namespace()).thenReturn("bentobox"); + + + // Tags + /* + for (Material m : Material.values()) { + if (m.name().contains("_SIGN")) { + when(Tag.ALL_SIGNS.isTagged(m)).thenReturn(true); + when(Tag.SIGNS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_WALL_SIGN")) { + when(Tag.WALL_SIGNS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_TRAPDOOR")) { + when(Tag.TRAPDOORS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("FENCE")) { + when(Tag.FENCES.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_DOOR")) { + when(Tag.DOORS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_BOAT") || m.name().contains("_RAFT")) { + when(Tag.ITEMS_BOATS.isTagged(m)).thenReturn(true); + } + + }*/ + } + + /** + * @throws Exception + */ + @AfterEach + public void tearDown() throws Exception { + // IMPORTANT: Explicitly close the mock to prevent leakage + mockedBukkit.closeOnDemand(); + mockedUtil.closeOnDemand(); + closeable.close(); + MockBukkit.unmock(); + User.clearUsers(); + Mockito.framework().clearInlineMocks(); + deleteAll(new File("database")); + deleteAll(new File("database_backup")); + } + + protected static void deleteAll(File file) throws IOException { + if (file.exists()) { + if (file.isDirectory()) { + Files.walk(file.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } else { + file.delete(); + } + } + + } + + /** + * Check that spigot sent the message + * @param message - message to check + */ + public void checkSpigotMessage(String expectedMessage) { + checkSpigotMessage(expectedMessage, 1); + } + + @SuppressWarnings("deprecation") + public void checkSpigotMessage(String expectedMessage, int expectedOccurrences) { + // Capture the argument passed to spigot().sendMessage(...) if messages are sent + ArgumentCaptor captor = ArgumentCaptor.forClass(TextComponent.class); + + // Verify that sendMessage() was called at least 0 times (capture any sent messages) + verify(spigot, atLeast(0)).sendMessage(captor.capture()); + + // Get all captured TextComponents + List capturedMessages = captor.getAllValues(); + + // Count the number of occurrences of the expectedMessage in the captured messages + long actualOccurrences = capturedMessages.stream().map(component -> component.toLegacyText()) // Convert each TextComponent to plain text + .filter(messageText -> messageText.contains(expectedMessage)) // Check if the message contains the expected text + .count(); // Count how many times the expected message appears + + // Assert that the number of occurrences matches the expectedOccurrences + assertEquals(expectedOccurrences, + actualOccurrences, "Expected message occurrence mismatch: " + expectedMessage); + } + + /** + * Get the explode event + * @param entity + * @param l + * @param list + * @return + */ + public EntityExplodeEvent getExplodeEvent(Entity entity, Location l, List list) { + //return new EntityExplodeEvent(entity, l, list, 0, null); + return new EntityExplodeEvent(entity, l, list, 0, null); + } + + public PlayerDeathEvent getPlayerDeathEvent(Player player, List drops, int droppedExp, int newExp, + int newTotalExp, int newLevel, @Nullable String deathMessage) { + //Technically this null is not allowed, but it works right now + return new PlayerDeathEvent(player, null, drops, droppedExp, newExp, + newTotalExp, newLevel, deathMessage); + } + +} diff --git a/src/test/java/world/bentobox/stranger/RanksManagerTestSetup.java b/src/test/java/world/bentobox/stranger/RanksManagerTestSetup.java new file mode 100644 index 0000000..db2f510 --- /dev/null +++ b/src/test/java/world/bentobox/stranger/RanksManagerTestSetup.java @@ -0,0 +1,140 @@ +package world.bentobox.stranger; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.DatabaseSetup; +import world.bentobox.bentobox.database.objects.Ranks; +import world.bentobox.bentobox.database.objects.TeamInvite; +import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.stranger.database.NetherChunksMade; + +/** + * @author tastybento + * + */ +public abstract class RanksManagerTestSetup extends CommonTestSetup { + + // Constants that define the hard coded rank values + public static final String ADMIN_RANK_REF = "ranks.admin"; + public static final String MOD_RANK_REF = "ranks.mod"; + public static final String OWNER_RANK_REF = "ranks.owner"; + public static final String SUB_OWNER_RANK_REF = "ranks.sub-owner"; + public static final String MEMBER_RANK_REF = "ranks.member"; + public static final String TRUSTED_RANK_REF = "ranks.trusted"; + public static final String COOP_RANK_REF = "ranks.coop"; + public static final String VISITOR_RANK_REF = "ranks.visitor"; + public static final String BANNED_RANK_REF = "ranks.banned"; + public static final int ADMIN_RANK = 10000; + public static final int MOD_RANK = 5000; + public static final int OWNER_RANK = 1000; + public static final int SUB_OWNER_RANK = 900; + public static final int MEMBER_RANK = 500; + public static final int TRUSTED_RANK = 400; + public static final int COOP_RANK = 200; + public static final int VISITOR_RANK = 0; + public static final int BANNED_RANK = -1; + + // The store of ranks + public static final Map DEFAULT_RANKS = Map.of(ADMIN_RANK_REF, ADMIN_RANK, MOD_RANK_REF, MOD_RANK, + OWNER_RANK_REF, OWNER_RANK, SUB_OWNER_RANK_REF, SUB_OWNER_RANK, MEMBER_RANK_REF, MEMBER_RANK, + TRUSTED_RANK_REF, TRUSTED_RANK, COOP_RANK_REF, COOP_RANK, VISITOR_RANK_REF, VISITOR_RANK, BANNED_RANK_REF, + BANNED_RANK); + + @Mock + public RanksManager rm; + protected AbstractDatabaseHandler ranksHandler; + private MockedStatic mockedDatabaseSetup; + + protected Object savedObject; + protected MockedStatic mockedRanksManager; + private AbstractDatabaseHandler netherChunksMadeHandler; + + @SuppressWarnings("unchecked") + @BeforeEach + public void setUp() throws Exception { + super.setUp(); + // Clear any lingering database + deleteAll(new File("database")); + deleteAll(new File("database_backup")); + + // This has to be done beforeClass otherwise the tests will interfere with each other + ranksHandler = (AbstractDatabaseHandler)mock(AbstractDatabaseHandler.class); + netherChunksMadeHandler = (AbstractDatabaseHandler)mock(AbstractDatabaseHandler.class); + // Database + mockedDatabaseSetup = Mockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + mockedDatabaseSetup.when(() -> DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(eq(Ranks.class))).thenReturn(ranksHandler); + when(ranksHandler.saveObject(any())).thenReturn(CompletableFuture.completedFuture(true)); + when(dbSetup.getHandler(eq(NetherChunksMade.class))).thenReturn(netherChunksMadeHandler); + when(netherChunksMadeHandler.saveObject(any())).thenReturn(CompletableFuture.completedFuture(true)); + + // Capture the parameter passed to saveObject() and store it in savedObject + doAnswer(invocation -> { + savedObject = invocation.getArgument(0); + return CompletableFuture.completedFuture(true); + }).when(ranksHandler).saveObject(any()); + doAnswer(invocation -> { + savedObject = invocation.getArgument(0); + return CompletableFuture.completedFuture(true); + }).when(netherChunksMadeHandler).saveObject(any()); + + // Now when loadObject() is called, return the savedObject + when(ranksHandler.loadObject(any())).thenAnswer(invocation -> savedObject); + when(netherChunksMadeHandler.loadObject(any())).thenAnswer(invocation -> savedObject); + + // Delete object + doAnswer(invocation -> { + savedObject = null; + return null; + }).when(ranksHandler).deleteObject(any()); + doAnswer(invocation -> { + savedObject = null; + return null; + }).when(netherChunksMadeHandler).deleteObject(any()); + + doAnswer(invocation -> { + savedObject = null; + return null; + }).when(ranksHandler).deleteID(anyString()); + doAnswer(invocation -> { + savedObject = null; + return null; + }).when(netherChunksMadeHandler).deleteID(anyString()); + + // RanksManager + mockedRanksManager = Mockito.mockStatic(RanksManager.class, Mockito.RETURNS_MOCKS); + mockedRanksManager.when(() -> RanksManager.getInstance()).thenReturn(rm); + when(rm.getRanks()).thenReturn(DEFAULT_RANKS); + when(rm.getRank(anyInt())).thenReturn(""); + // Clear savedObject + savedObject = null; + } + + @AfterEach + public void tearDown() throws Exception { + super.tearDown(); + deleteAll(new File("database")); + deleteAll(new File("database_backup")); + ranksHandler.close(); + netherChunksMadeHandler.close(); + } + +} diff --git a/src/test/java/world/bentobox/stranger/SettingsTest.java b/src/test/java/world/bentobox/stranger/SettingsTest.java new file mode 100644 index 0000000..508fcbc --- /dev/null +++ b/src/test/java/world/bentobox/stranger/SettingsTest.java @@ -0,0 +1,1353 @@ +package world.bentobox.stranger; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Difficulty; +import org.bukkit.GameMode; +import org.bukkit.entity.EntityType; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import world.bentobox.stranger.border.BorderType; + +class SettingsTest { + + private Settings s; + + /** + * @throws java.lang.Exception + */ + @BeforeEach + void setUp() throws Exception { + s = new Settings(); + } + + /** + * @throws java.lang.Exception + */ + @AfterEach + void tearDown() throws Exception { + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getFriendlyName()}. + */ + @Test + void testGetFriendlyName() { + assertEquals("StrangerRealms", s.getFriendlyName()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getWorldName()}. + */ + @Test + void testGetWorldName() { + assertEquals("stranger-world", s.getWorldName()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDifficulty()}. + */ + @Test + void testGetDifficulty() { + assertEquals(Difficulty.NORMAL, s.getDifficulty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandDistance()}. + */ + @Test + void testGetIslandDistance() { + assertEquals(32, s.getIslandDistance()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandProtectionRange()}. + */ + @Test + void testGetIslandProtectionRange() { + assertEquals(32, s.getIslandProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandStartX()}. + */ + @Test + void testGetIslandStartX() { + assertEquals(0, s.getIslandStartX()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandStartZ()}. + */ + @Test + void testGetIslandStartZ() { + assertEquals(0, s.getIslandStartZ()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandXOffset()}. + */ + @Test + void testGetIslandXOffset() { + assertEquals(0, s.getIslandXOffset()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandZOffset()}. + */ + @Test + void testGetIslandZOffset() { + assertEquals(0, s.getIslandZOffset()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIslandHeight()}. + */ + @Test + void testGetIslandHeight() { + assertEquals(-64, s.getIslandHeight()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isUseOwnGenerator()}. + */ + @Test + void testIsUseOwnGenerator() { + assertFalse(s.isUseOwnGenerator()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSeaHeight()}. + */ + @Test + void testGetSeaHeight() { + assertEquals(0, s.getSeaHeight()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMaxIslands()}. + */ + @Test + void testGetMaxIslands() { + assertEquals(-1, s.getMaxIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDefaultGameMode()}. + */ + @Test + void testGetDefaultGameMode() { + assertEquals(GameMode.SURVIVAL, s.getDefaultGameMode()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isNetherGenerate()}. + */ + @Test + void testIsNetherGenerate() { + assertTrue(s.isNetherGenerate()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isNetherIslands()}. + */ + @Test + void testIsNetherIslands() { + assertTrue(s.isNetherIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getNetherSpawnRadius()}. + */ + @Test + void testGetNetherSpawnRadius() { + assertEquals(32, s.getNetherSpawnRadius()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isEndGenerate()}. + */ + @Test + void testIsEndGenerate() { + assertTrue(s.isEndGenerate()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isEndIslands()}. + */ + @Test + void testIsEndIslands() { + assertFalse(s.isEndIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isDragonSpawn()}. + */ + @Test + void testIsDragonSpawn() { + assertFalse(s.isDragonSpawn()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getRemoveMobsWhitelist()}. + */ + @Test + void testGetRemoveMobsWhitelist() { + assertTrue(s.getRemoveMobsWhitelist().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getWorldFlags()}. + */ + @Test + void testGetWorldFlags() { + assertTrue(s.getWorldFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDefaultIslandFlags()}. + */ + @Test + void testGetDefaultIslandFlags() { + assertTrue(s.getDefaultIslandFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDefaultIslandSettings()}. + */ + @Test + void testGetDefaultIslandSettings() { + assertTrue(s.getDefaultIslandSettings().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getHiddenFlags()}. + */ + @Test + void testGetHiddenFlags() { + assertTrue(s.getHiddenFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getVisitorBannedCommands()}. + */ + @Test + void testGetVisitorBannedCommands() { + assertTrue(s.getVisitorBannedCommands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getFallingBannedCommands()}. + */ + @Test + void testGetFallingBannedCommands() { + assertTrue(s.getFallingBannedCommands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMaxTeamSize()}. + */ + @Test + void testGetMaxTeamSize() { + assertEquals(4, s.getMaxTeamSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMaxHomes()}. + */ + @Test + void testGetMaxHomes() { + assertEquals(5, s.getMaxHomes()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getResetLimit()}. + */ + @Test + void testGetResetLimit() { + assertEquals(-1, s.getResetLimit()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isLeaversLoseReset()}. + */ + @Test + void testIsLeaversLoseReset() { + assertFalse(s.isLeaversLoseReset()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isKickedKeepInventory()}. + */ + @Test + void testIsKickedKeepInventory() { + assertTrue(s.isKickedKeepInventory()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isCreateIslandOnFirstLoginEnabled()}. + */ + @Test + void testIsCreateIslandOnFirstLoginEnabled() { + assertFalse(s.isCreateIslandOnFirstLoginEnabled()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getCreateIslandOnFirstLoginDelay()}. + */ + @Test + void testGetCreateIslandOnFirstLoginDelay() { + assertEquals(0, s.getCreateIslandOnFirstLoginDelay()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isCreateIslandOnFirstLoginAbortOnLogout()}. + */ + @Test + void testIsCreateIslandOnFirstLoginAbortOnLogout() { + assertTrue(s.isCreateIslandOnFirstLoginAbortOnLogout()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetMoney()}. + */ + @Test + void testIsOnJoinResetMoney() { + assertFalse(s.isOnJoinResetMoney()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetInventory()}. + */ + @Test + void testIsOnJoinResetInventory() { + assertFalse(s.isOnJoinResetInventory()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetEnderChest()}. + */ + @Test + void testIsOnJoinResetEnderChest() { + assertFalse(s.isOnJoinResetEnderChest()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetMoney()}. + */ + @Test + void testIsOnLeaveResetMoney() { + assertFalse(s.isOnLeaveResetMoney()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetInventory()}. + */ + @Test + void testIsOnLeaveResetInventory() { + assertFalse(s.isOnLeaveResetInventory()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetEnderChest()}. + */ + @Test + void testIsOnLeaveResetEnderChest() { + assertFalse(s.isOnLeaveResetEnderChest()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isDeathsCounted()}. + */ + @Test + void testIsDeathsCounted() { + assertFalse(s.isDeathsCounted()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isAllowSetHomeInNether()}. + */ + @Test + void testIsAllowSetHomeInNether() { + assertTrue(s.isAllowSetHomeInNether()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isAllowSetHomeInTheEnd()}. + */ + @Test + void testIsAllowSetHomeInTheEnd() { + assertTrue(s.isAllowSetHomeInTheEnd()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isRequireConfirmationToSetHomeInNether()}. + */ + @Test + void testIsRequireConfirmationToSetHomeInNether() { + assertTrue(s.isRequireConfirmationToSetHomeInNether()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isRequireConfirmationToSetHomeInTheEnd()}. + */ + @Test + void testIsRequireConfirmationToSetHomeInTheEnd() { + assertTrue(s.isRequireConfirmationToSetHomeInTheEnd()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDeathsMax()}. + */ + @Test + void testGetDeathsMax() { + assertEquals(0, s.getDeathsMax()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isTeamJoinDeathReset()}. + */ + @Test + void testIsTeamJoinDeathReset() { + assertFalse(s.isTeamJoinDeathReset()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getGeoLimitSettings()}. + */ + @Test + void testGetGeoLimitSettings() { + assertTrue(s.getGeoLimitSettings().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getIvSettings()}. + */ + @Test + void testGetIvSettings() { + assertTrue(s.getIvSettings().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getResetEpoch()}. + */ + @Test + void testGetResetEpoch() { + assertEquals(0L, s.getResetEpoch()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setFriendlyName(java.lang.String)}. + */ + @Test + void testSetFriendlyName() { + s.setFriendlyName("X"); + assertEquals("X", s.getFriendlyName()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setWorldName(java.lang.String)}. + */ + @Test + void testSetWorldName() { + s.setWorldName("world2"); + assertEquals("world2", s.getWorldName()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDifficulty(org.bukkit.Difficulty)}. + */ + @Test + void testSetDifficulty() { + s.setDifficulty(Difficulty.HARD); + assertEquals(Difficulty.HARD, s.getDifficulty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setIslandDistance(int)}. + */ + @Test + void testSetIslandDistance() { + s.setIslandDistance(10); + assertEquals(10, s.getIslandDistance()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setIslandProtectionRange(int)}. + */ + @Test + void testSetIslandProtectionRange() { + s.setIslandProtectionRange(15); + assertEquals(15, s.getIslandProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMaxIslands(int)}. + */ + @Test + void testSetMaxIslands() { + s.setMaxIslands(42); + assertEquals(42, s.getMaxIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setNetherGenerate(boolean)}. + */ + @Test + void testSetNetherGenerate() { + s.setNetherGenerate(false); + assertFalse(s.isNetherGenerate()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setEndGenerate(boolean)}. + */ + @Test + void testSetEndGenerate() { + s.setEndGenerate(false); + assertFalse(s.isEndGenerate()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setRemoveMobsWhitelist(java.util.Set)}. + */ + @Test + void testSetRemoveMobsWhitelist() { + Set set = new HashSet<>(); + set.add(EntityType.ZOMBIE); + s.setRemoveMobsWhitelist(set); + assertEquals(set, s.getRemoveMobsWhitelist()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setWorldFlags(java.util.Map)}. + */ + @Test + void testSetWorldFlags() { + Map m = new HashMap<>(); + m.put("flag", true); + s.setWorldFlags(m); + assertEquals(m, s.getWorldFlags()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDefaultIslandFlags(java.util.Map)}. + */ + @Test + void testSetDefaultIslandFlags() { + Map m = new HashMap<>(); + s.setDefaultIslandFlags(m); + assertEquals(m, s.getDefaultIslandFlags()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDefaultIslandSettings(java.util.Map)}. + */ + @Test + void testSetDefaultIslandSettings() { + Map m = new HashMap<>(); + s.setDefaultIslandSettings(m); + assertEquals(m, s.getDefaultIslandSettings()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setHiddenFlags(java.util.List)}. + */ + @Test + void testSetHiddenFlags() { + List l = Arrays.asList("a","b"); + s.setHiddenFlags(l); + assertEquals(l, s.getHiddenFlags()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setVisitorBannedCommands(java.util.List)}. + */ + @Test + void testSetVisitorBannedCommands() { + List l = Arrays.asList("cmd"); + s.setVisitorBannedCommands(l); + assertEquals(l, s.getVisitorBannedCommands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMaxTeamSize(int)}. + */ + @Test + void testSetMaxTeamSize() { + s.setMaxTeamSize(8); + assertEquals(8, s.getMaxTeamSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMaxHomes(int)}. + */ + @Test + void testSetMaxHomes() { + s.setMaxHomes(7); + assertEquals(7, s.getMaxHomes()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setIvSettings(java.util.List)}. + */ + @Test + void testSetIvSettings() { + List l = Arrays.asList("dmg"); + s.setIvSettings(l); + assertEquals(l, s.getIvSettings()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setAllowSetHomeInNether(boolean)}. + */ + @Test + void testSetAllowSetHomeInNether() { + s.setAllowSetHomeInNether(false); + assertFalse(s.isAllowSetHomeInNether()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setAllowSetHomeInTheEnd(boolean)}. + */ + @Test + void testSetAllowSetHomeInTheEnd() { + s.setAllowSetHomeInTheEnd(false); + assertFalse(s.isAllowSetHomeInTheEnd()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setRequireConfirmationToSetHomeInNether(boolean)}. + */ + @Test + void testSetRequireConfirmationToSetHomeInNether() { + s.setRequireConfirmationToSetHomeInNether(false); + assertFalse(s.isRequireConfirmationToSetHomeInNether()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setRequireConfirmationToSetHomeInTheEnd(boolean)}. + */ + @Test + void testSetRequireConfirmationToSetHomeInTheEnd() { + s.setRequireConfirmationToSetHomeInTheEnd(false); + assertFalse(s.isRequireConfirmationToSetHomeInTheEnd()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setResetEpoch(long)}. + */ + @Test + void testSetResetEpoch() { + s.setResetEpoch(12345L); + assertEquals(12345L, s.getResetEpoch()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getPermissionPrefix()}. + */ + @Test + void testGetPermissionPrefix() { + assertEquals("stranger", s.getPermissionPrefix()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isWaterUnsafe()}. + */ + @Test + void testIsWaterUnsafe() { + assertFalse(s.isWaterUnsafe()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getBanLimit()}. + */ + @Test + void testGetBanLimit() { + assertEquals(-1, s.getBanLimit()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setBanLimit(int)}. + */ + @Test + void testSetBanLimit() { + s.setBanLimit(10); + assertEquals(10, s.getBanLimit()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getPlayerCommandAliases()}. + */ + @Test + void testGetPlayerCommandAliases() { + assertEquals("st strange", s.getPlayerCommandAliases()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setPlayerCommandAliases(java.lang.String)}. + */ + @Test + void testSetPlayerCommandAliases() { + s.setPlayerCommandAliases("p1 p2"); + assertEquals("p1 p2", s.getPlayerCommandAliases()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getAdminCommandAliases()}. + */ + @Test + void testGetAdminCommandAliases() { + assertEquals("stranger", s.getAdminCommandAliases()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setAdminCommandAliases(java.lang.String)}. + */ + @Test + void testSetAdminCommandAliases() { + s.setAdminCommandAliases("adm"); + assertEquals("adm", s.getAdminCommandAliases()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isDeathsResetOnNewIsland()}. + */ + @Test + void testIsDeathsResetOnNewIsland() { + assertFalse(s.isDeathsResetOnNewIsland()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getOnJoinCommands()}. + */ + @Test + void testGetOnJoinCommands() { + assertNotNull(s.getOnJoinCommands()); + assertTrue(s.getOnJoinCommands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setOnJoinCommands(java.util.List)}. + */ + @Test + void testSetOnJoinCommands() { + List cmds = Arrays.asList("[SUDO] echo hi"); + s.setOnJoinCommands(cmds); + assertEquals(cmds, s.getOnJoinCommands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getOnLeaveCommands()}. + */ + @Test + void testGetOnLeaveCommands() { + assertNotNull(s.getOnLeaveCommands()); + assertTrue(s.getOnLeaveCommands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setOnLeaveCommands(java.util.List)}. + */ + @Test + void testSetOnLeaveCommands() { + List cmds = Arrays.asList("say bye"); + s.setOnLeaveCommands(cmds); + assertEquals(cmds, s.getOnLeaveCommands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getOnRespawnCommands()}. + */ + @Test + void testGetOnRespawnCommands() { + assertNotNull(s.getOnRespawnCommands()); + assertTrue(s.getOnRespawnCommands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setOnRespawnCommands(java.util.List)}. + */ + @Test + void testSetOnRespawnCommands() { + List cmds = Arrays.asList("tp [player] 0 64 0"); + s.setOnRespawnCommands(cmds); + assertEquals(cmds, s.getOnRespawnCommands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetHealth()}. + */ + @Test + void testIsOnJoinResetHealth() { + assertFalse(s.isOnJoinResetHealth()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetHunger()}. + */ + @Test + void testIsOnJoinResetHunger() { + assertFalse(s.isOnJoinResetHunger()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnJoinResetXP()}. + */ + @Test + void testIsOnJoinResetXP() { + assertFalse(s.isOnJoinResetXP()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetHealth()}. + */ + @Test + void testIsOnLeaveResetHealth() { + assertFalse(s.isOnLeaveResetHealth()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetHunger()}. + */ + @Test + void testIsOnLeaveResetHunger() { + assertFalse(s.isOnLeaveResetHunger()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isOnLeaveResetXP()}. + */ + @Test + void testIsOnLeaveResetXP() { + assertFalse(s.isOnLeaveResetXP()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isPasteMissingIslands()}. + */ + @Test + void testIsPasteMissingIslands() { + assertFalse(s.isPasteMissingIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isTeleportPlayerToIslandUponIslandCreation()}. + */ + @Test + void testIsTeleportPlayerToIslandUponIslandCreation() { + assertTrue(s.isTeleportPlayerToIslandUponIslandCreation()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSpawnLimitMonsters()}. + */ + @Test + void testGetSpawnLimitMonsters() { + assertEquals(-1, s.getSpawnLimitMonsters()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setSpawnLimitMonsters(int)}. + */ + @Test + void testSetSpawnLimitMonsters() { + s.setSpawnLimitMonsters(99); + assertEquals(99, s.getSpawnLimitMonsters()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSpawnLimitAnimals()}. + */ + @Test + void testGetSpawnLimitAnimals() { + assertEquals(-1, s.getSpawnLimitAnimals()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setSpawnLimitAnimals(int)}. + */ + @Test + void testSetSpawnLimitAnimals() { + s.setSpawnLimitAnimals(50); + assertEquals(50, s.getSpawnLimitAnimals()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSpawnLimitWaterAnimals()}. + */ + @Test + void testGetSpawnLimitWaterAnimals() { + assertEquals(-1, s.getSpawnLimitWaterAnimals()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setSpawnLimitWaterAnimals(int)}. + */ + @Test + void testSetSpawnLimitWaterAnimals() { + s.setSpawnLimitWaterAnimals(20); + assertEquals(20, s.getSpawnLimitWaterAnimals()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSpawnLimitAmbient()}. + */ + @Test + void testGetSpawnLimitAmbient() { + assertEquals(-1, s.getSpawnLimitAmbient()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setSpawnLimitAmbient(int)}. + */ + @Test + void testSetSpawnLimitAmbient() { + s.setSpawnLimitAmbient(5); + assertEquals(5, s.getSpawnLimitAmbient()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getTicksPerAnimalSpawns()}. + */ + @Test + void testGetTicksPerAnimalSpawns() { + assertEquals(-1, s.getTicksPerAnimalSpawns()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setTicksPerAnimalSpawns(int)}. + */ + @Test + void testSetTicksPerAnimalSpawns() { + s.setTicksPerAnimalSpawns(400); + assertEquals(400, s.getTicksPerAnimalSpawns()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getTicksPerMonsterSpawns()}. + */ + @Test + void testGetTicksPerMonsterSpawns() { + assertEquals(-1, s.getTicksPerMonsterSpawns()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setTicksPerMonsterSpawns(int)}. + */ + @Test + void testSetTicksPerMonsterSpawns() { + s.setTicksPerMonsterSpawns(300); + assertEquals(300, s.getTicksPerMonsterSpawns()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMaxCoopSize()}. + */ + @Test + void testGetMaxCoopSize() { + assertEquals(4, s.getMaxCoopSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMaxCoopSize(int)}. + */ + @Test + void testSetMaxCoopSize() { + s.setMaxCoopSize(6); + assertEquals(6, s.getMaxCoopSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMaxTrustSize()}. + */ + @Test + void testGetMaxTrustSize() { + assertEquals(4, s.getMaxTrustSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMaxTrustSize(int)}. + */ + @Test + void testSetMaxTrustSize() { + s.setMaxTrustSize(7); + assertEquals(7, s.getMaxTrustSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDefaultNewPlayerAction()}. + */ + @Test + void testGetDefaultNewPlayerAction() { + assertEquals("spawn", s.getDefaultNewPlayerAction()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDefaultNewPlayerAction(java.lang.String)}. + */ + @Test + void testSetDefaultNewPlayerAction() { + s.setDefaultNewPlayerAction("create"); + assertEquals("create", s.getDefaultNewPlayerAction()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getDefaultPlayerAction()}. + */ + @Test + void testGetDefaultPlayerAction() { + assertEquals("go", s.getDefaultPlayerAction()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDefaultPlayerAction(java.lang.String)}. + */ + @Test + void testSetDefaultPlayerAction() { + s.setDefaultPlayerAction("teleport"); + assertEquals("teleport", s.getDefaultPlayerAction()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMobLimitSettings()}. + */ + @Test + void testGetMobLimitSettings() { + assertTrue(s.getMobLimitSettings().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMobLimitSettings(java.util.List)}. + */ + @Test + void testSetMobLimitSettings() { + List l = Arrays.asList("ZOMBIE"); + s.setMobLimitSettings(l); + assertEquals(l, s.getMobLimitSettings()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSeed()}. + */ + @Test + void testGetSeed() { + assertEquals(602103456450L, s.getSeed()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setSeed(long)}. + */ + @Test + void testSetSeed() { + s.setSeed(9999L); + assertEquals(9999L, s.getSeed()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isCheckForBlocks()}. + */ + @Test + void testIsCheckForBlocks() { + assertFalse(s.isCheckForBlocks()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isMakeNetherPortals()}. + */ + @Test + void testIsMakeNetherPortals() { + assertTrue(s.isMakeNetherPortals()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSeedX()}. + */ + @Test + void testGetSeedX() { + assertEquals(0, s.getSeedX()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getSeedZ()}. + */ + @Test + void testGetSeedZ() { + assertEquals(0, s.getSeedZ()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getNetherSeedX()}. + */ + @Test + void testGetNetherSeedX() { + assertEquals(0, s.getNetherSeedX()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getNetherSeedZ()}. + */ + @Test + void testGetNetherSeedZ() { + assertEquals(0, s.getNetherSeedZ()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getEndSeedX()}. + */ + @Test + void testGetEndSeedX() { + assertEquals(0, s.getEndSeedX()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getEndSeedZ()}. + */ + @Test + void testGetEndSeedZ() { + assertEquals(0, s.getEndSeedZ()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getConcurrentIslands()}. + */ + @Test + void testGetConcurrentIslands() { + assertEquals(3, s.getConcurrentIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setConcurrentIslands(int)}. + */ + @Test + void testSetConcurrentIslands() { + s.setConcurrentIslands(6); + assertEquals(6, s.getConcurrentIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isDisallowTeamMemberIslands()}. + */ + @Test + void testIsDisallowTeamMemberIslands() { + assertTrue(s.isDisallowTeamMemberIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDisallowTeamMemberIslands(boolean)}. + */ + @Test + void testSetDisallowTeamMemberIslands() { + s.setDisallowTeamMemberIslands(false); + assertFalse(s.isDisallowTeamMemberIslands()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isAllowStructures()}. + */ + @Test + void testIsAllowStructures() { + assertTrue(s.isAllowStructures()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setAllowStructures(boolean)}. + */ + @Test + void testSetAllowStructures() { + s.setAllowStructures(false); + assertFalse(s.isAllowStructures()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getType()}. + */ + @Test + void testGetType() { + assertEquals(BorderType.VANILLA, s.getType()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isUseBarrierBlocks()}. + */ + @Test + void testIsUseBarrierBlocks() { + assertFalse(s.isUseBarrierBlocks()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isShowParticles()}. + */ + @Test + void testIsShowParticles() { + assertTrue(s.isShowParticles()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getBarrierReductionSpeed()}. + */ + @Test + void testGetBarrierReductionSpeed() { + assertEquals(10, s.getBarrierReductionSpeed()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setBarrierReductionSpeed(int)}. + */ + @Test + void testSetBarrierReductionSpeed() { + s.setBarrierReductionSpeed(5); + assertEquals(5, s.getBarrierReductionSpeed()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getBarrierIncreaseBlocks()}. + */ + @Test + void testGetBarrierIncreaseBlocks() { + assertEquals(320, s.getBarrierIncreaseBlocks()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setBarrierIncreaseBlocks(int)}. + */ + @Test + void testSetBarrierIncreaseBlocks() { + s.setBarrierIncreaseBlocks(100); + assertEquals(100, s.getBarrierIncreaseBlocks()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getMemberBonus()}. + */ + @Test + void testGetMemberBonus() { + assertEquals(32, s.getMemberBonus()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setMemberBonus(int)}. + */ + @Test + void testSetMemberBonus() { + s.setMemberBonus(10); + assertEquals(10, s.getMemberBonus()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isManualBorderSize()}. + */ + @Test + void testIsManualBorderSize() { + assertFalse(s.isManualBorderSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setManualBorderSize(boolean)}. + */ + @Test + void testSetManualBorderSize() { + s.setManualBorderSize(true); + assertTrue(s.isManualBorderSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isDisableWorldBorder()}. + */ + @Test + void testIsDisableWorldBorder() { + assertFalse(s.isDisableWorldBorder()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setDisableWorldBorder(boolean)}. + */ + @Test + void testSetDisableWorldBorder() { + s.setDisableWorldBorder(true); + assertTrue(s.isDisableWorldBorder()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#isUseUpsideDown()}. + */ + @Test + void testIsUseUpsideDown() { + assertTrue(s.isUseUpsideDown()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setUseUpsideDown(boolean)}. + */ + @Test + void testSetUseUpsideDown() { + s.setUseUpsideDown(false); + assertFalse(s.isUseUpsideDown()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getAttrition()}. + */ + @Test + void testGetAttrition() { + assertEquals(5, s.getAttrition()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setAttrition(int)}. + */ + @Test + void testSetAttrition() { + s.setAttrition(2); + assertEquals(2, s.getAttrition()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getChestFills()}. + */ + @Test + void testGetChestFills() { + assertEquals(3, s.getChestFills()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setChestFills(int)}. + */ + @Test + void testSetChestFills() { + s.setChestFills(6); + assertEquals(6, s.getChestFills()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#getRedstoneChance()}. + */ + @Test + void testGetRedstoneChance() { + assertEquals(100, s.getRedstoneChance()); + } + + /** + * Test method for {@link world.bentobox.stranger.Settings#setRedstoneChance(int)}. + */ + @Test + void testSetRedstoneChance() { + s.setRedstoneChance(50); + assertEquals(50, s.getRedstoneChance()); + s.setRedstoneChance(150); + assertEquals(100, s.getRedstoneChance()); // clamped to 100 + s.setRedstoneChance(-10); + assertEquals(0, s.getRedstoneChance()); // clamped to 0 + } + +} diff --git a/src/test/java/world/bentobox/stranger/StrangerRealmsTest.java b/src/test/java/world/bentobox/stranger/StrangerRealmsTest.java new file mode 100644 index 0000000..da10b9b --- /dev/null +++ b/src/test/java/world/bentobox/stranger/StrangerRealmsTest.java @@ -0,0 +1,258 @@ +package world.bentobox.stranger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.mock; +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.Optional; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import world.bentobox.bentobox.api.addons.AddonDescription; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.managers.AddonsManager; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.stranger.border.BorderType; +import world.bentobox.stranger.border.PerPlayerBorderProxy; +import world.bentobox.stranger.database.NetherChunksMade; + +class StrangerRealmsTest extends RanksManagerTestSetup { + private static File jFile; + private AbstractDatabaseHandler h; + private StrangerRealms addon; + @Mock + private AddonsManager am; + @Mock + private CommandsManager cm; + private Settings settings; + + @BeforeAll + public static void beforeClass() throws IOException { + deleteAll(new File("config.yml")); + deleteAll(new File("addon.jar")); + // 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 = 0; + JarEntry entry = new JarEntry(path.toString()); + tempJarOutputStream.putNextEntry(entry); + while((bytesRead = fis.read(buffer)) != -1) { + tempJarOutputStream.write(buffer, 0, bytesRead); + } + } + } + } + + /** + * @throws java.lang.Exception + */ + @SuppressWarnings("unchecked") + @Override + @BeforeEach + public void setUp() throws Exception { + super.setUp(); + // Flags Manager + when(plugin.getFlagsManager()).thenReturn(fm); + // Commands Manager + when(plugin.getCommandsManager()).thenReturn(cm); + + // Addon + addon = new StrangerRealms(); + File dataFolder = new File("addons/StrangerRealms"); + addon.setDataFolder(dataFolder); + addon.setFile(jFile); + AddonDescription desc = new AddonDescription.Builder("bentobox", "StrangerRealms", "1.3").description("test").authors("tastybento").build(); + addon.setDescription(desc); + + + when(plugin.getAddonsManager()).thenReturn(am); + when(am.getAddonByName("Border")).thenReturn(Optional.of(addon)); + when(am.getAddonByName("invSwitcher")).thenReturn(Optional.of(addon)); + + // Get started + addon.onLoad(); + addon.createWorlds(); + addon.onEnable(); + + } + + /** + * @throws java.lang.Exception + */ + @Override + @AfterEach + public void tearDown() throws Exception { + super.tearDown(); + } + + @AfterAll + public static void cleanUp() throws Exception { + deleteAll(new File("addon.jar")); + deleteAll(new File("addons")); + deleteAll(new File("config.yml")); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#onEnable()}. + */ + @Test + void testOnEnable() { + verify(plugin).logWarning("[StrangerRealms] StrangerRealms recommends the InvSwitcher addon."); + verify(plugin).logWarning( + "[StrangerRealms] StrangerRealms has its own Border, so do not use Border addon." + ); + verify(plugin).logError( + "[StrangerRealms] Could not make a spawn claim. You will have to set one manually in the world." + ); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#onReload()}. + */ + @Test + void testOnReload() { + addon.onReload(); + verify(plugin).log("[StrangerRealms] Reloaded settings"); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#isUsesNewChunkGeneration()}. + */ + @Test + void testIsUsesNewChunkGeneration() { + assertTrue(addon.isUsesNewChunkGeneration()); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#isFixIslandCenter()}. + */ + @Test + void testIsFixIslandCenter() { + assertFalse(addon.isFixIslandCenter()); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#isEnforceEqualRanges()}. + */ + @Test + void testIsEnforceEqualRanges() { + assertFalse(addon.isEnforceEqualRanges()); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getSettings()}. + */ + @Test + void testGetSettings() { + Settings settings = addon.getSettings(); + assertNotNull(settings); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getWorldSettings()}. + */ + @Test + void testGetWorldSettings() { + assertNotNull(addon.getWorldSettings()); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getDefaultWorldGenerator(java.lang.String, java.lang.String)}. + */ + @Test + void testGetDefaultWorldGeneratorStringString() { + assertNotNull(addon.getDefaultWorldGenerator("stranger-realms", "")); + + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getAvailableBorderTypesView()}. + */ + @Test + void testGetAvailableBorderTypesView() { + Set types = addon.getAvailableBorderTypesView(); + assertTrue(types.contains(BorderType.BARRIER)); + assertTrue(types.contains(BorderType.VANILLA)); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getBorderShower()}. + */ + @Test + void testGetBorderShower() { + assertTrue(addon.getBorderShower() instanceof PerPlayerBorderProxy); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getBorderSize()}. + */ + @Test + void testGetBorderSize() { + assertEquals(320D, addon.getBorderSize(), 0.1D); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#setBorderSize(int)}. + */ + @Test + void testSetBorderSize() { + assertEquals(320D, addon.getBorderSize()); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#createWarpedCompassItem()}. + */ + @Test + void testCreateWarpedCompassItem() { + ItemStack item = StrangerRealms.createWarpedCompassItem(); + assertTrue(StrangerRealms.isWarpedCompass(item)); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#isWarpedCompass(org.bukkit.inventory.ItemStack)}. + */ + @Test + void testIsWarpedCompass() { + ItemStack item = mock(ItemStack.class); + when(item.getType()).thenReturn(Material.ACACIA_BOAT); + assertFalse(StrangerRealms.isWarpedCompass(item)); + } + + /** + * Test method for {@link world.bentobox.stranger.StrangerRealms#getPlayerListener()}. + */ + @Test + void testGetPlayerListener() { + assertNotNull(addon.getPlayerListener()); + } + +} diff --git a/src/test/java/world/bentobox/stranger/TestWorldSettings.java b/src/test/java/world/bentobox/stranger/TestWorldSettings.java new file mode 100644 index 0000000..c550159 --- /dev/null +++ b/src/test/java/world/bentobox/stranger/TestWorldSettings.java @@ -0,0 +1,409 @@ +package world.bentobox.stranger; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Difficulty; +import org.bukkit.GameMode; +import org.bukkit.entity.EntityType; +import org.eclipse.jdt.annotation.NonNull; + +import world.bentobox.bentobox.api.configuration.WorldSettings; +import world.bentobox.bentobox.api.flags.Flag; + +/** + * Class for tests that require world settings + * @author tastybento + * + */ +public class TestWorldSettings implements WorldSettings { + + private long epoch; + + @Override + public GameMode getDefaultGameMode() { + + return GameMode.SURVIVAL; + } + + @Override + public Map getDefaultIslandFlags() { + + return Collections.emptyMap(); + } + + @Override + public Map getDefaultIslandSettings() { + + return Collections.emptyMap(); + } + + @Override + public Difficulty getDifficulty() { + + return Difficulty.EASY; + } + + @Override + public void setDifficulty(Difficulty difficulty) { + + + } + + @Override + public String getFriendlyName() { + + return "friendly_name"; + } + + @Override + public int getIslandDistance() { + + return 0; + } + + @Override + public int getIslandHeight() { + + return 0; + } + + @Override + public int getIslandProtectionRange() { + + return 0; + } + + @Override + public int getIslandStartX() { + + return 0; + } + + @Override + public int getIslandStartZ() { + + return 0; + } + + @Override + public int getIslandXOffset() { + + return 0; + } + + @Override + public int getIslandZOffset() { + + return 0; + } + + @Override + public List getIvSettings() { + + return Collections.emptyList(); + } + + @Override + public int getMaxHomes() { + + return 3; + } + + @Override + public int getMaxIslands() { + + return 0; + } + + @Override + public int getMaxTeamSize() { + + return 4; + } + + @Override + public int getNetherSpawnRadius() { + + return 10; + } + + @Override + public String getPermissionPrefix() { + + return "perm."; + } + + @Override + public Set getRemoveMobsWhitelist() { + + return Collections.emptySet(); + } + + @Override + public int getSeaHeight() { + + return 0; + } + + @Override + public List getHiddenFlags() { + + return Collections.emptyList(); + } + + @Override + public List getVisitorBannedCommands() { + + return Collections.emptyList(); + } + + @Override + public Map getWorldFlags() { + + return Collections.emptyMap(); + } + + @Override + public String getWorldName() { + + return "world_name"; + } + + @Override + public boolean isDragonSpawn() { + + return false; + } + + @Override + public boolean isEndGenerate() { + + return true; + } + + @Override + public boolean isEndIslands() { + + return true; + } + + @Override + public boolean isNetherGenerate() { + + return true; + } + + @Override + public boolean isNetherIslands() { + + return true; + } + + @Override + public boolean isOnJoinResetEnderChest() { + + return false; + } + + @Override + public boolean isOnJoinResetInventory() { + + return false; + } + + @Override + public boolean isOnJoinResetMoney() { + + return false; + } + + @Override + public boolean isOnJoinResetHealth() { + + return false; + } + + @Override + public boolean isOnJoinResetHunger() { + + return false; + } + + @Override + public boolean isOnJoinResetXP() { + + return false; + } + + @Override + public @NonNull List getOnJoinCommands() { + + return Collections.emptyList(); + } + + @Override + public boolean isOnLeaveResetEnderChest() { + + return false; + } + + @Override + public boolean isOnLeaveResetInventory() { + + return false; + } + + @Override + public boolean isOnLeaveResetMoney() { + + return false; + } + + @Override + public boolean isOnLeaveResetHealth() { + + return false; + } + + @Override + public boolean isOnLeaveResetHunger() { + + return false; + } + + @Override + public boolean isOnLeaveResetXP() { + + return false; + } + + @Override + public @NonNull List getOnLeaveCommands() { + + return Collections.emptyList(); + } + + @Override + public boolean isUseOwnGenerator() { + + return false; + } + + @Override + public boolean isWaterUnsafe() { + + return false; + } + + @Override + public List getGeoLimitSettings() { + + return Collections.emptyList(); + } + + @Override + public int getResetLimit() { + + return 0; + } + + @Override + public long getResetEpoch() { + + return epoch; + } + + @Override + public void setResetEpoch(long timestamp) { + this.epoch = timestamp; + + } + + @Override + public boolean isTeamJoinDeathReset() { + + return false; + } + + @Override + public int getDeathsMax() { + + return 0; + } + + @Override + public boolean isDeathsCounted() { + + return true; + } + + @Override + public boolean isDeathsResetOnNewIsland() { + + return true; + } + + @Override + public boolean isAllowSetHomeInNether() { + + return false; + } + + @Override + public boolean isAllowSetHomeInTheEnd() { + + return false; + } + + @Override + public boolean isRequireConfirmationToSetHomeInNether() { + + return false; + } + + @Override + public boolean isRequireConfirmationToSetHomeInTheEnd() { + + return false; + } + + @Override + public int getBanLimit() { + + return 10; + } + + @Override + public boolean isLeaversLoseReset() { + + return true; + } + + @Override + public boolean isKickedKeepInventory() { + + return true; + } + + @Override + public boolean isCreateIslandOnFirstLoginEnabled() { + + return false; + } + + @Override + public int getCreateIslandOnFirstLoginDelay() { + + return 0; + } + + @Override + public boolean isCreateIslandOnFirstLoginAbortOnLogout() { + + return false; + } + +} diff --git a/src/test/java/world/bentobox/stranger/WhiteBox.java b/src/test/java/world/bentobox/stranger/WhiteBox.java new file mode 100644 index 0000000..7c68178 --- /dev/null +++ b/src/test/java/world/bentobox/stranger/WhiteBox.java @@ -0,0 +1,26 @@ +package world.bentobox.stranger; + +public class WhiteBox { + /** + * Sets the value of a private static field using Java Reflection. + * @param targetClass The class containing the static field. + * @param fieldName The name of the private static field. + * @param value The value to set the field to. + */ + public static void setInternalState(Class targetClass, String fieldName, Object value) { + try { + // 1. Get the Field object from the class + java.lang.reflect.Field field = targetClass.getDeclaredField(fieldName); + + // 2. Make the field accessible (required for private fields) + field.setAccessible(true); + + // 3. Set the new value. The first argument is 'null' for static fields. + field.set(null, value); + + } catch (NoSuchFieldException | IllegalAccessException e) { + // Wrap reflection exceptions in a runtime exception for clarity + throw new RuntimeException("Failed to set static field '" + fieldName + "' on class " + targetClass.getName(), e); + } + } +}