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)
|
delay(60_000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,4 @@ interface MessageFeature {
|
||||||
|
|
||||||
interface EventFeature {
|
interface EventFeature {
|
||||||
fun register(api: DiscordApi)
|
fun register(api: DiscordApi)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,19 @@ class TimeoutFeature(raw: RawTimeoutFeature) : MessageFeature {
|
||||||
?: throw IllegalArgumentException("No timeout role defined")
|
?: throw IllegalArgumentException("No timeout role defined")
|
||||||
|
|
||||||
override fun handle(message: MessageCreateEvent) {
|
override fun handle(message: MessageCreateEvent) {
|
||||||
val (target, time) = message.readableMessageContent.split(' ', limit = 3).let {
|
val timeout = message.readableMessageContent.split(' ', limit = 4).let { args ->
|
||||||
if (it.size != 3) {
|
if (args.size < 3) {
|
||||||
message.channel.sendMessage("Error: expected “<command> <user> <time>”. If the name contains spaces, please use the user ID instead.")
|
message.channel.sendMessage("Error: expected “<command> <user> <time> [<reason>]”. If the name contains spaces, please use the user ID instead.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val time = it[2].toLongOrNull()
|
val time = args[2].toLongOrNull()
|
||||||
if (time == null) {
|
if (time == null) {
|
||||||
message.channel.sendMessage("Error: malformed time")
|
message.channel.sendMessage("Error: malformed time")
|
||||||
return
|
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)
|
val oldRoles = user.getRoles(Config.server)
|
||||||
.filter { !it.isManaged }
|
.filter { !it.isManaged }
|
||||||
.map { role ->
|
.map { role ->
|
||||||
|
@ -38,13 +38,16 @@ class TimeoutFeature(raw: RawTimeoutFeature) : MessageFeature {
|
||||||
role.id
|
role.id
|
||||||
}
|
}
|
||||||
user.addRole(timeoutRole)
|
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)
|
Dao.saveTimeout(releaseTime, listOf(user.id) + oldRoles)
|
||||||
user.sendEmbed {
|
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}")
|
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() {
|
fun checkAndRelease() {
|
||||||
|
@ -77,4 +80,6 @@ class UserInTimeout(private val id: Long, private val roles: List<Long>) {
|
||||||
return UserInTimeout(userId, roles)
|
return UserInTimeout(userId, roles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ParsedTimeout(val target: String, val duration: Long, val reason: String?)
|
||||||
|
|
|
@ -65,7 +65,8 @@ object TestUtil {
|
||||||
|
|
||||||
fun prepareTestEnvironment(
|
fun prepareTestEnvironment(
|
||||||
sentEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
sentEmbeds: MutableList<EmbedBuilder> = mutableListOf(),
|
||||||
sentMessages: MutableList<String> = mutableListOf()
|
sentMessages: MutableList<String> = mutableListOf(),
|
||||||
|
dmEmbeds: MutableList<EmbedBuilder> = mutableListOf()
|
||||||
) {
|
) {
|
||||||
val channel = mockk<Optional<ServerTextChannel>>(relaxed = true) {
|
val channel = mockk<Optional<ServerTextChannel>>(relaxed = true) {
|
||||||
every { isPresent } returns true
|
every { isPresent } returns true
|
||||||
|
@ -87,6 +88,7 @@ object TestUtil {
|
||||||
every { getMembersByName(any()) } returns listOf(mockk(relaxed = true) {
|
every { getMembersByName(any()) } returns listOf(mockk(relaxed = true) {
|
||||||
every { id } returns 123
|
every { id } returns 123
|
||||||
every { getRoles(any()) } returns listOf(TEST_ROLE)
|
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
|
||||||
import moe.kageru.kagebot.TestUtil.TEST_ROLE
|
import moe.kageru.kagebot.TestUtil.TEST_ROLE
|
||||||
import moe.kageru.kagebot.persistence.Dao
|
import moe.kageru.kagebot.persistence.Dao
|
||||||
|
import org.javacord.api.entity.message.embed.EmbedBuilder
|
||||||
|
|
||||||
class TimeoutFeatureTest : StringSpec({
|
class TimeoutFeatureTest : StringSpec({
|
||||||
TestUtil.prepareTestEnvironment()
|
TestUtil.prepareTestEnvironment()
|
||||||
|
@ -17,6 +18,16 @@ class TimeoutFeatureTest : StringSpec({
|
||||||
val user = Dao.deleteTimeout(it.first())
|
val user = Dao.deleteTimeout(it.first())
|
||||||
user shouldBe arrayOf(123, TEST_ROLE.id)
|
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" {
|
"should return error for invalid input" {
|
||||||
val replies = mutableListOf<String>()
|
val replies = mutableListOf<String>()
|
||||||
|
@ -30,4 +41,21 @@ class TimeoutFeatureTest : StringSpec({
|
||||||
replies.size shouldBe 1
|
replies.size shouldBe 1
|
||||||
replies[0] shouldContain "Error"
|
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"
|
permissionDenied = "no permissions"
|
||||||
redirectedMessage = "says"
|
redirectedMessage = "says"
|
||||||
messageDeleted = "message dongered"
|
messageDeleted = "message dongered"
|
||||||
timeout = "timeout"
|
timeout = "timeout @@ minutes"
|
||||||
|
|
||||||
[feature.welcome]
|
[feature.welcome]
|
||||||
fallbackChannel = "123"
|
fallbackChannel = "123"
|
||||||
|
@ -31,4 +31,4 @@ feature = "welcome"
|
||||||
|
|
||||||
[[command]]
|
[[command]]
|
||||||
trigger = "!timeout"
|
trigger = "!timeout"
|
||||||
feature = "timeout"
|
feature = "timeout"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user