diff --git a/build.gradle.kts b/build.gradle.kts index 7191f392..a6843a23 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,6 +40,13 @@ kotlin { implementation("com.pubnub:pubnub-kotlin-impl:9.2-DEV") } } + + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + implementation("com.pubnub:pubnub-kotlin-test") + } + } } if (enableAnyIosTarget) { diff --git a/pubnub-chat-api/api/pubnub-chat-api.api b/pubnub-chat-api/api/pubnub-chat-api.api index 197926e5..7bc2f7cd 100644 --- a/pubnub-chat-api/api/pubnub-chat-api.api +++ b/pubnub-chat-api/api/pubnub-chat-api.api @@ -180,6 +180,7 @@ public abstract interface class com/pubnub/chat/Message { public abstract fun pin ()Lcom/pubnub/kmp/PNFuture; public abstract fun removeThread ()Lcom/pubnub/kmp/PNFuture; public abstract fun report (Ljava/lang/String;)Lcom/pubnub/kmp/PNFuture; + public abstract fun restore ()Lcom/pubnub/kmp/PNFuture; public abstract fun streamUpdates (Lkotlin/jvm/functions/Function1;)Ljava/lang/AutoCloseable; public abstract fun toggleReaction (Ljava/lang/String;)Lcom/pubnub/kmp/PNFuture; } diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Message.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Message.kt index a50d087b..b46a7638 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Message.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Message.kt @@ -56,5 +56,7 @@ interface Message { // todo do we want to have test for this? fun streamUpdates(callback: (message: T) -> Unit): AutoCloseable + fun restore(): PNFuture + companion object } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatImpl.kt index 18f44774..73c3a353 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatImpl.kt @@ -8,6 +8,7 @@ import com.pubnub.api.models.consumer.PNBoundedPage import com.pubnub.api.models.consumer.PNPublishResult import com.pubnub.api.models.consumer.history.PNFetchMessageItem import com.pubnub.api.models.consumer.history.PNFetchMessagesResult +import com.pubnub.api.models.consumer.message_actions.PNMessageAction import com.pubnub.api.models.consumer.message_actions.PNRemoveMessageActionResult import com.pubnub.api.models.consumer.objects.PNKey import com.pubnub.api.models.consumer.objects.PNMembershipKey @@ -70,6 +71,7 @@ import com.pubnub.chat.internal.error.PubNubErrorMessage.THERE_IS_NO_ACTION_TIME import com.pubnub.chat.internal.error.PubNubErrorMessage.THERE_IS_NO_THREAD_TO_BE_DELETED import com.pubnub.chat.internal.error.PubNubErrorMessage.THERE_IS_NO_THREAD_WITH_ID import com.pubnub.chat.internal.error.PubNubErrorMessage.THIS_MESSAGE_IS_NOT_A_THREAD +import com.pubnub.chat.internal.error.PubNubErrorMessage.THIS_THREAD_ID_ALREADY_RESTORED import com.pubnub.chat.internal.error.PubNubErrorMessage.THREAD_FOR_THIS_MESSAGE_ALREADY_EXISTS import com.pubnub.chat.internal.error.PubNubErrorMessage.USER_ID_ALREADY_EXIST import com.pubnub.chat.internal.error.PubNubErrorMessage.USER_NOT_EXIST @@ -178,6 +180,27 @@ class ChatImpl( type = user.type ) + override fun restoreThreadChannel(message: Message): PNFuture { + val threadChannelId = getThreadId(message.channelId, message.timetoken) + return getChannel(threadChannelId).thenAsync { channel: Channel? -> + if (channel == null) { + null.asFuture() + } else { + if (message.actions?.get(THREAD_ROOT_ID)?.get(threadChannelId)?.isNotEmpty() == true) { + log.pnError(THIS_THREAD_ID_ALREADY_RESTORED) + } + + val messageAction = PNMessageAction( + type = THREAD_ROOT_ID, + value = threadChannelId, + messageTimetoken = message.timetoken + ) + pubNub.addMessageAction(channel = message.channelId, messageAction = messageAction) + // we don't update action map here but we do this in message#restore() + } + } + } + override fun createUser( id: String, name: String?, @@ -201,6 +224,34 @@ class ChatImpl( } } + override fun removeThreadChannel( + chat: Chat, + message: Message, + soft: Boolean + ): PNFuture> { + if (!message.hasThread) { + return PubNubException(THERE_IS_NO_THREAD_TO_BE_DELETED).logErrorAndReturnException(log).asFuture() + } + + val threadId = getThreadId(message.channelId, message.timetoken) + + val actionTimetoken = + message.actions?.get(THREAD_ROOT_ID)?.get(threadId)?.get(0)?.actionTimetoken + ?: return PubNubException(THERE_IS_NO_ACTION_TIMETOKEN_CORRESPONDING_TO_THE_THREAD).logErrorAndReturnException( + log + ).asFuture() + + return chat.getChannel(threadId).thenAsync { threadChannel -> + if (threadChannel == null) { + log.pnError("$THERE_IS_NO_THREAD_WITH_ID$threadId") + } + awaitAll( + chat.pubNub.removeMessageAction(message.channelId, message.timetoken, actionTimetoken), + threadChannel.delete(soft) + ) + } + } + override fun getUser(userId: String): PNFuture { if (!isValidId(userId)) { return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() @@ -1118,34 +1169,6 @@ class ChatImpl( ).asFuture() } } - - internal fun removeThreadChannel( - chat: Chat, - message: Message, - soft: Boolean = false - ): PNFuture> { - if (!message.hasThread) { - return PubNubException(THERE_IS_NO_THREAD_TO_BE_DELETED).logErrorAndReturnException(log).asFuture() - } - - val threadId = getThreadId(message.channelId, message.timetoken) - - val actionTimetoken = - message.actions?.get("threadRootId")?.get(threadId)?.get(0)?.actionTimetoken - ?: return PubNubException(THERE_IS_NO_ACTION_TIMETOKEN_CORRESPONDING_TO_THE_THREAD).logErrorAndReturnException( - log - ).asFuture() - - return chat.getChannel(threadId).thenAsync { threadChannel -> - if (threadChannel == null) { - log.pnError("$THERE_IS_NO_THREAD_WITH_ID$threadId") - } - awaitAll( - chat.pubNub.removeMessageAction(message.channelId, message.timetoken, actionTimetoken), - threadChannel.delete(soft) - ) - } - } } private fun storeUserActivityTimestamp(): PNFuture { diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatInternal.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatInternal.kt index b10e47ec..976cb692 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatInternal.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/ChatInternal.kt @@ -1,6 +1,10 @@ package com.pubnub.chat.internal +import com.pubnub.api.models.consumer.message_actions.PNMessageAction +import com.pubnub.api.models.consumer.message_actions.PNRemoveMessageActionResult +import com.pubnub.chat.Channel import com.pubnub.chat.Chat +import com.pubnub.chat.Message import com.pubnub.chat.User import com.pubnub.kmp.PNFuture @@ -9,4 +13,12 @@ interface ChatInternal : Chat { val deleteMessageActionName: String fun createUser(user: User): PNFuture + + fun removeThreadChannel( + chat: Chat, + message: Message, + soft: Boolean = false + ): PNFuture> + + fun restoreThreadChannel(message: Message): PNFuture } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/BaseChannel.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/BaseChannel.kt index b2f6f4d0..51de5b25 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/BaseChannel.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/BaseChannel.kt @@ -770,6 +770,7 @@ abstract class BaseChannel( val newChannel = previousChannel?.plus(message.data) ?: ChannelImpl.fromDTO(chat, message.data) newChannel to newChannelId } + is PNDeleteChannelMetadataEventMessage -> null to message.channel else -> return@createEventListener } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ThreadChannelImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ThreadChannelImpl.kt index 7d32914c..45196f77 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ThreadChannelImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ThreadChannelImpl.kt @@ -10,6 +10,7 @@ import com.pubnub.chat.ThreadMessage import com.pubnub.chat.internal.ChatImpl import com.pubnub.chat.internal.ChatInternal import com.pubnub.chat.internal.DELETED +import com.pubnub.chat.internal.THREAD_ROOT_ID import com.pubnub.chat.internal.error.PubNubErrorMessage.PARENT_CHANNEL_DOES_NOT_EXISTS import com.pubnub.chat.internal.message.ThreadMessageImpl import com.pubnub.chat.internal.util.pnError @@ -74,6 +75,10 @@ data class ThreadChannelImpl( } } + override fun delete(soft: Boolean): PNFuture { + return chat.removeThreadChannel(chat, parentMessage, soft).then { it.second } + } + override fun sendText( text: String, meta: Map?, @@ -93,7 +98,7 @@ data class ThreadChannelImpl( chat.pubNub.addMessageAction( parentMessage.channelId, PNMessageAction( - "threadRootId", + THREAD_ROOT_ID, id, parentMessage.timetoken ) diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/error/PubNubErrorMessage.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/error/PubNubErrorMessage.kt index 1e916723..f69e7351 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/error/PubNubErrorMessage.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/error/PubNubErrorMessage.kt @@ -70,4 +70,6 @@ internal object PubNubErrorMessage { internal const val THREAD_FOR_THIS_MESSAGE_ALREADY_EXISTS = "Thread for this message already exists." internal const val RECEIPT_EVENT_WAS_NOT_SENT_TO_CHANNEL = "Because PAM did not allow it 'receipt' event was not sent to channel: " internal const val ERROR_HANDLING_ONMESSAGE_EVENT = "Error handling onMessage event" + internal const val THIS_MESSAGE_HAS_NOT_BEEN_DELETED = "This message has not been deleted" + internal const val THIS_THREAD_ID_ALREADY_RESTORED = "This thread is already restored" } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/BaseMessage.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/BaseMessage.kt index 8b94f60d..025a4cc0 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/BaseMessage.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/BaseMessage.kt @@ -1,10 +1,14 @@ package com.pubnub.chat.internal.message import com.pubnub.api.JsonElement +import com.pubnub.api.PubNubException import com.pubnub.api.asMap +import com.pubnub.api.endpoints.message_actions.RemoveMessageAction +import com.pubnub.api.models.consumer.PNBoundedPage import com.pubnub.api.models.consumer.PNPublishResult import com.pubnub.api.models.consumer.history.PNFetchMessageItem import com.pubnub.api.models.consumer.message_actions.PNAddMessageActionResult +import com.pubnub.api.models.consumer.message_actions.PNGetMessageActionsResult import com.pubnub.api.models.consumer.message_actions.PNMessageAction import com.pubnub.chat.Channel import com.pubnub.chat.Message @@ -20,10 +24,13 @@ import com.pubnub.chat.internal.THREAD_ROOT_ID import com.pubnub.chat.internal.channel.ChannelImpl import com.pubnub.chat.internal.error.PubNubErrorMessage import com.pubnub.chat.internal.error.PubNubErrorMessage.CANNOT_STREAM_MESSAGE_UPDATES_ON_EMPTY_LIST +import com.pubnub.chat.internal.error.PubNubErrorMessage.THIS_MESSAGE_HAS_NOT_BEEN_DELETED import com.pubnub.chat.internal.serialization.PNDataEncoder +import com.pubnub.chat.internal.util.logWarnAndReturnException import com.pubnub.chat.internal.util.pnError import com.pubnub.chat.types.EventContent import com.pubnub.chat.types.File +import com.pubnub.chat.types.MessageActionType import com.pubnub.chat.types.MessageMentionedUsers import com.pubnub.chat.types.MessageReferencedChannels import com.pubnub.chat.types.QuotedMessage @@ -56,7 +63,7 @@ abstract class BaseMessage( override val text: String get() { val edits = actions?.get(chat.editMessageActionName) ?: return content.text - val flatEdits = edits.mapValues { it.value.first() } + val flatEdits = edits.filterValues { it.isNotEmpty() }.mapValues { it.value.first() } val lastEdit = flatEdits.entries.reduce { acc, entry -> if (acc.value.actionTimetoken > entry.value.actionTimetoken) { acc @@ -68,7 +75,7 @@ abstract class BaseMessage( } override val deleted: Boolean - get() = actions?.get(chat.deleteMessageActionName)?.get(chat.deleteMessageActionName)?.isNotEmpty() ?: false + get() = getDeleteActions() != null override val hasThread: Boolean get() { @@ -84,7 +91,8 @@ abstract class BaseMessage( override val files: List get() = content.files ?: emptyList() - override val reactions get() = actions?.get(com.pubnub.chat.types.MessageActionType.REACTIONS.toString()) ?: emptyMap() + override val reactions: Map> + get() = actions?.get(MessageActionType.REACTIONS.toString()) ?: emptyMap() override val textLinks: List? get() = ( meta?.get( @@ -188,13 +196,14 @@ abstract class BaseMessage( override fun createThread(): PNFuture = ChatImpl.createThreadChannel(chat, this) - override fun removeThread() = ChatImpl.removeThreadChannel(chat, this) + override fun removeThread() = chat.removeThreadChannel(chat, this) override fun toggleReaction(reaction: String): PNFuture { val existingReaction = reactions[reaction]?.find { it.uuid == chat.currentUser.id } - val messageAction = PNMessageAction(com.pubnub.chat.types.MessageActionType.REACTIONS.toString(), reaction, timetoken) + val messageAction = + PNMessageAction(MessageActionType.REACTIONS.toString(), reaction, timetoken) val newActions = if (existingReaction != null) { chat.pubNub.removeMessageAction(channelId, timetoken, existingReaction.actionTimetoken.toLong()) .then { filterAction(actions, messageAction) } @@ -205,7 +214,57 @@ abstract class BaseMessage( return newActions.then { copyWithActions(it) } } + override fun streamUpdates(callback: (message: M) -> Unit): AutoCloseable { + return streamUpdatesOn(listOf(this as M)) { + callback(it.first()) + } + } + + override fun restore(): PNFuture { + val deleteActions: List = getDeleteActions() + ?: return PubNubException(THIS_MESSAGE_HAS_NOT_BEEN_DELETED).logWarnAndReturnException(log).asFuture() + + var updatedActions: Actions? = actions?.filterNot { + it.key == chat.deleteMessageActionName + } + + return deleteActions + .map { removeMessageAction(it.actionTimetoken) } + .awaitAll() + .thenAsync { + // get messageAction for all messages in channel + chat.pubNub.getMessageActions(channel = channelId, page = PNBoundedPage(end = timetoken)) + }.then { pnGetMessageActionsResult: PNGetMessageActionsResult -> + // getMessageAction assigned to this message + val messageActionsForMessage = pnGetMessageActionsResult.actions.filter { it.messageTimetoken == timetoken } + + // update actions map + messageActionsForMessage.forEach { pnMessageAction -> + updatedActions = assignAction(updatedActions, pnMessageAction) + } + }.thenAsync { + chat.restoreThreadChannel(this) + }.then { pnMessageAction: PNMessageAction? -> + // update actions map + pnMessageAction?.let { updatedActions = assignAction(updatedActions, it) } + copyWithActions(updatedActions) + } + } + + private fun removeMessageAction(deleteActionTimetoken: Long): RemoveMessageAction { + return chat.pubNub.removeMessageAction( + channel = channelId, + messageTimetoken = timetoken, + actionTimetoken = deleteActionTimetoken + ) + } + + private fun getDeleteActions(): List? { + return actions?.get(chat.deleteMessageActionName)?.get(chat.deleteMessageActionName) + } + private fun deleteThread(soft: Boolean): PNFuture { + // todo check on server, discuss with Team if (hasThread) { return getThread().thenAsync { it.delete(soft) @@ -222,13 +281,7 @@ abstract class BaseMessage( ) } - internal abstract fun copyWithActions(actions: Actions): T - - override fun streamUpdates(callback: (message: M) -> Unit): AutoCloseable { - return streamUpdatesOn(listOf(this as M)) { - callback(it.first()) - } - } + internal abstract fun copyWithActions(actions: Actions?): T companion object { private val log = logging() @@ -244,7 +297,8 @@ abstract class BaseMessage( val chat = messages.first().chat val listener = createEventListener(chat.pubNub, onMessageAction = { _, event -> val message = - latestMessages.find { it.timetoken == event.messageAction.messageTimetoken } ?: return@createEventListener + latestMessages.find { it.timetoken == event.messageAction.messageTimetoken } + ?: return@createEventListener if (message.channelId != event.channel) { return@createEventListener } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/MessageImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/MessageImpl.kt index ad059309..0d76ee23 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/MessageImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/MessageImpl.kt @@ -35,7 +35,7 @@ data class MessageImpl( referencedChannels = referencedChannels, quotedMessage = quotedMessage ) { - override fun copyWithActions(actions: Actions): Message = copy(actions = actions) + override fun copyWithActions(actions: Actions?): Message = copy(actions = actions) companion object { internal fun fromDTO(chat: ChatInternal, pnMessageResult: PNMessageResult): Message { diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/ThreadMessageImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/ThreadMessageImpl.kt index 2506f26e..3a94ec89 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/ThreadMessageImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/message/ThreadMessageImpl.kt @@ -47,7 +47,7 @@ data class ThreadMessageImpl( quotedMessage = quotedMessage ), ThreadMessage { - override fun copyWithActions(actions: Actions): ThreadMessage = copy(actions = actions) + override fun copyWithActions(actions: Actions?): ThreadMessage = copy(actions = actions) companion object { private val log = logging() diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/util/Utils.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/util/Utils.kt index 89bb96b4..13a3bf64 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/util/Utils.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/util/Utils.kt @@ -31,10 +31,14 @@ internal val PNFetchMessagesResult.channelsUrlDecoded: Map>> = + mapOf("deleted" to mapOf("deleted" to listOf(Action("user1", 1234L)))) + objectUnderTest = MessageImpl( + chat = chat, + timetoken = timetoken, + content = messageContent, + channelId = channelId, + userId = userId, + actions = actionsWithEntryIndicatingThatMessageHasBeenDeleted + ) + every { chat.deleteMessageActionName } returns "DELETED" + + objectUnderTest.restore().async { result: Result -> + assertTrue(result.isFailure) + assertEquals("This message has not been deleted", result.exceptionOrNull()?.message) + println(result) + } + } +} diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/utils/FakeChat.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/utils/FakeChat.kt index 5a1aecf8..2ff1820b 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/utils/FakeChat.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/utils/FakeChat.kt @@ -2,6 +2,8 @@ package com.pubnub.kmp.utils import com.pubnub.api.PubNub import com.pubnub.api.models.consumer.PNPublishResult +import com.pubnub.api.models.consumer.message_actions.PNMessageAction +import com.pubnub.api.models.consumer.message_actions.PNRemoveMessageActionResult import com.pubnub.api.models.consumer.objects.PNKey import com.pubnub.api.models.consumer.objects.PNMembershipKey import com.pubnub.api.models.consumer.objects.PNPage @@ -9,6 +11,7 @@ import com.pubnub.api.models.consumer.objects.PNSortKey import com.pubnub.api.models.consumer.push.PNPushAddChannelResult import com.pubnub.api.models.consumer.push.PNPushRemoveChannelResult import com.pubnub.chat.Channel +import com.pubnub.chat.Chat import com.pubnub.chat.Event import com.pubnub.chat.Message import com.pubnub.chat.ThreadChannel @@ -43,6 +46,14 @@ abstract class FakeChat(override val config: ChatConfiguration, override val pub TODO("Not yet implemented") } + override fun removeThreadChannel( + chat: Chat, + message: Message, + soft: Boolean + ): PNFuture> { + TODO("Not yet implemented") + } + override fun getCurrentUserMentions( startTimetoken: Long?, endTimetoken: Long?, @@ -258,4 +269,8 @@ abstract class FakeChat(override val config: ChatConfiguration, override val pub override fun unregisterAllPushChannels(): PNFuture { TODO("Not yet implemented") } + + override fun restoreThreadChannel(message: Message): PNFuture { + TODO("Not yet implemented") + } } diff --git a/pubnub-kotlin b/pubnub-kotlin index e47ee8d7..22a7566d 160000 --- a/pubnub-kotlin +++ b/pubnub-kotlin @@ -1 +1 @@ -Subproject commit e47ee8d7a3121238755b6e4f2baaa64463c6b606 +Subproject commit 22a7566d8d2faa335c377fbc8ac5422242a1f681 diff --git a/src/jvmTest/kotlin/compubnub/chat/ChatIntegrationTest.kt b/src/jvmTest/kotlin/compubnub/chat/ChatIntegrationTest.kt new file mode 100644 index 00000000..35ef52c6 --- /dev/null +++ b/src/jvmTest/kotlin/compubnub/chat/ChatIntegrationTest.kt @@ -0,0 +1,27 @@ +package compubnub.chat + +import com.pubnub.api.PubNubException +import com.pubnub.api.UserId +import com.pubnub.api.v2.PNConfiguration +import com.pubnub.api.v2.callbacks.Result +import com.pubnub.chat.Chat +import com.pubnub.chat.config.ChatConfiguration +import com.pubnub.chat.config.LogLevel +import com.pubnub.chat.init +import kotlin.test.Test + +class ChatIntegrationTest { + @Test + fun canInitializeChatWithLogLevel() { + val chatConfig = ChatConfiguration(logLevel = LogLevel.OFF) + val pnConfiguration = PNConfiguration.builder(userId = UserId("myUserId"), subscribeKey = "mySubscribeKey").build() + + Chat.init(chatConfig, pnConfiguration).async { result: Result -> + result.onSuccess { chat: Chat -> + println("Chat successfully initialized having logLevel: ${chatConfig.logLevel}") + }.onFailure { exception: PubNubException -> + println("Exception initialising chat: ${exception.message}") + } + } + } +}