Add optional reason to timeout command (closes #14)
This commit is contained in:
parent
b4c2275670
commit
35bd570c93
|
@ -18,4 +18,4 @@ object CronD {
|
|||
delay(60_000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,4 @@ interface MessageFeature {
|
|||
|
||||
interface EventFeature {
|
||||
fun register(api: DiscordApi)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,19 @@ class TimeoutFeature(raw: RawTimeoutFeature) : MessageFeature {
|
|||
?: throw IllegalArgumentException("No timeout role defined")
|
||||
|
||||
override fun handle(message: MessageCreateEvent) {
|
||||
val (target, time) = message.readableMessageContent.split(' ', limit = 3).let {
|
||||
if (it.size != 3) {
|
||||
message.channel.sendMessage("Error: expected “<command> <user> <time>”. If the name contains spaces, please use the user ID instead.")
|
||||
val timeout = message.readableMessageContent.split(' ', limit = 4).let { args ->
|
||||
if (args.size < 3) {
|
||||
message.channel.sendMessage("Error: expected “<command> <user> <time> [<reason>]”. If the name contains spaces, please use the user ID instead.")
|
||||
return
|
||||
}
|
||||
val time = it[2].toLongOrNull()
|
||||
val time = args[2].toLongOrNull()
|
||||
if (time == null) {
|
||||
message.channel.sendMessage("Error: malformed time")
|
||||
return
|
||||
}
|
||||
Pair(it[1], time)
|
||||
ParsedTimeout(args[1], time, args.getOrNull(3))
|
||||
}
|
||||
findUser(target)?.let { user ->
|
||||
findUser(timeout.target)?.let { user ->
|
||||
val oldRoles = user.getRoles(Config.server)
|
||||
.filter { !it.isManaged }
|
||||
.map { role ->
|
||||
|
@ -38,13 +38,16 @@ class TimeoutFeature(raw: RawTimeoutFeature) : MessageFeature {
|
|||
role.id
|
||||
}
|
||||
user.addRole(timeoutRole)
|
||||
val releaseTime = Instant.now().plus(Duration.ofMinutes(time)).epochSecond
|
||||
val releaseTime = Instant.now().plus(Duration.ofMinutes(timeout.duration)).epochSecond
|
||||
Dao.saveTimeout(releaseTime, listOf(user.id) + oldRoles)
|
||||
user.sendEmbed {
|
||||
addField("Timeout", Config.localization.timeout.replace("@@", time.toString()))
|
||||
addField("Timeout", Config.localization.timeout.replace("@@", timeout.duration.toString()))
|
||||
timeout.reason?.let {
|
||||
addField("Reason", it)
|
||||
}
|
||||
}
|
||||
Log.info("Removed roles ${oldRoles.joinToString()} from user ${user.discriminatedName}")
|
||||
} ?: message.channel.sendMessage("Could not find user $target. Consider using the user ID.")
|
||||
} ?: message.channel.sendMessage("Could not find user ${timeout.target}. Consider using the user ID.")
|
||||
}
|
||||
|
||||
fun checkAndRelease() {
|
||||
|
@ -77,4 +80,6 @@ class UserInTimeout(private val id: Long, private val roles: List<Long>) {
|
|||
return UserInTimeout(userId, roles)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ParsedTimeout(val target: String, val duration: Long, val reason: String?)
|
||||
|
|
|
@ -65,7 +65,8 @@ object TestUtil {
|
|||
|
||||
fun prepareTestEnvironment(
|
||||
sentEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
||||
sentMessages: MutableList<String> = mutableListOf()
|
||||
sentMessages: MutableList<String> = mutableListOf(),
|
||||
dmEmbeds: MutableList<EmbedBuilder> = mutableListOf()
|
||||
) {
|
||||
val channel = mockk<Optional<ServerTextChannel>>(relaxed = true) {
|
||||
every { isPresent } returns true
|
||||
|
@ -87,6 +88,7 @@ object TestUtil {
|
|||
every { getMembersByName(any()) } returns listOf(mockk(relaxed = true) {
|
||||
every { id } returns 123
|
||||
every { getRoles(any()) } returns listOf(TEST_ROLE)
|
||||
every { sendMessage(capture(dmEmbeds)) } returns mockk()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import moe.kageru.kagebot.Kagebot.process
|
|||
import moe.kageru.kagebot.TestUtil
|
||||
import moe.kageru.kagebot.TestUtil.TEST_ROLE
|
||||
import moe.kageru.kagebot.persistence.Dao
|
||||
import org.javacord.api.entity.message.embed.EmbedBuilder
|
||||
|
||||
class TimeoutFeatureTest : StringSpec({
|
||||
TestUtil.prepareTestEnvironment()
|
||||
|
@ -17,6 +18,16 @@ class TimeoutFeatureTest : StringSpec({
|
|||
val user = Dao.deleteTimeout(it.first())
|
||||
user shouldBe arrayOf(123, TEST_ROLE.id)
|
||||
}
|
||||
clearTimeouts()
|
||||
}
|
||||
"should announce timeout via DM" {
|
||||
val dms = mutableListOf<EmbedBuilder>()
|
||||
TestUtil.prepareTestEnvironment(dmEmbeds = dms)
|
||||
val time = "1235436"
|
||||
TestUtil.mockMessage("!timeout kageru $time").process()
|
||||
dms.size shouldBe 1
|
||||
TestUtil.embedToString(dms[0]) shouldContain time
|
||||
clearTimeouts()
|
||||
}
|
||||
"should return error for invalid input" {
|
||||
val replies = mutableListOf<String>()
|
||||
|
@ -30,4 +41,21 @@ class TimeoutFeatureTest : StringSpec({
|
|||
replies.size shouldBe 1
|
||||
replies[0] shouldContain "Error"
|
||||
}
|
||||
})
|
||||
"should print optional reason" {
|
||||
val dms = mutableListOf<EmbedBuilder>()
|
||||
TestUtil.prepareTestEnvironment(dmEmbeds = dms)
|
||||
val reason = "because I don’t like you"
|
||||
TestUtil.mockMessage("!timeout kageru 1 $reason").process()
|
||||
dms.size shouldBe 1
|
||||
TestUtil.embedToString(dms[0]) shouldContain reason
|
||||
clearTimeouts()
|
||||
}
|
||||
}) {
|
||||
companion object {
|
||||
private fun clearTimeouts() {
|
||||
Dao.getAllTimeouts().forEach { to ->
|
||||
Dao.deleteTimeout(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ color = "#1793d0"
|
|||
permissionDenied = "no permissions"
|
||||
redirectedMessage = "says"
|
||||
messageDeleted = "message dongered"
|
||||
timeout = "timeout"
|
||||
timeout = "timeout @@ minutes"
|
||||
|
||||
[feature.welcome]
|
||||
fallbackChannel = "123"
|
||||
|
@ -31,4 +31,4 @@ feature = "welcome"
|
|||
|
||||
[[command]]
|
||||
trigger = "!timeout"
|
||||
feature = "timeout"
|
||||
feature = "timeout"
|
||||
|
|
Loading…
Reference in New Issue
Block a user