diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroup.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroup.kt index 534f9c6..41d560e 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroup.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroup.kt @@ -17,9 +17,13 @@ package love.forte.simbot.component.onebot.v11.core.actor +import love.forte.simbot.ability.DeleteOption +import love.forte.simbot.ability.DeleteSupport +import love.forte.simbot.ability.StandardDeleteOption import love.forte.simbot.common.collectable.Collectable import love.forte.simbot.common.collectable.asCollectable import love.forte.simbot.common.id.ID +import love.forte.simbot.component.onebot.v11.core.api.SetGroupLeaveApi import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.definition.ChatGroup @@ -28,6 +32,9 @@ import love.forte.simbot.message.MessageContent import love.forte.simbot.suspendrunner.ST import love.forte.simbot.suspendrunner.STP import kotlin.coroutines.CoroutineContext +import kotlin.jvm.JvmName +import kotlin.jvm.JvmStatic +import kotlin.jvm.JvmSynthetic /** @@ -38,9 +45,15 @@ import kotlin.coroutines.CoroutineContext * - 来自 Bot relation API * ([OneBotBot.groupRelation][love.forte.simbot.component.onebot.v11.core.bot.OneBotBot.groupRelation]) * + * ## DeleteSupport + * + * [OneBotGroup] 实现 [DeleteSupport], + * [delete] 代表使Bot退出此群或解散群聊。 + * + * * @author ForteScarlet */ -public interface OneBotGroup : ChatGroup { +public interface OneBotGroup : ChatGroup, DeleteSupport { /** * 协程上下文。源自 [OneBotBot], 但是不含 [Job][kotlinx.coroutines.Job]。 */ @@ -82,14 +95,70 @@ public interface OneBotGroup : ChatGroup { @STP override suspend fun botAsMember(): OneBotMember - + /** + * 向此群内发送消息。 + * + * @throws Throwable 任何可能在请求API时产生的异常 + */ @ST override suspend fun send(message: Message): OneBotMessageReceipt + /** + * 向此群内发送消息。 + * + * @throws Throwable 任何可能在请求API时产生的异常 + */ @ST override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt + /** + * 向此群内发送消息。 + * + * @throws Throwable 任何可能在请求API时产生的异常 + */ @ST override suspend fun send(text: String): OneBotMessageReceipt + /** + * 让当前bot退出/离开此群。 + * + * @param options 进行删除行为时的额外属性。 + * 支持: + * - [StandardDeleteOption.IGNORE_ON_FAILURE] + * - [OneBotGroupDeleteOption] 的所有子实现 + * + * @throws Throwable 任何可能在请求API时产生的异常 + */ + @JvmSynthetic + override suspend fun delete(vararg options: DeleteOption) +} + +/** + * 在 [OneBotGroup.delete] 中可选择使用的额外属性。 + */ +public sealed class OneBotGroupDeleteOption : DeleteOption { + /** + * 是否为解散群。如果bot为群主, + * 则需要提供此参数来使 [OneBotGroup.delete] 解散群, + * 否则无法解散或退出。 + * + * 更多参考:[SetGroupLeaveApi] + * + * @see SetGroupLeaveApi + */ + public data object Dismiss : OneBotGroupDeleteOption() + + public companion object { + /** + * 是否为解散群。 + * 更多参考见 [Dismiss]。 + * + * @see Dismiss + */ + @get:JvmStatic + @get:JvmName("dismiss") + public val dismiss: Dismiss + get() = Dismiss + + } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt index fb40139..524c8a4 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMember.kt @@ -17,9 +17,13 @@ package love.forte.simbot.component.onebot.v11.core.actor +import love.forte.simbot.ability.DeleteOption +import love.forte.simbot.ability.DeleteSupport +import love.forte.simbot.ability.StandardDeleteOption import love.forte.simbot.common.id.ID import love.forte.simbot.common.id.literal import love.forte.simbot.component.onebot.v11.common.utils.qqAvatar640 +import love.forte.simbot.component.onebot.v11.core.api.SetGroupKickApi import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.definition.Member @@ -27,6 +31,9 @@ import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent import love.forte.simbot.suspendrunner.ST import kotlin.coroutines.CoroutineContext +import kotlin.jvm.JvmName +import kotlin.jvm.JvmStatic +import kotlin.jvm.JvmSynthetic /** @@ -37,9 +44,14 @@ import kotlin.coroutines.CoroutineContext * - 来自 Group API * ([OneBotGroup.members]) * + * ## DeleteSupport + * + * [OneBotMember] 实现 [DeleteSupport], + * [delete] 代表试着踢出这个群成员。 + * * @author ForteScarlet */ -public interface OneBotMember : Member { +public interface OneBotMember : Member, DeleteSupport { /** * 协程上下文。源自 [OneBotBot], 但是不含 [Job][kotlinx.coroutines.Job]。 */ @@ -62,13 +74,73 @@ public interface OneBotMember : Member { override val avatar: String get() = qqAvatar640(id.literal) + /** + * 向此成员发送消息。 + * + * @throws Throwable 任何可能在请求API时得到的异常 + */ @ST override suspend fun send(text: String): OneBotMessageReceipt + /** + * 向此成员发送消息。 + * + * @throws Throwable 任何可能在请求API时得到的异常 + */ @ST override suspend fun send(message: Message): OneBotMessageReceipt + /** + * 向此成员发送消息。 + * + * @throws Throwable 任何可能在请求API时得到的异常 + */ @ST override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt + /** + * 尝试踢出此群成员,类似于 `kick` 行为。 + * + * @param options 删除时可提供的额外选项。 + * 可用: + * - [StandardDeleteOption.IGNORE_ON_FAILURE] + * - [OneBotMemberDeleteOption] 的所有实现 + * + * @throws Throwable 任何可能在请求API时得到的异常 + */ + @JvmSynthetic + override suspend fun delete(vararg options: DeleteOption) { + StandardDeleteOption + SetGroupKickApi + } +} + +/** + * 在 [OneBotMember.delete] 中可以使用的更多额外属性, + * 大多与 [SetGroupKickApi] 中的属性相关。 + * + * @see OneBotMember.delete + */ +public sealed class OneBotMemberDeleteOption : DeleteOption { + + /** + * 拒绝此人的加群请求,也就是踢出后将其屏蔽。 + * + * @see SetGroupKickApi + */ + public data object RejectRequest : OneBotMemberDeleteOption() + + public companion object { + /** + * 拒绝此人的加群请求,也就是踢出后将其屏蔽。 + * + * @see SetGroupKickApi + * @see RejectRequest + */ + @get:JvmStatic + @get:JvmName("rejectRequest") + public val rejectRequest: RejectRequest + get() = RejectRequest + + } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt index 945dab7..3bc9bd4 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt @@ -17,14 +17,18 @@ package love.forte.simbot.component.onebot.v11.core.actor.internal +import love.forte.simbot.ability.DeleteOption +import love.forte.simbot.ability.StandardDeleteOption import love.forte.simbot.common.collectable.Collectable import love.forte.simbot.common.collectable.flowCollectable import love.forte.simbot.common.id.ID import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup +import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroupDeleteOption import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.api.GetGroupInfoResult import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberInfoApi import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberListApi +import love.forte.simbot.component.onebot.v11.core.api.SetGroupLeaveApi import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.bot.requestDataBy import love.forte.simbot.component.onebot.v11.core.bot.requestResultBy @@ -38,6 +42,7 @@ import love.forte.simbot.component.onebot.v11.message.resolveToOneBotSegmentList import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent import kotlin.coroutines.CoroutineContext +import kotlin.jvm.JvmInline internal abstract class OneBotGroupImpl : OneBotGroup { @@ -92,6 +97,49 @@ internal abstract class OneBotGroupImpl : OneBotGroup { ).requestDataBy(bot).toReceipt(bot) } + override suspend fun delete(vararg options: DeleteOption) { + var mark = DeleteMark() + for (option in options) { + when { + mark.isFull -> break + option == StandardDeleteOption.IGNORE_ON_FAILURE -> mark = mark.ignoreFailure() + option == OneBotGroupDeleteOption.Dismiss -> mark = mark.dismiss() + } + } + + doDelete(mark) + } + + private suspend fun doDelete(mark: DeleteMark) { + kotlin.runCatching { + SetGroupLeaveApi.create( + groupId = id, + isDismiss = mark.isDismiss + ).requestDataBy(bot) + }.onFailure { err -> + if (!mark.isIgnoreFailure) { + throw err + } + } + } + + @JvmInline + internal value class DeleteMark(private val mark: Int = 0) { + fun ignoreFailure(): DeleteMark = DeleteMark(mark or IGNORE_FAILURE_MARK) + fun dismiss(): DeleteMark = DeleteMark(mark or DISMISS_MARK) + + val isIgnoreFailure: Boolean get() = mark and IGNORE_FAILURE_MARK != 0 + val isDismiss: Boolean get() = mark and DISMISS_MARK != 0 + val isFull: Boolean get() = mark == FULL + + private companion object { + const val IGNORE_FAILURE_MARK = 0b01 + const val DISMISS_MARK = 0b10 + + const val FULL = 0b11 + } + } + override fun toString(): String = "OneBotGroup(id=$id, bot=${bot.id})" } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt index b3aa3ef..b5eb75c 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt @@ -17,10 +17,14 @@ package love.forte.simbot.component.onebot.v11.core.actor.internal +import love.forte.simbot.ability.DeleteOption +import love.forte.simbot.ability.StandardDeleteOption import love.forte.simbot.common.id.ID import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember +import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberDeleteOption import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberRole import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberInfoResult +import love.forte.simbot.component.onebot.v11.core.api.SetGroupKickApi import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.bot.requestDataBy import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt @@ -34,10 +38,12 @@ import love.forte.simbot.component.onebot.v11.message.resolveToOneBotSegmentList import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent import kotlin.coroutines.CoroutineContext +import kotlin.jvm.JvmInline internal abstract class OneBotMemberImpl : OneBotMember { protected abstract val bot: OneBotBotImpl + protected abstract val groupId: ID? override suspend fun send(text: String): OneBotMessageReceipt { return sendPrivateTextMsgApi( @@ -64,11 +70,63 @@ internal abstract class OneBotMemberImpl : OneBotMember { ).requestDataBy(bot).toReceipt(bot) } + override suspend fun delete(vararg options: DeleteOption) { + var mark = DeleteMark() + for (option in options) { + when { + mark.isFull -> break + option == StandardDeleteOption.IGNORE_ON_FAILURE -> mark = mark.ignoreFailure() + option == OneBotMemberDeleteOption.RejectRequest -> mark = mark.rejectRequest() + } + } + + doDelete(mark) + } + + private suspend fun doDelete(mark: DeleteMark) { + val groupId = this.groupId + ?: if (mark.isIgnoreFailure) { + return + } else { + error("The group id for current member $this is unknown") + } + + kotlin.runCatching { + SetGroupKickApi.create( + groupId = groupId, + userId = id, + rejectAddRequest = mark.isRejectRequest + ).requestDataBy(bot) + }.onFailure { err -> + if (!mark.isIgnoreFailure) { + throw err + } + } + } + + @JvmInline + internal value class DeleteMark(private val mark: Int = 0) { + fun ignoreFailure(): DeleteMark = DeleteMark(mark or IGNORE_FAILURE_MARK) + fun rejectRequest(): DeleteMark = DeleteMark(mark or REJECT_REQUEST) + + val isIgnoreFailure: Boolean get() = mark and IGNORE_FAILURE_MARK != 0 + val isRejectRequest: Boolean get() = mark and REJECT_REQUEST != 0 + val isFull: Boolean get() = mark == FULL + + private companion object { + const val IGNORE_FAILURE_MARK = 0b01 + const val REJECT_REQUEST = 0b10 + + const val FULL = 0b11 + } + } + override fun toString(): String = "OneBotMember(id=$id, bot=${bot.id})" } internal class OneBotMemberPrivateMessageEventSenderImpl( private val source: PrivateMessageEvent.Sender, + override val groupId: ID?, override val bot: OneBotBotImpl, override val nick: String?, override val role: OneBotMemberRole?, @@ -78,12 +136,14 @@ internal class OneBotMemberPrivateMessageEventSenderImpl( override val id: ID get() = source.userId + override val name: String get() = source.nickname } internal class OneBotMemberGroupMessageEventSenderImpl( private val source: GroupMessageEvent.Sender, + override val groupId: ID?, override val bot: OneBotBotImpl, ) : OneBotMemberImpl() { override val coroutineContext: CoroutineContext = bot.subContext @@ -104,11 +164,13 @@ internal class OneBotMemberGroupMessageEventSenderImpl( internal fun PrivateMessageEvent.Sender.toMember( bot: OneBotBotImpl, + groupId: ID? = null, nick: String? = null, role: OneBotMemberRole? = null, ): OneBotMemberPrivateMessageEventSenderImpl = OneBotMemberPrivateMessageEventSenderImpl( source = this, + groupId = groupId, bot = bot, nick = nick, role = role @@ -116,9 +178,11 @@ internal fun PrivateMessageEvent.Sender.toMember( internal fun GroupMessageEvent.Sender.toMember( bot: OneBotBotImpl, + groupId: ID, ): OneBotMemberGroupMessageEventSenderImpl = OneBotMemberGroupMessageEventSenderImpl( source = this, + groupId = groupId, bot = bot, ) @@ -131,6 +195,9 @@ internal class OneBotMemberApiResultImpl( override val id: ID get() = source.userId + override val groupId: ID + get() = source.groupId + override val name: String get() = source.nickname diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt index d13e525..97a599c 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt @@ -100,7 +100,7 @@ internal class OneBotNormalGroupMessageEventImpl( ) : OneBotGroupMessageEventImpl(sourceEvent, bot), OneBotNormalGroupMessageEvent { override suspend fun author(): OneBotMember { - return sourceEvent.sender.toMember(bot) + return sourceEvent.sender.toMember(bot, sourceEvent.groupId) } override fun toString(): String = eventToString("OneBotNormalGroupMessageEvent") @@ -114,7 +114,7 @@ internal class OneBotAnonymousGroupMessageEventImpl( ) : OneBotGroupMessageEventImpl(sourceEvent, bot), OneBotAnonymousGroupMessageEvent { override suspend fun author(): OneBotMember { - return sourceEvent.sender.toMember(bot) + return sourceEvent.sender.toMember(bot, sourceEvent.groupId) } override fun toString(): String = eventToString("OneBotAnonymousGroupMessageEvent") diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt index 9c1e9e6..321d88d 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt @@ -107,12 +107,11 @@ internal class OneBotGroupPrivateMessageEventImpl( ) : OneBotPrivateMessageEventImpl(sourceEvent, bot), OneBotGroupPrivateMessageEvent { override suspend fun content(): OneBotMember { - return sourceEvent.sender.toMember(bot) + return sourceEvent.sender.toMember(bot, groupId = null) // group id is unknown. } override suspend fun source(): OneBotGroup { // TODO 额,怎么知道群号? - // 无法得知群号 throw UnsupportedOperationException("The way to get the group number from PrivateMessageEvent is unknown.") } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroupDeleteTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroupDeleteTests.kt new file mode 100644 index 0000000..cad8a9e --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotGroupDeleteTests.kt @@ -0,0 +1,60 @@ +package love.forte.simbot.component.onebot.v11.core.actor + +import io.ktor.client.* +import io.ktor.client.engine.mock.* +import io.ktor.utils.io.core.* +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.booleanOrNull +import kotlinx.serialization.json.jsonPrimitive +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.component.onebot.v11.core.actor.internal.OneBotGroupImpl +import love.forte.simbot.component.onebot.v11.core.api.SetGroupLeaveApi +import love.forte.simbot.component.onebot.v11.core.api.requestData +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + + +/** + * + * @author ForteScarlet + */ +class OneBotGroupDeleteTests { + + @Test + fun oneBotGroupDeleteMarkTest() { + var mark = OneBotGroupImpl.DeleteMark() + assertFalse(mark.isDismiss) + assertFalse(mark.isIgnoreFailure) + + mark = mark.dismiss() + assertTrue(mark.isDismiss) + + mark = mark.ignoreFailure() + assertTrue(mark.isIgnoreFailure) + } + + @Test + fun oneBotGroupDeleteTest() = runTest { + HttpClient( + MockEngine { reqData -> + val json = reqData.body.toByteArray().decodeToString() + val obj = Json.decodeFromString(JsonObject.serializer(), json) + val dismiss = obj["is_dismiss"]?.jsonPrimitive?.booleanOrNull + assertNotNull(dismiss) + assertTrue(dismiss) + respondOk("""{"retcode":0,"status":null,"data":null}""") + } + ).use { client -> + SetGroupLeaveApi.create(123.ID, isDismiss = true).requestData( + client, + "127.0.0.1" + ) + } + + } + +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMemberDeleteTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMemberDeleteTests.kt new file mode 100644 index 0000000..0216815 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonTest/kotlin/love/forte/simbot/component/onebot/v11/core/actor/OneBotMemberDeleteTests.kt @@ -0,0 +1,60 @@ +package love.forte.simbot.component.onebot.v11.core.actor + +import io.ktor.client.* +import io.ktor.client.engine.mock.* +import io.ktor.utils.io.core.* +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.booleanOrNull +import kotlinx.serialization.json.jsonPrimitive +import love.forte.simbot.common.id.UIntID.Companion.ID +import love.forte.simbot.common.id.ULongID.Companion.ID +import love.forte.simbot.component.onebot.v11.core.actor.internal.OneBotMemberImpl +import love.forte.simbot.component.onebot.v11.core.api.SetGroupKickApi +import love.forte.simbot.component.onebot.v11.core.api.requestData +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + + +/** + * + * @author ForteScarlet + */ +class OneBotMemberDeleteTests { + @Test + fun oneBotMemberDeleteMarkTest() { + var mark = OneBotMemberImpl.DeleteMark() + assertFalse(mark.isRejectRequest) + assertFalse(mark.isIgnoreFailure) + + mark = mark.rejectRequest() + assertTrue(mark.isRejectRequest) + + mark = mark.ignoreFailure() + assertTrue(mark.isIgnoreFailure) + } + + @Test + fun oneBotMemberDeleteTest() = runTest { + HttpClient( + MockEngine { reqData -> + val json = reqData.body.toByteArray().decodeToString() + val obj = Json.decodeFromString(JsonObject.serializer(), json) + val rejectRequest = obj["reject_add_request"]?.jsonPrimitive?.booleanOrNull + assertNotNull(rejectRequest) + assertTrue(rejectRequest) + respondOk("""{"retcode":0,"status":null,"data":null}""") + } + ).use { client -> + SetGroupKickApi.create(ULong.MAX_VALUE.ID, UInt.MAX_VALUE.ID, rejectAddRequest = true).requestData( + client, + "127.0.0.1" + ) + } + + } + +}