diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-02-26 00:17:21 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-02-26 00:17:21 +0900 |
| commit | 70c785eee4c61601ba7fffa17cc8b992b4793491 (patch) | |
| tree | 2bb41b90c19cfd3cfbe638f9f8fbd420ab96aa86 /platform-paper | |
| parent | 365d9ede9d0abaae2bad03231b6bc5243013fc92 (diff) | |
| download | LunaticChat-70c785eee4c61601ba7fffa17cc8b992b4793491.tar.gz LunaticChat-70c785eee4c61601ba7fffa17cc8b992b4793491.tar.bz2 LunaticChat-70c785eee4c61601ba7fffa17cc8b992b4793491.zip | |
test: expand test coverage across all modules
- Add 23 new test files covering exceptions, data classes, permissions,
setting handlers, commands, and cross-server relay
- Change command execute methods from private to internal visibility
to enable unit testing (16 command files)
- Engine coverage: 65.5% → 92.4%
- Platform-paper coverage: 16.8% → 40.0%
- Platform-velocity coverage: 62.4% → 76.8%
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'platform-paper')
34 files changed, 2332 insertions, 16 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt index a3dea37..82dcd9f 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt @@ -39,7 +39,7 @@ class StatusCommand( handleResult(context, result) } - private fun execute(ctx: CommandContext): CommandResult { + internal fun execute(ctx: CommandContext): CommandResult { val sender = ctx.requirePlayer() val features = configuration.features diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt index 90d4e6d..5a6b52f 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt @@ -68,7 +68,7 @@ class ChannelBanCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt index cad2231..fa97a46 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt @@ -81,7 +81,7 @@ class ChannelCreateCommand( ), ) - private fun execute( + internal fun execute( ctx: CommandContext, channelId: String, name: String, diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt index 8ca3a55..f39d8e8 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt @@ -72,7 +72,7 @@ class ChannelDeleteCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, channelId: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt index cb040d6..fc32f9b 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt @@ -63,7 +63,7 @@ class ChannelInfoCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, channelIdArg: String?, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt index d4ce07a..37c8d7a 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt @@ -58,7 +58,7 @@ class ChannelInviteCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt index 83a40b9..2edb0da 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt @@ -62,7 +62,7 @@ class ChannelJoinCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, channelId: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt index 672cf2d..452c48d 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt @@ -66,7 +66,7 @@ class ChannelKickCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt index 5e45d27..d763853 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt @@ -40,7 +40,7 @@ class ChannelLeaveCommand( handleResult(context, result) } - private fun execute(ctx: CommandContext): CommandResult { + internal fun execute(ctx: CommandContext): CommandResult { val sender = ctx.requirePlayer() // Get current channel before leaving diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt index 1004baf..c0df8bf 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt @@ -58,7 +58,7 @@ class ChannelListCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, page: Int, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt index 82caa39..a368abb 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt @@ -64,7 +64,7 @@ class ChannelModCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt index 576b072..6724052 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt @@ -64,7 +64,7 @@ class ChannelOwnershipCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt index 3b65765..7fb41c6 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt @@ -48,7 +48,7 @@ class ChannelStatusCommand( handleResult(context, result) } - private fun execute(ctx: CommandContext): CommandResult { + internal fun execute(ctx: CommandContext): CommandResult { val sender = ctx.requirePlayer() // Get active channel diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt index 13d44d2..6f8cc8f 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt @@ -58,7 +58,7 @@ class ChannelSwitchCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, channelId: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt index e7a7295..043ca01 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt @@ -63,7 +63,7 @@ class ChannelUnbanCommand( }, ) - private fun execute( + internal fun execute( ctx: CommandContext, playerName: String, ): CommandResult { diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt index cea1814..e447639 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommand.kt @@ -37,7 +37,7 @@ class ChatModeToggleCommand( handleResult(context, result) } - private fun execute(ctx: CommandContext): CommandResult { + internal fun execute(ctx: CommandContext): CommandResult { val sender = ctx.requirePlayer() val newMode = chatModeManager.toggleChatMode(sender.uniqueId) diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommandTest.kt new file mode 100644 index 0000000..95c8b92 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommandTest.kt @@ -0,0 +1,125 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.BuildInfo +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import dev.m1sk9.lunaticChat.paper.velocity.VelocityConnectionManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.unmockkObject +import io.mockk.verify +import net.kyori.adventure.text.Component +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class StatusCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(configuration: LunaticChatConfiguration = TestUtils.createTestConfiguration()): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + every { plugin.velocityConnectionManager } returns null + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = StatusCommand(plugin, languageManager, configuration) + return TestDeps(command, ctx, plugin, languageManager, configuration, mockPlayer) + } + + private data class TestDeps( + val command: StatusCommand, + val ctx: CommandContext, + val plugin: LunaticChat, + val languageManager: LanguageManager, + val configuration: LunaticChatConfiguration, + val mockPlayer: org.bukkit.entity.Player, + ) + + @Test + fun `execute should return Success`() { + val deps = createDependencies() + + mockkObject(BuildInfo) + try { + every { BuildInfo.versionWithCommit() } returns "0.10.0-test" + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkObject(BuildInfo) + } + } + + @Test + fun `execute should send messages to player`() { + val deps = createDependencies() + + mockkObject(BuildInfo) + try { + every { BuildInfo.versionWithCommit() } returns "0.10.0-test" + + deps.command.execute(deps.ctx) + + verify(atLeast = 1) { deps.mockPlayer.sendMessage(any<Component>()) } + } finally { + unmockkObject(BuildInfo) + } + } + + @Test + fun `execute with velocity enabled should check connection state`() { + val velocityConfig = + TestUtils.createTestConfiguration().let { config -> + config.copy( + features = + config.features.copy( + velocityIntegration = config.features.velocityIntegration.copy(enabled = true), + ), + ) + } + val deps = createDependencies(configuration = velocityConfig) + + val velocityManager = mockk<VelocityConnectionManager>(relaxed = true) + every { velocityManager.getState() } returns VelocityConnectionManager.ConnectionState.CONNECTED + every { deps.plugin.velocityConnectionManager } returns velocityManager + + mockkObject(BuildInfo) + try { + every { BuildInfo.versionWithCommit() } returns "0.10.0-test" + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkObject(BuildInfo) + } + } + + @Test + fun `execute should display feature toggles`() { + val deps = createDependencies() + + mockkObject(BuildInfo) + try { + every { BuildInfo.versionWithCommit() } returns "0.10.0-test" + + deps.command.execute(deps.ctx) + + // Verify multiple sendMessage calls for version, health, features, config, and links + verify(atLeast = 5) { deps.mockPlayer.sendMessage(any<Component>()) } + } finally { + unmockkObject(BuildInfo) + } + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommandTest.kt new file mode 100644 index 0000000..59fc98a --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommandTest.kt @@ -0,0 +1,137 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.Channel +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelPlayerAlreadyBannedException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelBanCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-ch" + + private val plugin = mockk<LunaticChat>(relaxed = true) + private val channelManager = mockk<ChannelManager>(relaxed = true) + private val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + private val notificationHandler = mockk<ChannelNotificationHandler>(relaxed = true) + private val languageManager = mockk<LanguageManager>(relaxed = true) + + private val command = ChannelBanCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager) + + @BeforeTest + fun setUp() { + mockkStatic(Bukkit::class) + every { languageManager.getMessage(any(), any()) } returns "test message" + } + + @AfterTest + fun tearDown() { + unmockkStatic(Bukkit::class) + } + + private fun createContext(): CommandContext { + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + return ctx + } + + private fun setupOfflinePlayer( + hasPlayedBefore: Boolean = true, + isOnline: Boolean = false, + ): OfflinePlayer { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns targetUUID + every { offlinePlayer.hasPlayedBefore() } returns hasPlayedBefore + every { offlinePlayer.isOnline } returns isOnline + every { offlinePlayer.name } returns "TargetPlayer" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + return offlinePlayer + } + + @Test + fun `execute should return SuccessWithMessage on ban`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { Bukkit.getPlayer(any<String>()) } returns null + + val channel = Channel(id = channelId, name = "Test Channel", ownerId = testUUID, createdAt = 1000L) + every { channelManager.banPlayer(channelId, targetUUID) } returns Result.success(channel) + every { channelManager.getChannel(channelId) } returns Result.success(channel) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.banPlayer(channelId, targetUUID) } + } + + @Test + fun `execute should return Failure when no active channel`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when no permission`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MEMBER + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when player not found`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer(hasPlayedBefore = false, isOnline = false) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when already banned`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { Bukkit.getPlayer(any<String>()) } returns null + + every { channelManager.banPlayer(channelId, targetUUID) } returns + Result.failure(ChannelPlayerAlreadyBannedException(targetUUID, channelId)) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommandTest.kt new file mode 100644 index 0000000..9c57eec --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommandTest.kt @@ -0,0 +1,128 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelLimitExceededException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelCreateCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(): Triple<CommandContext, ChannelManager, LanguageManager> { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val channelManager = mockk<ChannelManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getMessage(any()) } returns "test message" + + return Triple(ctx, channelManager, languageManager) + } + + @Test + fun `execute with valid ID should return SuccessWithMessage`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + every { channelManager.createChannel(any()) } returns + Result.success( + TestUtils.createTestChannel(id = "test-ch", name = "Test Channel", ownerId = testUUID), + ) + + val result = command.execute(ctx, "test-ch", "Test Channel", null, false) + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute with private channel should return SuccessWithMessage`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + every { channelManager.createChannel(any()) } returns + Result.success( + TestUtils.createTestChannel(id = "private-ch", name = "Private Channel", ownerId = testUUID, isPrivate = true), + ) + + val result = command.execute(ctx, "private-ch", "Private Channel", null, true) + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute with invalid ID pattern should return Failure`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + val result = command.execute(ctx, "ab", "Short ID", null, false) + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute when channel already exists should return Failure`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + every { channelManager.createChannel(any()) } returns + Result.failure( + IllegalArgumentException("Channel already exists"), + ) + + val result = command.execute(ctx, "existing-ch", "Existing Channel", null, false) + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute when limit exceeded should return Failure`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + every { channelManager.createChannel(any()) } returns + Result.failure( + ChannelLimitExceededException(10), + ) + + val result = command.execute(ctx, "new-channel", "New Channel", null, false) + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute with description should pass it to channel`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelCreateCommand(plugin, channelManager, languageManager) + + every { channelManager.createChannel(any()) } returns + Result.success( + TestUtils.createTestChannel(id = "desc-ch", name = "Desc Channel", description = "test desc", ownerId = testUUID), + ) + + val result = command.execute(ctx, "desc-ch", "Desc Channel", "test desc", false) + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { + channelManager.createChannel( + match { it.description == "test desc" }, + ) + } + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommandTest.kt new file mode 100644 index 0000000..5b76978 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommandTest.kt @@ -0,0 +1,95 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelNoOwnerPermissionException +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelDeleteCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(hasBypass: Boolean = false): Triple<CommandContext, ChannelManager, LanguageManager> { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + every { player.hasPermission(LunaticChatPermissionNode.ChannelBypass.permissionNode) } returns hasBypass + + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val channelManager = mockk<ChannelManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getMessage(any()) } returns "test message" + + return Triple(ctx, channelManager, languageManager) + } + + @Test + fun `execute should return SuccessWithMessage on successful delete`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelDeleteCommand(plugin, channelManager, languageManager) + + every { channelManager.deleteChannel("test-ch", testUUID, false) } returns Result.success(Unit) + + val result = command.execute(ctx, "test-ch") + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute should return Failure when channel not found`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelDeleteCommand(plugin, channelManager, languageManager) + + every { channelManager.deleteChannel("unknown-ch", testUUID, false) } returns + Result.failure( + ChannelNotFoundException("unknown-ch"), + ) + + val result = command.execute(ctx, "unknown-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when no owner permission`() { + val (ctx, channelManager, languageManager) = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelDeleteCommand(plugin, channelManager, languageManager) + + every { channelManager.deleteChannel("other-ch", testUUID, false) } returns + Result.failure( + ChannelNoOwnerPermissionException(testUUID), + ) + + val result = command.execute(ctx, "other-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute with bypass permission should pass hasBypass true`() { + val (ctx, channelManager, languageManager) = createDependencies(hasBypass = true) + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelDeleteCommand(plugin, channelManager, languageManager) + + every { channelManager.deleteChannel("test-ch", testUUID, true) } returns Result.success(Unit) + + val result = command.execute(ctx, "test-ch") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.deleteChannel("test-ch", testUUID, true) } + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommandTest.kt new file mode 100644 index 0000000..f1cd3a3 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommandTest.kt @@ -0,0 +1,123 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelInfoCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val channelId = "test-channel-1" + + private fun createDependencies(): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val channelManager = mockk<ChannelManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = ChannelInfoCommand(plugin, channelManager, languageManager) + return TestDeps(command, ctx, channelManager, languageManager, mockPlayer) + } + + private data class TestDeps( + val command: ChannelInfoCommand, + val ctx: CommandContext, + val channelManager: ChannelManager, + val languageManager: LanguageManager, + val mockPlayer: org.bukkit.entity.Player, + ) + + private fun mockBukkitOfflinePlayer() { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.name } returns "Player1" + every { Bukkit.getOfflinePlayer(any<UUID>()) } returns offlinePlayer + } + + @Test + fun `execute with channelId should return Success`() { + val deps = createDependencies() + val channel = TestUtils.createTestChannel(id = channelId, ownerId = testUUID) + val members = + listOf( + TestUtils.createTestChannelMember(channelId = channelId, playerId = testUUID), + ) + + every { deps.channelManager.getChannel(channelId) } returns Result.success(channel) + every { deps.channelManager.getChannelMembers(channelId) } returns Result.success(members) + + mockkStatic(Bukkit::class) + try { + mockBukkitOfflinePlayer() + + val result = deps.command.execute(deps.ctx, channelId) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute with null channelId should use active channel`() { + val deps = createDependencies() + val channel = TestUtils.createTestChannel(id = channelId, ownerId = testUUID) + val members = + listOf( + TestUtils.createTestChannelMember(channelId = channelId, playerId = testUUID), + ) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.channelManager.getChannel(channelId) } returns Result.success(channel) + every { deps.channelManager.getChannelMembers(channelId) } returns Result.success(members) + + mockkStatic(Bukkit::class) + try { + mockBukkitOfflinePlayer() + + val result = deps.command.execute(deps.ctx, null) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure when no channel specified and no active channel`() { + val deps = createDependencies() + + every { deps.channelManager.getPlayerChannel(testUUID) } returns null + + val result = deps.command.execute(deps.ctx, null) + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when channel not found`() { + val deps = createDependencies() + + every { deps.channelManager.getChannel("nonexistent") } returns + Result.failure(ChannelNotFoundException("nonexistent")) + + val result = deps.command.execute(deps.ctx, "nonexistent") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommandTest.kt new file mode 100644 index 0000000..c51f460 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommandTest.kt @@ -0,0 +1,152 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.bukkit.Bukkit +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelInviteCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-channel-1" + + private fun createDependencies(): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val channelManager = mockk<ChannelManager>(relaxed = true) + val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = ChannelInviteCommand(plugin, channelManager, membershipManager, languageManager) + return TestDeps(command, ctx, channelManager, membershipManager, languageManager, mockPlayer) + } + + private data class TestDeps( + val command: ChannelInviteCommand, + val ctx: CommandContext, + val channelManager: ChannelManager, + val membershipManager: ChannelMembershipManager, + val languageManager: LanguageManager, + val mockPlayer: org.bukkit.entity.Player, + ) + + @Test + fun `execute should return SuccessWithMessage on invite`() { + val deps = createDependencies() + val targetPlayer = TestUtils.createMockPlayer(uuid = targetUUID, name = "TargetPlayer") + val channel = TestUtils.createTestChannel(id = channelId, ownerId = testUUID) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + every { deps.channelManager.isPlayerBanned(channelId, targetUUID) } returns Result.success(false) + every { deps.membershipManager.joinChannel(targetUUID, channelId, bypassPrivateCheck = true) } returns Result.success(Unit) + every { deps.channelManager.getChannel(channelId) } returns Result.success(channel) + + mockkStatic(Bukkit::class) + try { + every { Bukkit.getPlayer(any<String>()) } returns targetPlayer + + val result = deps.command.execute(deps.ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure when inviting self`() { + val deps = createDependencies() + val selfTarget = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + + mockkStatic(Bukkit::class) + try { + every { Bukkit.getPlayer(any<String>()) } returns selfTarget + + val result = deps.command.execute(deps.ctx, "Player1") + + assertIs<CommandResult.Failure>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure when target is banned`() { + val deps = createDependencies() + val targetPlayer = TestUtils.createMockPlayer(uuid = targetUUID, name = "TargetPlayer") + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + every { deps.channelManager.isPlayerBanned(channelId, targetUUID) } returns Result.success(true) + + mockkStatic(Bukkit::class) + try { + every { Bukkit.getPlayer(any<String>()) } returns targetPlayer + + val result = deps.command.execute(deps.ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure when player not found`() { + val deps = createDependencies() + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + + mockkStatic(Bukkit::class) + try { + every { Bukkit.getPlayer(any<String>()) } returns null + + val result = deps.command.execute(deps.ctx, "OfflinePlayer") + + assertIs<CommandResult.Failure>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure when no permission`() { + val deps = createDependencies() + val targetPlayer = TestUtils.createMockPlayer(uuid = targetUUID, name = "TargetPlayer") + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MEMBER + + mockkStatic(Bukkit::class) + try { + every { Bukkit.getPlayer(any<String>()) } returns targetPlayer + + val result = deps.command.execute(deps.ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommandTest.kt new file mode 100644 index 0000000..72f0040 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommandTest.kt @@ -0,0 +1,151 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelAlreadyActiveException +import dev.m1sk9.lunaticChat.engine.exception.ChannelMemberAlreadyException +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.engine.exception.ChannelPlayerBannedException +import dev.m1sk9.lunaticChat.engine.exception.ChannelPrivateRequiresInvitationException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelJoinCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private data class Dependencies( + val ctx: CommandContext, + val channelManager: ChannelManager, + val membershipManager: ChannelMembershipManager, + val notificationHandler: ChannelNotificationHandler, + val languageManager: LanguageManager, + ) + + private fun createDependencies(): Dependencies { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val channelManager = mockk<ChannelManager>(relaxed = true) + val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + val notificationHandler = mockk<ChannelNotificationHandler>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getMessage(any()) } returns "test message" + + every { channelManager.getChannel(any()) } returns + Result.success( + TestUtils.createTestChannel(id = "test-ch", name = "Test Channel"), + ) + + return Dependencies(ctx, channelManager, membershipManager, notificationHandler, languageManager) + } + + @Test + fun `execute should return SuccessWithMessage on join`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "test-ch") } returns Result.success(Unit) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute should return Failure when channel not found`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "unknown-ch") } returns + Result.failure( + ChannelNotFoundException("unknown-ch"), + ) + + val result = command.execute(deps.ctx, "unknown-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when already active`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "test-ch") } returns + Result.failure( + ChannelAlreadyActiveException(testUUID, "test-ch"), + ) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when already member`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "test-ch") } returns + Result.failure( + ChannelMemberAlreadyException(testUUID, "test-ch"), + ) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when banned`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "test-ch") } returns + Result.failure( + ChannelPlayerBannedException(testUUID, "test-ch"), + ) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when private without invite`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelJoinCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.membershipManager.joinChannel(testUUID, "private-ch") } returns + Result.failure( + ChannelPrivateRequiresInvitationException(testUUID, "private-ch"), + ) + + val result = command.execute(deps.ctx, "private-ch") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommandTest.kt new file mode 100644 index 0000000..cab6ef0 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommandTest.kt @@ -0,0 +1,136 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.Channel +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelKickCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-ch" + + private val plugin = mockk<LunaticChat>(relaxed = true) + private val channelManager = mockk<ChannelManager>(relaxed = true) + private val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + private val notificationHandler = mockk<ChannelNotificationHandler>(relaxed = true) + private val languageManager = mockk<LanguageManager>(relaxed = true) + + private val command = ChannelKickCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager) + + @BeforeTest + fun setUp() { + mockkStatic(Bukkit::class) + every { languageManager.getMessage(any(), any()) } returns "test message" + } + + @AfterTest + fun tearDown() { + unmockkStatic(Bukkit::class) + } + + private fun createContext(): CommandContext { + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + return ctx + } + + private fun setupOfflinePlayer( + hasPlayedBefore: Boolean = true, + isOnline: Boolean = false, + ): OfflinePlayer { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns targetUUID + every { offlinePlayer.hasPlayedBefore() } returns hasPlayedBefore + every { offlinePlayer.isOnline } returns isOnline + every { offlinePlayer.name } returns "TargetPlayer" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + return offlinePlayer + } + + @Test + fun `execute should return SuccessWithMessage on kick`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { Bukkit.getPlayer(any<String>()) } returns null + every { membershipManager.isMember(targetUUID, channelId) } returns Result.success(true) + + val channel = Channel(id = channelId, name = "Test Channel", ownerId = testUUID, createdAt = 1000L) + every { channelManager.removeMember(channelId, targetUUID) } returns Result.success(Unit) + every { channelManager.getPlayerChannel(targetUUID) } returns channelId + every { channelManager.getChannel(channelId) } returns Result.success(channel) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.removeMember(channelId, targetUUID) } + } + + @Test + fun `execute should return Failure when no active channel`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when no permission`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MEMBER + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when target not member`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { Bukkit.getPlayer(any<String>()) } returns null + every { membershipManager.isMember(targetUUID, channelId) } returns Result.success(false) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when player not found`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer(hasPlayedBefore = false, isOnline = false) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommandTest.kt new file mode 100644 index 0000000..b97fe99 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommandTest.kt @@ -0,0 +1,125 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotMemberException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelLeaveCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private data class Dependencies( + val ctx: CommandContext, + val channelManager: ChannelManager, + val membershipManager: ChannelMembershipManager, + val notificationHandler: ChannelNotificationHandler, + val languageManager: LanguageManager, + ) + + private fun createDependencies(): Dependencies { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val channelManager = mockk<ChannelManager>(relaxed = true) + val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + val notificationHandler = mockk<ChannelNotificationHandler>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getMessage(any()) } returns "test message" + + return Dependencies(ctx, channelManager, membershipManager, notificationHandler, languageManager) + } + + @Test + fun `execute should return SuccessWithMessage on leave`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelLeaveCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns "ch-1" + every { deps.channelManager.getChannel("ch-1") } returns + Result.success( + TestUtils.createTestChannel(id = "ch-1", name = "Channel One"), + ) + every { deps.membershipManager.leaveChannel(testUUID) } returns Result.success(Unit) + + val result = command.execute(deps.ctx) + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute should return Failure when no active channel`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelLeaveCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns null + every { deps.membershipManager.leaveChannel(testUUID) } returns + Result.failure( + ChannelNotMemberException(testUUID, ""), + ) + + val result = command.execute(deps.ctx) + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should broadcast leave notification`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelLeaveCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns "ch-1" + every { deps.channelManager.getChannel("ch-1") } returns + Result.success( + TestUtils.createTestChannel(id = "ch-1", name = "Channel One"), + ) + every { deps.membershipManager.leaveChannel(testUUID) } returns Result.success(Unit) + + command.execute(deps.ctx) + + verify { deps.notificationHandler.broadcastLeave("ch-1", "Player1") } + } + + @Test + fun `execute should show channel name in success message`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = + ChannelLeaveCommand(plugin, deps.channelManager, deps.membershipManager, deps.notificationHandler, deps.languageManager) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns "ch-1" + every { deps.channelManager.getChannel("ch-1") } returns + Result.success( + TestUtils.createTestChannel(id = "ch-1", name = "My Channel"), + ) + every { deps.membershipManager.leaveChannel(testUUID) } returns Result.success(Unit) + + val result = command.execute(deps.ctx) + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { + deps.languageManager.getMessage( + "channel.leave.success", + match { it["channelName"] == "My Channel" }, + ) + } + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommandTest.kt new file mode 100644 index 0000000..5ca6184 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommandTest.kt @@ -0,0 +1,107 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelListCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val channelManager = mockk<ChannelManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = ChannelListCommand(plugin, channelManager, languageManager) + return TestDeps(command, ctx, channelManager, languageManager, mockPlayer) + } + + private data class TestDeps( + val command: ChannelListCommand, + val ctx: CommandContext, + val channelManager: ChannelManager, + val languageManager: LanguageManager, + val mockPlayer: org.bukkit.entity.Player, + ) + + @Test + fun `execute should return Success with public channels`() { + val deps = createDependencies() + val channels = + listOf( + TestUtils.createTestChannel(id = "channel-1", name = "Channel 1", ownerId = testUUID), + TestUtils.createTestChannel(id = "channel-2", name = "Channel 2", ownerId = testUUID), + ) + val members = + listOf( + TestUtils.createTestChannelMember(channelId = "channel-1", playerId = testUUID), + ) + + every { deps.channelManager.getPublicChannels() } returns Result.success(channels) + every { deps.channelManager.getChannelMembers(any()) } returns Result.success(members) + + val result = deps.command.execute(deps.ctx, 1) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `execute should return Success with empty list message`() { + val deps = createDependencies() + + every { deps.channelManager.getPublicChannels() } returns Result.success(emptyList()) + + val result = deps.command.execute(deps.ctx, 1) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `execute should return Success on page 1 of multiple`() { + val deps = createDependencies() + val channels = + (1..15).map { i -> + TestUtils.createTestChannel( + id = "channel-$i", + name = "Channel $i", + ownerId = testUUID, + ) + } + val members = + listOf( + TestUtils.createTestChannelMember(channelId = "channel-1", playerId = testUUID), + ) + + every { deps.channelManager.getPublicChannels() } returns Result.success(channels) + every { deps.channelManager.getChannelMembers(any()) } returns Result.success(members) + + val result = deps.command.execute(deps.ctx, 1) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `execute should return Failure on error`() { + val deps = createDependencies() + + every { deps.channelManager.getPublicChannels() } returns Result.failure(ChannelNotFoundException("error")) + + val result = deps.command.execute(deps.ctx, 1) + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommandTest.kt new file mode 100644 index 0000000..da7c7e2 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommandTest.kt @@ -0,0 +1,147 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.Channel +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelModCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-ch" + + private val plugin = mockk<LunaticChat>(relaxed = true) + private val channelManager = mockk<ChannelManager>(relaxed = true) + private val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + private val languageManager = mockk<LanguageManager>(relaxed = true) + + private val command = ChannelModCommand(plugin, channelManager, membershipManager, languageManager) + + @BeforeTest + fun setUp() { + mockkStatic(Bukkit::class) + every { languageManager.getMessage(any(), any()) } returns "test message" + } + + @AfterTest + fun tearDown() { + unmockkStatic(Bukkit::class) + } + + private fun createContext(): CommandContext { + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + return ctx + } + + private fun setupOfflinePlayer( + hasPlayedBefore: Boolean = true, + isOnline: Boolean = false, + ): OfflinePlayer { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns targetUUID + every { offlinePlayer.hasPlayedBefore() } returns hasPlayedBefore + every { offlinePlayer.isOnline } returns isOnline + every { offlinePlayer.name } returns "TargetPlayer" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + return offlinePlayer + } + + @Test + fun `execute should promote to moderator`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { membershipManager.getMemberRoleOrNull(targetUUID, channelId) } returns ChannelRole.MEMBER + + val channel = Channel(id = channelId, name = "Test Channel", ownerId = testUUID, createdAt = 1000L) + every { channelManager.updateMemberRole(channelId, targetUUID, ChannelRole.MODERATOR) } returns Result.success(Unit) + every { channelManager.getChannel(channelId) } returns Result.success(channel) + every { Bukkit.getPlayer(any<String>()) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.updateMemberRole(channelId, targetUUID, ChannelRole.MODERATOR) } + } + + @Test + fun `execute should demote from moderator`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { membershipManager.getMemberRoleOrNull(targetUUID, channelId) } returns ChannelRole.MODERATOR + + val channel = Channel(id = channelId, name = "Test Channel", ownerId = testUUID, createdAt = 1000L) + every { channelManager.updateMemberRole(channelId, targetUUID, ChannelRole.MEMBER) } returns Result.success(Unit) + every { channelManager.getChannel(channelId) } returns Result.success(channel) + every { Bukkit.getPlayer(any<String>()) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.updateMemberRole(channelId, targetUUID, ChannelRole.MEMBER) } + } + + @Test + fun `execute should return Failure when modding self`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns testUUID + every { offlinePlayer.hasPlayedBefore() } returns true + every { offlinePlayer.isOnline } returns false + every { offlinePlayer.name } returns "Player1" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + + val result = command.execute(ctx, "Player1") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when not owner`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MODERATOR + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when target not member`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { membershipManager.getMemberRoleOrNull(targetUUID, channelId) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommandTest.kt new file mode 100644 index 0000000..9f25264 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommandTest.kt @@ -0,0 +1,139 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.Channel +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelOwnershipCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-ch" + + private val plugin = mockk<LunaticChat>(relaxed = true) + private val channelManager = mockk<ChannelManager>(relaxed = true) + private val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + private val languageManager = mockk<LanguageManager>(relaxed = true) + + private val command = ChannelOwnershipCommand(plugin, channelManager, membershipManager, languageManager) + + @BeforeTest + fun setUp() { + mockkStatic(Bukkit::class) + every { languageManager.getMessage(any(), any()) } returns "test message" + } + + @AfterTest + fun tearDown() { + unmockkStatic(Bukkit::class) + } + + private fun createContext(): CommandContext { + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + return ctx + } + + private fun setupOfflinePlayer( + hasPlayedBefore: Boolean = true, + isOnline: Boolean = false, + ): OfflinePlayer { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns targetUUID + every { offlinePlayer.hasPlayedBefore() } returns hasPlayedBefore + every { offlinePlayer.isOnline } returns isOnline + every { offlinePlayer.name } returns "TargetPlayer" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + return offlinePlayer + } + + @Test + fun `execute should transfer ownership successfully`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { membershipManager.getMemberRoleOrNull(targetUUID, channelId) } returns ChannelRole.MEMBER + + val updatedChannel = Channel(id = channelId, name = "Test Channel", ownerId = targetUUID, createdAt = 1000L) + every { channelManager.updateChannelOwner(channelId, targetUUID) } returns Result.success(updatedChannel) + every { Bukkit.getPlayer(any<String>()) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.updateChannelOwner(channelId, targetUUID) } + } + + @Test + fun `execute should return Failure when transferring to self`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns testUUID + every { offlinePlayer.hasPlayedBefore() } returns true + every { offlinePlayer.isOnline } returns false + every { offlinePlayer.name } returns "Player1" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + + val result = command.execute(ctx, "Player1") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when target not member`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + every { membershipManager.getMemberRoleOrNull(targetUUID, channelId) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when not owner`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MODERATOR + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when player not found`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer(hasPlayedBefore = false, isOnline = false) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommandTest.kt new file mode 100644 index 0000000..301160b --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommandTest.kt @@ -0,0 +1,142 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelStatusCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val channelId = "test-channel-1" + + private fun createDependencies(): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val channelManager = mockk<ChannelManager>(relaxed = true) + val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = ChannelStatusCommand(plugin, channelManager, membershipManager, languageManager) + return TestDeps(command, ctx, channelManager, membershipManager, languageManager, mockPlayer) + } + + private data class TestDeps( + val command: ChannelStatusCommand, + val ctx: CommandContext, + val channelManager: ChannelManager, + val membershipManager: ChannelMembershipManager, + val languageManager: LanguageManager, + val mockPlayer: org.bukkit.entity.Player, + ) + + private fun mockBukkitOfflinePlayer() { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.name } returns "Player1" + every { Bukkit.getOfflinePlayer(any<UUID>()) } returns offlinePlayer + } + + @Test + fun `execute with active channel should return Success`() { + val deps = createDependencies() + val channel = TestUtils.createTestChannel(id = channelId, ownerId = testUUID) + val members = + listOf( + TestUtils.createTestChannelMember(channelId = channelId, playerId = testUUID), + ) + + every { deps.channelManager.getPlayerChannel(testUUID) } returns channelId + every { deps.channelManager.getChannel(channelId) } returns Result.success(channel) + every { deps.channelManager.getChannelMembers(channelId) } returns Result.success(members) + every { deps.membershipManager.getPlayerChannels(testUUID) } returns Result.success(listOf(channelId)) + + mockkStatic(Bukkit::class) + try { + mockBukkitOfflinePlayer() + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute without active channel should return Success`() { + val deps = createDependencies() + + every { deps.channelManager.getPlayerChannel(testUUID) } returns null + every { deps.membershipManager.getPlayerChannels(testUUID) } returns Result.success(emptyList()) + + mockkStatic(Bukkit::class) + try { + mockBukkitOfflinePlayer() + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute with multiple channels should return Success`() { + val deps = createDependencies() + val channelIds = listOf("channel-1", "channel-2", "channel-3") + + every { deps.channelManager.getPlayerChannel(testUUID) } returns "channel-1" + every { deps.channelManager.getChannel("channel-1") } returns + Result.success(TestUtils.createTestChannel(id = "channel-1", name = "Channel 1", ownerId = testUUID)) + every { deps.channelManager.getChannel("channel-2") } returns + Result.success(TestUtils.createTestChannel(id = "channel-2", name = "Channel 2", ownerId = testUUID)) + every { deps.channelManager.getChannel("channel-3") } returns + Result.success(TestUtils.createTestChannel(id = "channel-3", name = "Channel 3", ownerId = testUUID)) + every { deps.channelManager.getChannelMembers(any()) } returns + Result.success( + listOf(TestUtils.createTestChannelMember(playerId = testUUID)), + ) + every { deps.membershipManager.getPlayerChannels(testUUID) } returns Result.success(channelIds) + + mockkStatic(Bukkit::class) + try { + mockBukkitOfflinePlayer() + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } finally { + unmockkStatic(Bukkit::class) + } + } + + @Test + fun `execute should return Failure on error`() { + val deps = createDependencies() + + every { deps.channelManager.getPlayerChannel(testUUID) } returns null + every { deps.membershipManager.getPlayerChannels(testUUID) } returns + Result.failure(ChannelNotFoundException("error")) + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommandTest.kt new file mode 100644 index 0000000..eb78956 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommandTest.kt @@ -0,0 +1,108 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelAlreadyActiveException +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException +import dev.m1sk9.lunaticChat.engine.exception.ChannelNotMemberException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelSwitchCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private data class Dependencies( + val ctx: CommandContext, + val channelManager: ChannelManager, + val membershipManager: ChannelMembershipManager, + val languageManager: LanguageManager, + ) + + private fun createDependencies(): Dependencies { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val channelManager = mockk<ChannelManager>(relaxed = true) + val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getMessage(any()) } returns "test message" + + every { channelManager.getChannel(any()) } returns + Result.success( + TestUtils.createTestChannel(id = "test-ch", name = "Test Channel"), + ) + + return Dependencies(ctx, channelManager, membershipManager, languageManager) + } + + @Test + fun `execute should return SuccessWithMessage on switch`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelSwitchCommand(plugin, deps.channelManager, deps.membershipManager, deps.languageManager) + + every { deps.membershipManager.switchChannel(testUUID, "test-ch") } returns Result.success(Unit) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.SuccessWithMessage>(result) + } + + @Test + fun `execute should return Failure when channel not found`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelSwitchCommand(plugin, deps.channelManager, deps.membershipManager, deps.languageManager) + + every { deps.membershipManager.switchChannel(testUUID, "unknown-ch") } returns + Result.failure( + ChannelNotFoundException("unknown-ch"), + ) + + val result = command.execute(deps.ctx, "unknown-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when already active`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelSwitchCommand(plugin, deps.channelManager, deps.membershipManager, deps.languageManager) + + every { deps.membershipManager.switchChannel(testUUID, "test-ch") } returns + Result.failure( + ChannelAlreadyActiveException(testUUID, "test-ch"), + ) + + val result = command.execute(deps.ctx, "test-ch") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when not member`() { + val deps = createDependencies() + val plugin = mockk<LunaticChat>(relaxed = true) + val command = ChannelSwitchCommand(plugin, deps.channelManager, deps.membershipManager, deps.languageManager) + + every { deps.membershipManager.switchChannel(testUUID, "other-ch") } returns + Result.failure( + ChannelNotMemberException(testUUID, "other-ch"), + ) + + val result = command.execute(deps.ctx, "other-ch") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommandTest.kt new file mode 100644 index 0000000..16dd383 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommandTest.kt @@ -0,0 +1,121 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.channel + +import dev.m1sk9.lunaticChat.engine.chat.channel.Channel +import dev.m1sk9.lunaticChat.engine.chat.channel.ChannelRole +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.engine.exception.ChannelPlayerNotBannedException +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager +import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.bukkit.Bukkit +import org.bukkit.OfflinePlayer +import java.util.UUID +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertIs + +class ChannelUnbanCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + private val targetUUID = UUID.fromString("00000002-0000-0000-0000-000000000000") + private val channelId = "test-ch" + + private val plugin = mockk<LunaticChat>(relaxed = true) + private val channelManager = mockk<ChannelManager>(relaxed = true) + private val membershipManager = mockk<ChannelMembershipManager>(relaxed = true) + private val languageManager = mockk<LanguageManager>(relaxed = true) + + private val command = ChannelUnbanCommand(plugin, channelManager, membershipManager, languageManager) + + @BeforeTest + fun setUp() { + mockkStatic(Bukkit::class) + every { languageManager.getMessage(any(), any()) } returns "test message" + } + + @AfterTest + fun tearDown() { + unmockkStatic(Bukkit::class) + } + + private fun createContext(): CommandContext { + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + return ctx + } + + private fun setupOfflinePlayer( + hasPlayedBefore: Boolean = true, + isOnline: Boolean = false, + ): OfflinePlayer { + val offlinePlayer = mockk<OfflinePlayer>(relaxed = true) + every { offlinePlayer.uniqueId } returns targetUUID + every { offlinePlayer.hasPlayedBefore() } returns hasPlayedBefore + every { offlinePlayer.isOnline } returns isOnline + every { offlinePlayer.name } returns "TargetPlayer" + every { Bukkit.getOfflinePlayer(any<String>()) } returns offlinePlayer + return offlinePlayer + } + + @Test + fun `execute should return SuccessWithMessage on unban`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + + val channel = Channel(id = channelId, name = "Test Channel", ownerId = testUUID, createdAt = 1000L) + every { channelManager.unbanPlayer(channelId, targetUUID) } returns Result.success(channel) + every { channelManager.getChannel(channelId) } returns Result.success(channel) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.SuccessWithMessage>(result) + verify { channelManager.unbanPlayer(channelId, targetUUID) } + } + + @Test + fun `execute should return Failure when no active channel`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns null + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when no permission`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.MEMBER + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } + + @Test + fun `execute should return Failure when player not banned`() { + val ctx = createContext() + every { channelManager.getPlayerChannel(testUUID) } returns channelId + every { membershipManager.getMemberRoleOrNull(testUUID, channelId) } returns ChannelRole.OWNER + setupOfflinePlayer() + + every { channelManager.unbanPlayer(channelId, targetUUID) } returns + Result.failure(ChannelPlayerNotBannedException(targetUUID, channelId)) + + val result = command.execute(ctx, "TargetPlayer") + + assertIs<CommandResult.Failure>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt new file mode 100644 index 0000000..d43c867 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/chatmode/ChatModeToggleCommandTest.kt @@ -0,0 +1,88 @@ +package dev.m1sk9.lunaticChat.paper.command.impl.lc.chatmode + +import dev.m1sk9.lunaticChat.engine.chat.ChatMode +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.chat.ChatModeManager +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.kyori.adventure.text.Component +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class ChatModeToggleCommandTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(): TestDeps { + val plugin = mockk<LunaticChat>(relaxed = true) + val chatModeManager = mockk<ChatModeManager>(relaxed = true) + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + + val mockPlayer = TestUtils.createMockPlayer(uuid = testUUID, name = "Player1") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns mockPlayer + + val command = ChatModeToggleCommand(plugin, chatModeManager, languageManager) + return TestDeps(command, ctx, chatModeManager, languageManager, mockPlayer) + } + + private data class TestDeps( + val command: ChatModeToggleCommand, + val ctx: CommandContext, + val chatModeManager: ChatModeManager, + val languageManager: LanguageManager, + val mockPlayer: org.bukkit.entity.Player, + ) + + @Test + fun `execute should toggle to CHANNEL mode`() { + val deps = createDependencies() + + every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.CHANNEL + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + verify { deps.chatModeManager.toggleChatMode(testUUID) } + } + + @Test + fun `execute should toggle to GLOBAL mode`() { + val deps = createDependencies() + + every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.GLOBAL + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + verify { deps.chatModeManager.toggleChatMode(testUUID) } + } + + @Test + fun `execute should send message to player`() { + val deps = createDependencies() + + every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.CHANNEL + + deps.command.execute(deps.ctx) + + verify { deps.mockPlayer.sendMessage(any<Component>()) } + } + + @Test + fun `execute should return Success`() { + val deps = createDependencies() + + every { deps.chatModeManager.toggleChatMode(testUUID) } returns ChatMode.GLOBAL + + val result = deps.command.execute(deps.ctx) + + assertIs<CommandResult.Success>(result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/SettingHandlerRegistryTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/SettingHandlerRegistryTest.kt new file mode 100644 index 0000000..52927a8 --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/SettingHandlerRegistryTest.kt @@ -0,0 +1,101 @@ +package dev.m1sk9.lunaticChat.paper.command.setting + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class SettingHandlerRegistryTest { + private fun createMockHandler(settingKey: SettingKey): SettingHandler = + object : SettingHandler { + override val key: SettingKey = settingKey + + override fun execute( + ctx: CommandContext, + enable: Boolean, + ): CommandResult = CommandResult.Success + + override fun showStatus(ctx: CommandContext): CommandResult = CommandResult.Success + } + + @Test + fun `register should make handler retrievable`() { + val registry = SettingHandlerRegistry() + val handler = createMockHandler(SettingKey.Japanese) + + registry.register(handler) + + assertEquals(handler, registry.getHandler(SettingKey.Japanese)) + } + + @Test + fun `registerAll should register multiple handlers`() { + val registry = SettingHandlerRegistry() + val handler1 = createMockHandler(SettingKey.Japanese) + val handler2 = createMockHandler(SettingKey.Notice) + val handler3 = createMockHandler(SettingKey.ChNotice) + + registry.registerAll(handler1, handler2, handler3) + + assertEquals(handler1, registry.getHandler(SettingKey.Japanese)) + assertEquals(handler2, registry.getHandler(SettingKey.Notice)) + assertEquals(handler3, registry.getHandler(SettingKey.ChNotice)) + } + + @Test + fun `getHandler should return null for unregistered key`() { + val registry = SettingHandlerRegistry() + + assertNull(registry.getHandler(SettingKey.Japanese)) + } + + @Test + fun `getAvailableKeys should return registered keys`() { + val registry = SettingHandlerRegistry() + registry.register(createMockHandler(SettingKey.Japanese)) + registry.register(createMockHandler(SettingKey.Notice)) + + val keys = registry.getAvailableKeys() + + assertEquals(2, keys.size) + assertTrue(keys.contains("japanese")) + assertTrue(keys.contains("notice")) + } + + @Test + fun `getAvailableKeys should return empty list for empty registry`() { + val registry = SettingHandlerRegistry() + assertTrue(registry.getAvailableKeys().isEmpty()) + } + + @Test + fun `register should overwrite handler with same key`() { + val registry = SettingHandlerRegistry() + val handler1 = createMockHandler(SettingKey.Japanese) + val handler2 = createMockHandler(SettingKey.Japanese) + + registry.register(handler1) + registry.register(handler2) + + assertEquals(handler2, registry.getHandler(SettingKey.Japanese)) + assertEquals(1, registry.getAvailableKeys().size) + } + + @Test + fun `register should return registry for method chaining`() { + val registry = SettingHandlerRegistry() + val result = registry.register(createMockHandler(SettingKey.Japanese)) + + assertEquals(registry, result) + } + + @Test + fun `registerAll should return registry for method chaining`() { + val registry = SettingHandlerRegistry() + val result = registry.registerAll(createMockHandler(SettingKey.Japanese)) + + assertEquals(registry, result) + } +} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/handler/SettingHandlerTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/handler/SettingHandlerTest.kt new file mode 100644 index 0000000..1967e1c --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/setting/handler/SettingHandlerTest.kt @@ -0,0 +1,191 @@ +package dev.m1sk9.lunaticChat.paper.command.setting.handler + +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.TestUtils +import dev.m1sk9.lunaticChat.paper.command.core.CommandContext +import dev.m1sk9.lunaticChat.paper.command.setting.SettingKey +import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager +import dev.m1sk9.lunaticChat.paper.settings.PlayerSettingsManager +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.kyori.adventure.text.Component +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertIs + +class SettingHandlerTest { + private val testUUID = UUID.fromString("00000001-0000-0000-0000-000000000000") + + private fun createDependencies(): Triple<CommandContext, PlayerSettingsManager, LanguageManager> { + val player = TestUtils.createMockPlayer(uuid = testUUID, name = "TestPlayer") + val ctx = mockk<CommandContext>(relaxed = true) + every { ctx.requirePlayer() } returns player + + val settingsManager = mockk<PlayerSettingsManager>(relaxed = true) + every { settingsManager.getSettings(testUUID) } returns + TestUtils.createTestPlayerSettings(uuid = testUUID) + + val languageManager = mockk<LanguageManager>(relaxed = true) + every { languageManager.getMessage(any(), any()) } returns "test message" + every { languageManager.getToggleText(any()) } returns "ON" + + return Triple(ctx, settingsManager, languageManager) + } + + // --- JapaneseConversionSettingHandler --- + + @Test + fun `JapaneseConversionSettingHandler key should be Japanese`() { + val (_, settingsManager, languageManager) = createDependencies() + val handler = JapaneseConversionSettingHandler(settingsManager, languageManager) + assertIs<SettingKey.Japanese>(handler.key) + } + + @Test + fun `JapaneseConversionSettingHandler execute enable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = JapaneseConversionSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, true) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { it.japaneseConversionEnabled }) } + } + + @Test + fun `JapaneseConversionSettingHandler execute disable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = JapaneseConversionSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, false) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { !it.japaneseConversionEnabled }) } + } + + @Test + fun `JapaneseConversionSettingHandler showStatus should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = JapaneseConversionSettingHandler(settingsManager, languageManager) + + val result = handler.showStatus(ctx) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `JapaneseConversionSettingHandler execute should send message to player`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = JapaneseConversionSettingHandler(settingsManager, languageManager) + + handler.execute(ctx, true) + + val player = ctx.requirePlayer() + verify { player.sendMessage(any<Component>()) } + } + + // --- DirectMessageNoticeSettingHandler --- + + @Test + fun `DirectMessageNoticeSettingHandler key should be Notice`() { + val (_, settingsManager, languageManager) = createDependencies() + val handler = DirectMessageNoticeSettingHandler(settingsManager, languageManager) + assertIs<SettingKey.Notice>(handler.key) + } + + @Test + fun `DirectMessageNoticeSettingHandler execute enable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = DirectMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, true) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { it.directMessageNotificationEnabled }) } + } + + @Test + fun `DirectMessageNoticeSettingHandler execute disable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = DirectMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, false) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { !it.directMessageNotificationEnabled }) } + } + + @Test + fun `DirectMessageNoticeSettingHandler showStatus should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = DirectMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.showStatus(ctx) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `DirectMessageNoticeSettingHandler execute should send message to player`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = DirectMessageNoticeSettingHandler(settingsManager, languageManager) + + handler.execute(ctx, true) + + val player = ctx.requirePlayer() + verify { player.sendMessage(any<Component>()) } + } + + // --- ChannelMessageNoticeSettingHandler --- + + @Test + fun `ChannelMessageNoticeSettingHandler key should be ChNotice`() { + val (_, settingsManager, languageManager) = createDependencies() + val handler = ChannelMessageNoticeSettingHandler(settingsManager, languageManager) + assertIs<SettingKey.ChNotice>(handler.key) + } + + @Test + fun `ChannelMessageNoticeSettingHandler execute enable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = ChannelMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, true) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { it.channelMessageNotificationEnabled }) } + } + + @Test + fun `ChannelMessageNoticeSettingHandler execute disable should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = ChannelMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.execute(ctx, false) + + assertIs<CommandResult.Success>(result) + verify { settingsManager.updateSettings(match { !it.channelMessageNotificationEnabled }) } + } + + @Test + fun `ChannelMessageNoticeSettingHandler showStatus should return Success`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = ChannelMessageNoticeSettingHandler(settingsManager, languageManager) + + val result = handler.showStatus(ctx) + + assertIs<CommandResult.Success>(result) + } + + @Test + fun `ChannelMessageNoticeSettingHandler execute should send message to player`() { + val (ctx, settingsManager, languageManager) = createDependencies() + val handler = ChannelMessageNoticeSettingHandler(settingsManager, languageManager) + + handler.execute(ctx, true) + + val player = ctx.requirePlayer() + verify { player.sendMessage(any<Component>()) } + } +} |
