update javacord and run ktlint
This commit is contained in:
parent
997284fb54
commit
80111b2bbf
@ -1,4 +1,6 @@
|
||||
# kagebot – where the code is better than the name
|
||||
# kagebot
|
||||
Kinda dead.
|
||||
|
||||
This bot is a replacement for [my old one](https://git.kageru.moe/kageru/discord-selphybot) with a very simple premise:
|
||||
As much as possible should be configurable in a human-readable way.
|
||||
This will allow anyone to modify the config to host their own instance tailored to their own needs,
|
||||
@ -14,4 +16,6 @@ The implementation has kind of deteriorated into a playground for me
|
||||
but it’s been running and moderating a 1000+ user server for over a year
|
||||
with relatively little maintenance.
|
||||
|
||||
[1]: While arrow is great, adding it to a project after the fact leads to a very weird combination of FP and non-FP constructs. Would not recommend in production.
|
||||
[1]: While arrow is great, adding it to a project after the fact leads to a very weird combination of FP and non-FP constructs.
|
||||
Would not recommend in production. This was also built in an early version of arrow that still had `Kind` and other concepts that were scrapped later,
|
||||
but I don’t plan to update that ever. The bot can keep running as-is until it breaks.
|
||||
|
@ -4,22 +4,22 @@ apply {
|
||||
plugin("kotlin-kapt")
|
||||
}
|
||||
plugins {
|
||||
kotlin("jvm") version "1.4.10"
|
||||
id("com.github.johnrengelman.shadow") version "5.2.0" apply true
|
||||
kotlin("jvm") version "1.9.0"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1" apply true
|
||||
application
|
||||
}
|
||||
|
||||
val botMainClass = "moe.kageru.kagebot.KagebotKt"
|
||||
application {
|
||||
mainClassName = botMainClass
|
||||
mainClass.set(botMainClass)
|
||||
}
|
||||
|
||||
tasks.withType<Jar> {
|
||||
manifest {
|
||||
attributes(
|
||||
mapOf(
|
||||
"Main-Class" to botMainClass
|
||||
)
|
||||
"Main-Class" to botMainClass,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -43,10 +43,10 @@ val arrowVersion = "0.11.0"
|
||||
dependencies {
|
||||
implementation("com.uchuhimo:konf-core:0.23.0")
|
||||
implementation("com.uchuhimo:konf-toml:0.23.0")
|
||||
implementation("org.javacord:javacord:3.1.1")
|
||||
implementation("org.javacord:javacord:3.8.0")
|
||||
implementation("org.mapdb:mapdb:3.0.8")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.10")
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.0")
|
||||
implementation("com.fasterxml.jackson.core:jackson-annotations:2.11.3")
|
||||
|
||||
implementation("io.arrow-kt:arrow-core:$arrowVersion")
|
||||
@ -55,10 +55,10 @@ dependencies {
|
||||
testImplementation("io.kotlintest:kotlintest-runner-junit5:3.4.2")
|
||||
testImplementation("io.mockk:mockk:1.10.0")
|
||||
// these two are needed to access javacord internals (such as reading from sent embeds during tests)
|
||||
testImplementation("org.javacord:javacord-core:3.1.1")
|
||||
testImplementation("org.javacord:javacord-core:3.8.0")
|
||||
testImplementation("com.fasterxml.jackson.core:jackson-databind:2.11.3")
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "14"
|
||||
kotlinOptions.jvmTarget = "20"
|
||||
}
|
||||
|
@ -42,12 +42,14 @@ object Kagebot {
|
||||
println("Caused by: ${e.cause}\n${e.cause?.stackTrace?.joinToString("\n")}")
|
||||
exitProcess(1)
|
||||
}
|
||||
Runtime.getRuntime().addShutdownHook(Thread {
|
||||
Log.info("Bot has been interrupted. Shutting down.")
|
||||
Dao.setCommandCounter(Globals.commandCounter.get())
|
||||
Dao.close()
|
||||
api.disconnect()
|
||||
})
|
||||
Runtime.getRuntime().addShutdownHook(
|
||||
Thread {
|
||||
Log.info("Bot has been interrupted. Shutting down.")
|
||||
Dao.setCommandCounter(Globals.commandCounter.get())
|
||||
Dao.close()
|
||||
api.disconnect()
|
||||
},
|
||||
)
|
||||
Log.info("kagebot Mk II running")
|
||||
api.addMessageCreateListener { checked { it.process() } }
|
||||
Config.features.eventFeatures().forEach { it.register(api) }
|
||||
|
@ -13,7 +13,7 @@ object Log {
|
||||
addHandler(
|
||||
FileHandler("kagebot.log", true).apply {
|
||||
formatter = LogFormatter()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -80,17 +80,6 @@ object Util {
|
||||
} catch (e: Exception) {
|
||||
Log.warn("An uncaught exception occurred.\n$e")
|
||||
Log.warn(e.stackTrace.joinToString("\n"))
|
||||
MessageUtil.sendEmbed(
|
||||
Globals.api.owner.get(),
|
||||
EmbedBuilder()
|
||||
.setColor(Color.RED)
|
||||
.addField("Error", "kagebot has encountered an error")
|
||||
.addField(
|
||||
"$e", """```
|
||||
${e.stackTrace.joinToString("\n\t")}
|
||||
```""".trimIndent().run { applyIf(length > 1800) { substring(1..1800) } }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class Command(
|
||||
private val actions: MessageActions?,
|
||||
embed: List<String>?,
|
||||
feature: String?,
|
||||
matchType: String?
|
||||
matchType: String?,
|
||||
) {
|
||||
val matchType: MatchType = matchType?.let { type ->
|
||||
MatchType.values().find { it.name.equals(type, ignoreCase = true) }
|
||||
@ -56,5 +56,5 @@ class Command(
|
||||
enum class MatchType(val matches: (String, Command) -> Boolean) {
|
||||
PREFIX({ message, command -> message.startsWith(command.trigger, ignoreCase = true) }),
|
||||
CONTAINS({ message, command -> message.contains(command.trigger, ignoreCase = true) }),
|
||||
REGEX({ message, command -> command.regex!!.matches(message) });
|
||||
REGEX({ message, command -> command.regex!!.matches(message) }),
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class MessageActions(
|
||||
private val delete: Boolean = false,
|
||||
private val redirect: MessageRedirect?,
|
||||
@JsonProperty("assign")
|
||||
private val assignment: RoleAssignment?
|
||||
private val assignment: RoleAssignment?,
|
||||
) {
|
||||
|
||||
fun run(message: MessageCreateEvent, command: Command) {
|
||||
|
@ -3,14 +3,12 @@ package moe.kageru.kagebot.command
|
||||
import arrow.core.Option
|
||||
import arrow.core.toOption
|
||||
import moe.kageru.kagebot.Util
|
||||
import moe.kageru.kagebot.extensions.unwrap
|
||||
import org.javacord.api.entity.permission.Role
|
||||
import org.javacord.api.event.message.MessageCreateEvent
|
||||
|
||||
class Permissions(
|
||||
hasOneOf: List<String>?,
|
||||
hasNoneOf: List<String>?,
|
||||
private val onlyDM: Boolean = false
|
||||
private val onlyDM: Boolean = false,
|
||||
) {
|
||||
private val hasOneOf: Option<Set<String>> = hasOneOf?.toSet().toOption()
|
||||
private val hasNoneOf: Option<Set<String>> = hasNoneOf?.toSet().toOption()
|
||||
|
@ -12,6 +12,6 @@ class RoleAssignment(@JsonProperty("role") role: String) {
|
||||
|
||||
fun assign(message: MessageCreateEvent) = message.getUser().fold(
|
||||
{ Log.warn("Could not find user ${message.messageAuthor.name} for role assign") },
|
||||
{ it.addRole(role, "Requested via command.") }
|
||||
{ it.addRole(role, "Requested via command.") },
|
||||
)
|
||||
}
|
||||
|
@ -22,11 +22,15 @@ class DebugFeature : MessageFeature {
|
||||
val runtime = Runtime.getRuntime()
|
||||
return MessageUtil.listToEmbed(
|
||||
listOf(
|
||||
"Bot:", getBotStats(),
|
||||
"Memory:", getMemoryInfo(runtime, osBean),
|
||||
"CPU:", getCpuInfo(osBean),
|
||||
"System:", getOsInfo()
|
||||
)
|
||||
"Bot:",
|
||||
getBotStats(),
|
||||
"Memory:",
|
||||
getMemoryInfo(runtime, osBean),
|
||||
"CPU:",
|
||||
getCpuInfo(osBean),
|
||||
"System:",
|
||||
getOsInfo(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@ -40,7 +44,7 @@ class DebugFeature : MessageFeature {
|
||||
uptime.toDaysPart(),
|
||||
uptime.toHoursPart(),
|
||||
uptime.toMinutesPart(),
|
||||
uptime.toSecondsPart()
|
||||
uptime.toSecondsPart(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package moe.kageru.kagebot.features
|
||||
class Features(
|
||||
val welcome: WelcomeFeature? = null,
|
||||
val timeout: TimeoutFeature? = null,
|
||||
vc: TempVCFeature = TempVCFeature(null)
|
||||
vc: TempVCFeature = TempVCFeature(null),
|
||||
) {
|
||||
private val debug = DebugFeature()
|
||||
private val help = HelpFeature()
|
||||
@ -18,7 +18,7 @@ class Features(
|
||||
"getConfig" to getConfig,
|
||||
"setConfig" to setConfig,
|
||||
"timeout" to timeout,
|
||||
"vc" to vc
|
||||
"vc" to vc,
|
||||
)
|
||||
|
||||
fun findByString(feature: String) = featureMap[feature]
|
||||
|
@ -19,17 +19,21 @@ class TempVCFeature(@JsonProperty("category") category: String? = null) : EventF
|
||||
private val category: ChannelCategory? = category?.let { Config.server.categoriesByName(it).first() }
|
||||
|
||||
override fun handle(message: MessageCreateEvent): Unit = with(message) {
|
||||
Either.cond(' ' in readableMessageContent,
|
||||
Either.cond(
|
||||
' ' in readableMessageContent,
|
||||
{ readableMessageContent.split(' ', limit = 2).last() },
|
||||
{ "Invalid syntax, expected `<command> <userlimit>`" })
|
||||
{ "Invalid syntax, expected `<command> <userlimit>`" },
|
||||
)
|
||||
.flatMap { limit ->
|
||||
limit.toIntOrNull().rightIfNotNull { "Invalid syntax, expected a number as limit, got $limit" }
|
||||
}.filterOrElse({ it < 99 }, { "Error: can’t create a channel with that many users." })
|
||||
.fold({ err -> channel.sendMessage(err) },
|
||||
.fold(
|
||||
{ err -> channel.sendMessage(err) },
|
||||
{ limit ->
|
||||
createChannel(message, limit)
|
||||
channel.sendMessage("Done")
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun register(api: DiscordApi) {
|
||||
@ -43,7 +47,7 @@ class TempVCFeature(@JsonProperty("category") category: String? = null) : EventF
|
||||
private fun deleteChannel(channel: ServerVoiceChannel) =
|
||||
channel.delete("Empty temporary channel").asOption().fold(
|
||||
{ Log.warn("Attempted to delete temporary VC without the necessary permissions") },
|
||||
{ Dao.removeTemporaryVC(channel.idAsString) }
|
||||
{ Dao.removeTemporaryVC(channel.idAsString) },
|
||||
)
|
||||
|
||||
private fun createChannel(message: MessageCreateEvent, limit: Int): Unit =
|
||||
@ -54,7 +58,8 @@ class TempVCFeature(@JsonProperty("category") category: String? = null) : EventF
|
||||
setCategory(category)
|
||||
}.create().asOption().fold(
|
||||
{ Log.warn("Attempted to create temporary VC without the necessary permissions") },
|
||||
{ channel -> Dao.addTemporaryVC(channel.idAsString) })
|
||||
{ channel -> Dao.addTemporaryVC(channel.idAsString) },
|
||||
)
|
||||
|
||||
private fun generateChannelName(message: MessageCreateEvent): String =
|
||||
"${message.messageAuthor.name}’s volatile corner"
|
||||
|
@ -30,7 +30,7 @@ class TimeoutFeature(@JsonProperty("role") role: String) : MessageFeature {
|
||||
Either.cond(
|
||||
args.size >= 3,
|
||||
{ Tuple3(args[1], args[2], args.getOrNull(3)) },
|
||||
{ "Error: expected “<command> <user> <time> [<reason>]”. If the name contains spaces, please use the user ID instead." }
|
||||
{ "Error: expected “<command> <user> <time> [<reason>]”. If the name contains spaces, please use the user ID instead." },
|
||||
).flatMap {
|
||||
it.mapFirst(Option.applicative(), ::findUser).fix()
|
||||
.toEither { "Error: User ${it.a} not found, consider using the user ID" }
|
||||
@ -47,7 +47,7 @@ class TimeoutFeature(@JsonProperty("role") role: String) : MessageFeature {
|
||||
addField("Timeout", Config.localization[LocalizationSpec.timeout].replace("@@", "$time"))
|
||||
reason?.let { addField("Reason", it) }
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ class TimeoutFeature(@JsonProperty("role") role: String) : MessageFeature {
|
||||
roleIds.forEach { findRole("$it").map(user::addRole) }
|
||||
user.removeRole(timeoutRole)
|
||||
Log.info("Lifted timeout from user ${user.discriminatedName}. Stored roles ${roleIds.joinToString()}")
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import org.javacord.api.event.server.member.ServerMemberJoinEvent
|
||||
class WelcomeFeature(
|
||||
content: List<String>?,
|
||||
fallbackChannel: String?,
|
||||
private val fallbackMessage: String?
|
||||
private val fallbackMessage: String?,
|
||||
) : MessageFeature, EventFeature {
|
||||
val embed: EmbedBuilder? by lazy { content?.let(MessageUtil::listToEmbed) }
|
||||
|
||||
@ -31,7 +31,7 @@ class WelcomeFeature(
|
||||
// If the user disabled direct messages, try the fallback (if defined)
|
||||
if (message.asOption().isEmpty() && hasFallback()) {
|
||||
fallbackChannel!!.sendMessage(
|
||||
fallbackMessage!!.replace("@@", event.user.mentionTag)
|
||||
fallbackMessage!!.replace("@@", event.user.mentionTag),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,11 @@ class ConfigTest : StringSpec() {
|
||||
timeout = "timeout"
|
||||
""".trimIndent()
|
||||
val message = TestUtil.mockMessage("anything")
|
||||
every { message.messageAttachments } returns listOf(mockk {
|
||||
every { url.openStream().readAllBytes() } returns testConfig.toByteArray()
|
||||
})
|
||||
every { message.messageAttachments } returns listOf(
|
||||
mockk {
|
||||
every { url.openStream().readAllBytes() } returns testConfig.toByteArray()
|
||||
},
|
||||
)
|
||||
SetConfigFeature().handle(message)
|
||||
Config.localization[LocalizationSpec.redirectedMessage] shouldBe redir
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ object TestUtil {
|
||||
replies: MutableList<String> = mutableListOf(),
|
||||
replyEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
||||
files: MutableList<File> = mutableListOf(),
|
||||
isBot: Boolean = false
|
||||
isBot: Boolean = false,
|
||||
): MessageCreateEvent {
|
||||
return mockk {
|
||||
every { messageContent } returns content
|
||||
@ -75,7 +75,7 @@ object TestUtil {
|
||||
fun prepareTestEnvironment(
|
||||
sentEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
||||
sentMessages: MutableList<String> = mutableListOf(),
|
||||
dmEmbeds: MutableList<EmbedBuilder> = mutableListOf()
|
||||
dmEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
||||
) {
|
||||
val channel = mockk<ServerTextChannel>(relaxed = true) {
|
||||
every { sendMessage(capture(sentEmbeds)) } returns mockk(relaxed = true) {
|
||||
@ -99,14 +99,16 @@ object TestUtil {
|
||||
every { isCompletedExceptionally } returns false
|
||||
every { join().idAsString } returns "12345"
|
||||
}
|
||||
every { getMembersByName(any()) } returns ListK.just(mockk(relaxed = true) {
|
||||
every { id } returns 123
|
||||
every { roles() } returns ListK.just(TEST_ROLE)
|
||||
every { getRoles(any()) } returns ListK.just(TEST_ROLE)
|
||||
every { sendMessage(capture(dmEmbeds)) } returns mockk(relaxed = true) {
|
||||
every { isCompletedExceptionally } returns false
|
||||
}
|
||||
})
|
||||
every { getMembersByName(any()) } returns setOf(
|
||||
mockk(relaxed = true) {
|
||||
every { id } returns 123
|
||||
every { roles() } returns ListK.just(TEST_ROLE)
|
||||
every { getRoles(any()) } returns ListK.just(TEST_ROLE)
|
||||
every { sendMessage(capture(dmEmbeds)) } returns mockk(relaxed = true) {
|
||||
every { isCompletedExceptionally } returns false
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
Globals.api = mockk(relaxed = true) {
|
||||
every { getServerById(any<String>()) } returns Optional.of(Config.server)
|
||||
@ -134,7 +136,7 @@ object TestUtil {
|
||||
fun withReplyContents(
|
||||
expected: List<String> = emptyList(),
|
||||
unexpected: List<String> = emptyList(),
|
||||
op: (MutableList<EmbedBuilder>) -> Unit
|
||||
op: (MutableList<EmbedBuilder>) -> Unit,
|
||||
) {
|
||||
val replies = mutableListOf<EmbedBuilder>()
|
||||
op(replies)
|
||||
|
@ -34,7 +34,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!ping"
|
||||
response = "pong"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val before = Globals.commandCounter.get()
|
||||
testMessageSuccess("!ping", "pong")
|
||||
@ -47,7 +47,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!ping"
|
||||
response = "pong"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("!ping", "pong")
|
||||
}
|
||||
@ -62,7 +62,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!embed"
|
||||
embed = [ "$heading", "$content" ]
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
TestUtil.withReplyContents(expected = listOf(heading, content)) {
|
||||
mockMessage("!embed", replyEmbeds = it).process()
|
||||
@ -76,7 +76,7 @@ class CommandTest : StringSpec({
|
||||
trigger = "somewhere"
|
||||
response = "found it"
|
||||
matchType = "CONTAINS"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("the trigger is somewhere in this message", "found it")
|
||||
}
|
||||
@ -88,7 +88,7 @@ class CommandTest : StringSpec({
|
||||
trigger = "A.+B"
|
||||
response = "regex matched"
|
||||
matchType = "REGEX"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("AcsdB", "regex matched")
|
||||
}
|
||||
@ -99,7 +99,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "answer me"
|
||||
response = "@@ there you go"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("answer me", "<@1> there you go")
|
||||
}
|
||||
@ -110,7 +110,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!ping"
|
||||
response = "pong"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<String>()
|
||||
mockMessage("!ping", replies = calls, isBot = true).process()
|
||||
@ -124,7 +124,7 @@ class CommandTest : StringSpec({
|
||||
trigger = "delet this"
|
||||
[command.action]
|
||||
delete = true
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val messageContent = "delet this"
|
||||
TestUtil.withReplyContents(expected = listOf(messageContent)) {
|
||||
@ -145,7 +145,7 @@ class CommandTest : StringSpec({
|
||||
hasOneOf = [
|
||||
"testrole",
|
||||
]
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val replies = mutableListOf<String>()
|
||||
val mockMessage = mockMessage("!restricted", replies = replies)
|
||||
@ -163,7 +163,7 @@ class CommandTest : StringSpec({
|
||||
hasOneOf = [
|
||||
"testrole"
|
||||
]
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<String>()
|
||||
val mockMessage = mockMessage("!restricted", replies = calls)
|
||||
@ -182,15 +182,17 @@ class CommandTest : StringSpec({
|
||||
hasOneOf = [
|
||||
"testrole"
|
||||
]
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<String>()
|
||||
val mockMessage = mockMessage("!restricted", replies = calls)
|
||||
every { mockMessage.messageAuthor.asUser() } returns Optional.of(mockk {
|
||||
every { roles() } returns ListK.just(
|
||||
Config.server.rolesByName("testrole").first()
|
||||
)
|
||||
})
|
||||
every { mockMessage.messageAuthor.asUser() } returns Optional.of(
|
||||
mockk {
|
||||
every { roles() } returns ListK.just(
|
||||
Config.server.rolesByName("testrole").first(),
|
||||
)
|
||||
},
|
||||
)
|
||||
mockMessage.process()
|
||||
calls shouldBe mutableListOf("access granted")
|
||||
}
|
||||
@ -203,7 +205,7 @@ class CommandTest : StringSpec({
|
||||
response = "access granted"
|
||||
[command.permissions]
|
||||
hasNoneOf = ["testrole"]
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<String>()
|
||||
val mockMessage = mockMessage("!almostUnrestricted", replies = calls)
|
||||
@ -211,7 +213,7 @@ class CommandTest : StringSpec({
|
||||
every { mockMessage.messageAuthor.asUser() } returns mockk {
|
||||
every { isPresent } returns true
|
||||
every { get().getRoles(any()) } returns listOf(
|
||||
Config.server.rolesByName("testrole").first()
|
||||
Config.server.rolesByName("testrole").first(),
|
||||
)
|
||||
}
|
||||
mockMessage.process()
|
||||
@ -234,7 +236,7 @@ class CommandTest : StringSpec({
|
||||
response = "access granted"
|
||||
[command.permissions]
|
||||
onlyDM = true
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<String>()
|
||||
mockMessage("!dm", replies = calls).process()
|
||||
@ -256,7 +258,7 @@ class CommandTest : StringSpec({
|
||||
[command.action.redirect]
|
||||
target = "testchannel"
|
||||
anonymous = true
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val message = "this is a message"
|
||||
mockMessage("!redirect $message").process()
|
||||
@ -271,7 +273,7 @@ class CommandTest : StringSpec({
|
||||
trigger = "!assign"
|
||||
[command.action.assign]
|
||||
role = "testrole"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val roles = mutableListOf<Role>()
|
||||
val user = mockk<User> {
|
||||
@ -288,7 +290,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!vc"
|
||||
feature = "vc"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("!vc 2", "Done")
|
||||
Dao.isTemporaryVC("12345") shouldBe true
|
||||
@ -301,7 +303,7 @@ class CommandTest : StringSpec({
|
||||
[[command]]
|
||||
trigger = "!vc"
|
||||
feature = "vc"
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
) {
|
||||
testMessageSuccess("!vc asd", "Invalid syntax, expected a number as limit, got asd")
|
||||
Dao.isTemporaryVC("12345") shouldBe false
|
||||
|
@ -16,7 +16,8 @@ class ConfigFeatureTest : ShouldSpec({
|
||||
[[command]]
|
||||
trigger = "!getConfig"
|
||||
feature = "getConfig"
|
||||
""".trimIndent()) {
|
||||
""".trimIndent(),
|
||||
) {
|
||||
val calls = mutableListOf<File>()
|
||||
mockMessage("!getConfig", files = calls).process()
|
||||
calls.size shouldBe 1
|
||||
|
@ -31,7 +31,7 @@ class HelpFeatureTest : StringSpec({
|
||||
trigger = "!prison"
|
||||
[command.permissions]
|
||||
hasOneOf = ["testrole"]
|
||||
""".trimIndent()
|
||||
""".trimIndent()
|
||||
"should show prefix command" {
|
||||
withCommands(commandConfig) {
|
||||
val expected = listOf("!ping", "!something")
|
||||
@ -47,11 +47,13 @@ class HelpFeatureTest : StringSpec({
|
||||
val unexpected = listOf("not a prefix")
|
||||
withReplyContents(expected = expected, unexpected = unexpected) { replies ->
|
||||
val message = mockMessage("!help", replyEmbeds = replies)
|
||||
every { message.messageAuthor.asUser() } returns Optional.of(mockk {
|
||||
every { getRoles(any()) } returns listOf(
|
||||
Config.server.rolesByName("testrole").first()
|
||||
)
|
||||
})
|
||||
every { message.messageAuthor.asUser() } returns Optional.of(
|
||||
mockk {
|
||||
every { getRoles(any()) } returns listOf(
|
||||
Config.server.rolesByName("testrole").first(),
|
||||
)
|
||||
},
|
||||
)
|
||||
message.process()
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class WelcomeFeatureTest : StringSpec({
|
||||
every { isCompletedExceptionally } returns false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
sentMessages shouldBe mutableListOf(Config.features.welcome!!.embed)
|
||||
}
|
||||
@ -40,7 +40,7 @@ class WelcomeFeatureTest : StringSpec({
|
||||
}
|
||||
every { mentionTag } returns "<@123>"
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
val channel = Config.server.channelsByName("").first()
|
||||
verify(exactly = 1) { channel.sendMessage("<@123> welcome") }
|
||||
|
Loading…
Reference in New Issue
Block a user