discord-kagebot/src/test/kotlin/moe/kageru/kagebot/command/CommandTest.kt

307 lines
9.7 KiB
Kotlin
Raw Normal View History

2019-06-15 14:35:17 +02:00
package moe.kageru.kagebot.command
2019-06-09 18:41:51 +02:00
import io.kotlintest.matchers.string.shouldContain
2019-06-08 21:52:47 +02:00
import io.kotlintest.shouldBe
import io.kotlintest.specs.StringSpec
2019-06-08 23:51:29 +02:00
import io.mockk.every
import io.mockk.mockk
import moe.kageru.kagebot.Globals
import moe.kageru.kagebot.Kagebot.process
2019-06-15 14:35:17 +02:00
import moe.kageru.kagebot.TestUtil
import moe.kageru.kagebot.TestUtil.embedToString
import moe.kageru.kagebot.TestUtil.messageableAuthor
import moe.kageru.kagebot.TestUtil.mockMessage
import moe.kageru.kagebot.TestUtil.prepareTestEnvironment
import moe.kageru.kagebot.TestUtil.testMessageSuccess
import moe.kageru.kagebot.TestUtil.withCommands
import moe.kageru.kagebot.Util
import moe.kageru.kagebot.config.Config
2019-10-19 11:32:28 +02:00
import moe.kageru.kagebot.persistence.Dao
2019-06-09 18:41:51 +02:00
import org.javacord.api.entity.message.embed.EmbedBuilder
import org.javacord.api.entity.permission.Role
import org.javacord.api.entity.user.User
import java.util.*
2019-06-08 21:52:47 +02:00
class CommandTest : StringSpec({
prepareTestEnvironment()
"should increment command counter" {
withCommands(
"""
[[command]]
trigger = "!ping"
response = "pong"
""".trimIndent()
) {
val before = Globals.commandCounter.get()
testMessageSuccess("!ping", "pong")
Globals.commandCounter.get() shouldBe (before + 1)
}
}
2019-10-18 22:15:22 +02:00
"should match prefix command" {
withCommands(
"""
[[command]]
trigger = "!ping"
response = "pong"
""".trimIndent()
) {
testMessageSuccess("!ping", "pong")
}
2019-06-08 21:52:47 +02:00
}
"should print embed for command" {
val calls = mutableListOf<EmbedBuilder>()
prepareTestEnvironment(calls)
val heading = "heading 1"
val content = "this is the first paragraph of the embed"
withCommands(
"""
[[command]]
trigger = "!embed"
embed = [ "$heading", "$content" ]
""".trimIndent()
) {
TestUtil.withReplyContents(expected = listOf(heading, content)) {
mockMessage("!embed", replyEmbeds = it).process()
}
}
}
2019-06-08 21:52:47 +02:00
"should match contains command" {
withCommands(
"""
[[command]]
trigger = "somewhere"
response = "found it"
matchType = "CONTAINS"
""".trimIndent()
) {
testMessageSuccess("the trigger is somewhere in this message", "found it")
}
2019-06-08 21:52:47 +02:00
}
"should match regex command" {
withCommands(
"""
[[command]]
trigger = "A.+B"
response = "regex matched"
matchType = "REGEX"
""".trimIndent()
) {
testMessageSuccess("AcsdB", "regex matched")
}
2019-06-08 21:52:47 +02:00
}
"should ping author" {
withCommands(
"""
[[command]]
trigger = "answer me"
response = "@@ there you go"
""".trimIndent()
) {
testMessageSuccess("answer me", "<@1> there you go")
}
2019-06-08 23:51:29 +02:00
}
"should not react to own message" {
withCommands(
"""
[[command]]
trigger = "!ping"
response = "pong"
""".trimIndent()
) {
val calls = mutableListOf<String>()
mockMessage("!ping", replies = calls, isBot = true).process()
calls shouldBe mutableListOf()
}
2019-06-08 23:51:29 +02:00
}
"should delete messages and send copy to author" {
withCommands(
"""
[[command]]
trigger = "delet this"
[command.action]
delete = true
""".trimIndent()
) {
val messageContent = "delet this"
TestUtil.withReplyContents(expected = listOf(messageContent)) {
val mockMessage = mockMessage(messageContent)
every { mockMessage.deleteMessage() } returns mockk()
every { mockMessage.messageAuthor.asUser() } returns Optional.of(messageableAuthor(it))
mockMessage.process()
}
}
2019-06-08 21:52:47 +02:00
}
2019-06-09 01:04:00 +02:00
"should refuse command without permissions" {
withCommands(
"""
[[command]]
trigger = "!restricted"
response = "access granted"
[command.permissions]
hasOneOf = [
"testrole",
]
""".trimIndent()
) {
val replies = mutableListOf<String>()
val mockMessage = mockMessage("!restricted", replies = replies)
mockMessage.process()
2019-11-11 19:09:58 +01:00
replies shouldBe mutableListOf()
}
2019-06-09 01:04:00 +02:00
}
"should accept restricted command for owner" {
withCommands(
"""
[[command]]
trigger = "!restricted"
response = "access granted"
[command.permissions]
hasOneOf = [
"testrole"
]
""".trimIndent()
) {
val calls = mutableListOf<String>()
val mockMessage = mockMessage("!restricted", replies = calls)
every { mockMessage.messageAuthor.isBotOwner } returns true
mockMessage.process()
calls shouldBe mutableListOf("access granted")
}
2019-06-09 01:04:00 +02:00
}
"should accept restricted command with permissions" {
withCommands(
"""
[[command]]
trigger = "!restricted"
response = "access granted"
[command.permissions]
hasOneOf = [
"testrole"
]
""".trimIndent()
) {
val calls = mutableListOf<String>()
val mockMessage = mockMessage("!restricted", replies = calls)
every { mockMessage.messageAuthor.asUser() } returns Optional.of(mockk {
every { getRoles(any()) } returns listOf(
2019-07-13 15:39:50 +02:00
Config.server.getRolesByNameIgnoreCase("testrole")[0]
)
})
mockMessage.process()
calls shouldBe mutableListOf("access granted")
2019-06-10 08:32:18 +02:00
}
2019-06-09 01:04:00 +02:00
}
2019-06-10 09:19:03 +02:00
"should deny command to excluded roles" {
withCommands(
"""
[[command]]
trigger = "!almostUnrestricted"
response = "access granted"
[command.permissions]
hasNoneOf = ["testrole"]
""".trimIndent()
) {
val calls = mutableListOf<String>()
val mockMessage = mockMessage("!almostUnrestricted", replies = calls)
// with the banned role
every { mockMessage.messageAuthor.asUser() } returns mockk {
every { isPresent } returns true
every { get().getRoles(any()) } returns listOf(
2019-07-13 15:39:50 +02:00
Config.server.getRolesByNameIgnoreCase("testrole")[0]
)
}
mockMessage.process()
2019-06-10 09:19:03 +02:00
// without the role
every { mockMessage.messageAuthor.asUser() } returns mockk {
every { isPresent } returns true
every { get().getRoles(any()) } returns emptyList()
}
mockMessage.process()
2019-11-11 19:09:58 +01:00
// first message didn’t answer anything
calls shouldBe mutableListOf("access granted")
}
}
"should refuse DM only message in server channel" {
withCommands(
"""
[[command]]
trigger = "!dm"
response = "access granted"
[command.permissions]
onlyDM = true
""".trimIndent()
) {
val calls = mutableListOf<String>()
mockMessage("!dm", replies = calls).process()
2019-11-11 19:09:58 +01:00
calls shouldBe mutableListOf()
2019-06-10 09:19:03 +02:00
}
}
2019-06-10 08:32:18 +02:00
/*
* This implicitly tests that the message author is not included in anonymous complaints
* because getting the authors name from the mock is undefined.
*/
2019-06-09 18:41:51 +02:00
"should redirect" {
val calls = mutableListOf<EmbedBuilder>()
prepareTestEnvironment(calls)
withCommands(
"""
[[command]]
trigger = "!redirect"
response = "redirected"
[command.action.redirect]
target = "testchannel"
anonymous = true
""".trimIndent()
) {
val message = "this is a message"
mockMessage("!redirect $message").process()
calls.size shouldBe 1
embedToString(calls[0]) shouldContain "\"$message\""
}
2019-06-08 21:52:47 +02:00
}
"should assign" {
withCommands(
"""
[[command]]
trigger = "!assign"
[command.action.assign]
role = "testrole"
""".trimIndent()
) {
val roles = mutableListOf<Role>()
val user = mockk<User> {
every { addRole(capture(roles), "Requested via command.") } returns mockk()
}
2019-07-13 15:39:50 +02:00
every { Config.server.getMemberById(1) } returns Optional.of(user)
mockMessage("!assign").process()
roles shouldBe mutableListOf(Util.findRole("testrole"))
}
}
2019-10-19 11:32:28 +02:00
"should create VC" {
withCommands(
"""
[[command]]
trigger = "!vc"
feature = "vc"
""".trimIndent()
) {
testMessageSuccess("!vc 2", "Done")
Dao.isTemporaryVC("12345") shouldBe true
Dao.removeTemporaryVC("12345")
}
}
"should reject invalid vc command" {
withCommands(
"""
[[command]]
trigger = "!vc"
feature = "vc"
""".trimIndent()
) {
testMessageSuccess("!vc asd", "Invalid syntax, expected a number, got asd")
Dao.isTemporaryVC("12345") shouldBe false
}
}
2019-07-13 14:52:05 +02:00
})