diff --git a/pubnub-chat-api/api/pubnub-chat-api.api b/pubnub-chat-api/api/pubnub-chat-api.api index f1b392c9..1a93230d 100644 --- a/pubnub-chat-api/api/pubnub-chat-api.api +++ b/pubnub-chat-api/api/pubnub-chat-api.api @@ -253,19 +253,18 @@ public final class com/pubnub/chat/User$DefaultImpls { public abstract interface class com/pubnub/chat/config/ChatConfiguration { public abstract fun getCustomPayloads ()Lcom/pubnub/chat/config/CustomPayloads; - public abstract fun getErrorLogger ()Ljava/lang/Object; + public abstract fun getLogLevel ()Lcom/pubnub/chat/config/LogLevel; public abstract fun getPushNotifications ()Lcom/pubnub/chat/config/PushNotificationsConfig; public abstract fun getRateLimitFactor ()I public abstract fun getRateLimitPerChannel ()Ljava/util/Map; - public abstract fun getSaveDebugLog ()Z public abstract fun getStoreUserActivityInterval-UwyO8pc ()J public abstract fun getStoreUserActivityTimestamps ()Z public abstract fun getTypingTimeout-UwyO8pc ()J } public final class com/pubnub/chat/config/ChatConfigurationKt { - public static final fun ChatConfiguration-ZH2SSTU (ZJJZLcom/pubnub/chat/config/PushNotificationsConfig;ILjava/util/Map;Ljava/lang/Object;Lcom/pubnub/chat/config/CustomPayloads;)Lcom/pubnub/chat/config/ChatConfiguration; - public static synthetic fun ChatConfiguration-ZH2SSTU$default (ZJJZLcom/pubnub/chat/config/PushNotificationsConfig;ILjava/util/Map;Ljava/lang/Object;Lcom/pubnub/chat/config/CustomPayloads;ILjava/lang/Object;)Lcom/pubnub/chat/config/ChatConfiguration; + public static final fun ChatConfiguration-QkTvx9o (Lcom/pubnub/chat/config/LogLevel;JJZLcom/pubnub/chat/config/PushNotificationsConfig;ILjava/util/Map;Lcom/pubnub/chat/config/CustomPayloads;)Lcom/pubnub/chat/config/ChatConfiguration; + public static synthetic fun ChatConfiguration-QkTvx9o$default (Lcom/pubnub/chat/config/LogLevel;JJZLcom/pubnub/chat/config/PushNotificationsConfig;ILjava/util/Map;Lcom/pubnub/chat/config/CustomPayloads;ILjava/lang/Object;)Lcom/pubnub/chat/config/ChatConfiguration; public static final fun RateLimitPerChannel-InTURus (JJJJ)Ljava/util/Map; public static synthetic fun RateLimitPerChannel-InTURus$default (JJJJILjava/lang/Object;)Ljava/util/Map; } @@ -280,6 +279,18 @@ public final class com/pubnub/chat/config/CustomPayloads { public final fun getGetMessageResponseBody ()Lkotlin/jvm/functions/Function1; } +public final class com/pubnub/chat/config/LogLevel : java/lang/Enum { + public static final field DEBUG Lcom/pubnub/chat/config/LogLevel; + public static final field ERROR Lcom/pubnub/chat/config/LogLevel; + public static final field INFO Lcom/pubnub/chat/config/LogLevel; + public static final field OFF Lcom/pubnub/chat/config/LogLevel; + public static final field VERBOSE Lcom/pubnub/chat/config/LogLevel; + public static final field WARN Lcom/pubnub/chat/config/LogLevel; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Lcom/pubnub/chat/config/LogLevel; + public static fun values ()[Lcom/pubnub/chat/config/LogLevel; +} + public final class com/pubnub/chat/config/PushNotificationsConfig { public fun (ZLjava/lang/String;Lcom/pubnub/api/enums/PNPushType;Ljava/lang/String;Lcom/pubnub/api/enums/PNPushEnvironment;)V public final fun getApnsEnvironment ()Lcom/pubnub/api/enums/PNPushEnvironment; diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/CustomPayloads.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/CustomPayloads.kt index 96d8b80a..fb16273c 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/CustomPayloads.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/CustomPayloads.kt @@ -5,7 +5,9 @@ import com.pubnub.chat.types.EventContent class CustomPayloads( val getMessagePublishBody: ((m: EventContent.TextMessageContent, channelId: String) -> Map)? = null, - val getMessageResponseBody: ((m: JsonElement) -> EventContent.TextMessageContent)? = null, // todo do we have tests that checks this functionality + val getMessageResponseBody: ( + (m: JsonElement) -> EventContent.TextMessageContent + )? = null, // todo do we have tests that checks this functionality val editMessageActionName: String? = null, val deleteMessageActionName: String? = null, ) diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/LogLevel.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/LogLevel.kt index ece6ea15..c6609e95 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/LogLevel.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/config/LogLevel.kt @@ -1,5 +1,10 @@ package com.pubnub.chat.config enum class LogLevel { - OFF, ERROR, WARN, INFO, DEBUG, VERBOSE + OFF, + ERROR, + WARN, + INFO, + DEBUG, + VERBOSE } 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 34b09363..2edef962 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 @@ -189,7 +189,7 @@ class ChatImpl( type: String?, ): PNFuture { if (!isValidId(id)) { - log.pnError(ID_IS_REQUIRED) + return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() } return getUser(id).thenAsync { user: User? -> @@ -203,14 +203,14 @@ class ChatImpl( override fun getUser(userId: String): PNFuture { if (!isValidId(userId)) { - log.pnError(ID_IS_REQUIRED) + return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() } return pubNub.getUUIDMetadata(uuid = userId, includeCustom = true) .then { pnUUIDMetadataResult: PNUUIDMetadataResult -> pnUUIDMetadataResult.data?.let { pnUUIDMetadata -> UserImpl.fromDTO(this, pnUUIDMetadata) - } ?: log.pnError(PNUUID_METADATA_RESULT_IS_NULL) + } ?: log.pnError(PNUUID_METADATA_RESULT_IS_NULL) }.catch { if (it is PubNubException && it.statusCode == HTTP_ERROR_404) { Result.success(null) @@ -259,7 +259,7 @@ class ChatImpl( type: String? ): PNFuture { if (!isValidId(id)) { - log.pnError(ID_IS_REQUIRED) + return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() } return getUser(id).thenAsync { user -> @@ -283,15 +283,13 @@ class ChatImpl( } else { performUserDelete(notNullUser) } - } ?: run { - log.pnError(USER_NOT_EXIST) - } + } ?: log.pnError(USER_NOT_EXIST) } } override fun wherePresent(userId: String): PNFuture> { if (!isValidId(userId)) { - log.pnError(ID_IS_REQUIRED) + return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() } return pubNub.whereNow(uuid = userId).then { pnWhereNowResult -> @@ -308,10 +306,10 @@ class ChatImpl( override fun isPresent(userId: String, channelId: String): PNFuture { if (!isValidId(userId)) { - log.pnError("$ID_IS_REQUIRED$channelId") + return log.logErrorAndReturnException(ID_IS_REQUIRED).asFuture() } if (!isValidId(channelId)) { - log.pnError("$CHANNEL_ID_IS_REQUIRED$channelId") + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return pubNub.whereNow(uuid = userId).then { pnWhereNowResult -> @@ -330,7 +328,7 @@ class ChatImpl( status: String? ): PNFuture { if (!isValidId(id)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return getChannel(id).thenAsync { channel: Channel? -> if (channel != null) { @@ -371,15 +369,13 @@ class ChatImpl( override fun getChannel(channelId: String): PNFuture { if (!isValidId(channelId)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return pubNub.getChannelMetadata(channel = channelId) .then { pnChannelMetadataResult: PNChannelMetadataResult -> pnChannelMetadataResult.data?.let { pnChannelMetadata: PNChannelMetadata -> ChannelImpl.fromDTO(this, pnChannelMetadata) - } ?: run { - log.pnError(PNCHANNEL_METADATA_IS_NULL) - } + } ?: log.pnError(PNCHANNEL_METADATA_IS_NULL) }.catch { exception -> if (exception is PubNubException && exception.statusCode == HTTP_ERROR_404) { Result.success(null) @@ -398,7 +394,7 @@ class ChatImpl( type: ChannelType? ): PNFuture { if (!isValidId(id)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return getChannel(id).thenAsync { channel: Channel? -> @@ -412,7 +408,7 @@ class ChatImpl( override fun deleteChannel(id: String, soft: Boolean): PNFuture { if (!isValidId(id)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return getChannelData(id).thenAsync { channel: Channel -> @@ -426,10 +422,10 @@ class ChatImpl( override fun forwardMessage(message: Message, channelId: String): PNFuture { if (!isValidId(channelId)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } if (message.channelId == channelId) { - log.pnError(CANNOT_FORWARD_MESSAGE_TO_THE_SAME_CHANNEL) + return log.logErrorAndReturnException(CANNOT_FORWARD_MESSAGE_TO_THE_SAME_CHANNEL).asFuture() } val meta = message.meta?.toMutableMap() ?: mutableMapOf() @@ -572,7 +568,7 @@ class ChatImpl( override fun whoIsPresent(channelId: String): PNFuture> { if (!isValidId(channelId)) { - log.pnError(CHANNEL_ID_IS_REQUIRED) + return log.logErrorAndReturnException(CHANNEL_ID_IS_REQUIRED).asFuture() } return pubNub.hereNow(listOf(channelId)).then { (it.channels[channelId]?.occupants?.map(PNHereNowOccupantData::uuid) ?: emptyList()) @@ -729,9 +725,7 @@ class ChatImpl( pnMessageCountResult.channels.map { (channelId, messageCount) -> val membershipMatchingChannel = memberships.find { membership: Membership -> membership.channel.id == channelId } - ?: run { - log.pnError("$CAN_NOT_FIND_CHANNEL_WITH_ID$channelId") - } + ?: log.pnError("$CAN_NOT_FIND_CHANNEL_WITH_ID$channelId") GetUnreadMessagesCounts( channel = membershipMatchingChannel.channel, membership = membershipMatchingChannel, @@ -894,7 +888,7 @@ class ChatImpl( count: Int ): PNFuture { if (count > 100) { - log.pnError(COUNT_SHOULD_NOT_EXCEED_100) + return log.logErrorAndReturnException(COUNT_SHOULD_NOT_EXCEED_100).asFuture() } var isMore = false @@ -960,9 +954,7 @@ class ChatImpl( .then { pnChannelMetadataResult: PNChannelMetadataResult -> pnChannelMetadataResult.data?.let { pnChannelMetadata -> ChannelImpl.fromDTO(this, pnChannelMetadata) - } ?: run { - log.pnError(CHANNEL_META_DATA_IS_EMPTY) - } + } ?: log.pnError(CHANNEL_META_DATA_IS_EMPTY) }.catch { exception -> Result.failure(PubNubException(FAILED_TO_RETRIEVE_CHANNEL_DATA, exception)) } @@ -983,9 +975,7 @@ class ChatImpl( ).then { pnUUIDMetadataResult -> pnUUIDMetadataResult.data?.let { pnUUIDMetadata: PNUUIDMetadata -> UserImpl.fromDTO(this, pnUUIDMetadata) - } ?: run { - log.pnError(PNUUID_METADATA_IS_NULL) - } + } ?: log.pnError(PNUUID_METADATA_IS_NULL) } } @@ -1005,9 +995,7 @@ class ChatImpl( ).then { pnChannelMetadataResult -> pnChannelMetadataResult.data?.let { pnChannelMetadata: PNChannelMetadata -> ChannelImpl.fromDTO(this, pnChannelMetadata) - } ?: run { - log.pnError(PNCHANNEL_METADATA_IS_NULL) - } + } ?: log.pnError(PNCHANNEL_METADATA_IS_NULL) }.catch { exception -> Result.failure(PubNubException(FAILED_TO_SOFT_DELETE_CHANNEL, exception)) } @@ -1035,9 +1023,7 @@ class ChatImpl( ).then { pnChannelMetadataResult -> pnChannelMetadataResult.data?.let { pnChannelMetadata -> ChannelImpl.fromDTO(this, pnChannelMetadata) - } ?: run { - log.pnError(NO_DATA_AVAILABLE_TO_CREATE_OR_UPDATE_CHANNEL) - } + } ?: log.pnError(NO_DATA_AVAILABLE_TO_CREATE_OR_UPDATE_CHANNEL) }.catch { exception -> Result.failure(PubNubException(FAILED_TO_CREATE_UPDATE_CHANNEL_DATA, exception)) } @@ -1097,18 +1083,17 @@ class ChatImpl( internal fun createThreadChannel(chat: ChatInternal, message: Message): PNFuture { if (message.channelId.startsWith(MESSAGE_THREAD_ID_PREFIX)) { - log.pnError(ONLY_ONE_LEVEL_OF_THREAD_NESTING_IS_ALLOWED) + return log.logErrorAndReturnException(ONLY_ONE_LEVEL_OF_THREAD_NESTING_IS_ALLOWED).asFuture() } if (message.deleted) { - log.pnError(YOU_CAN_NOT_CREATE_THREAD_ON_DELETED_MESSAGES) + return log.logErrorAndReturnException(YOU_CAN_NOT_CREATE_THREAD_ON_DELETED_MESSAGES).asFuture() } val threadChannelId = getThreadId(message.channelId, message.timetoken) return chat.getChannel(threadChannelId).thenAsync { it: Channel? -> if (it != null) { - log.info { "Error in createThreadChannel: $THREAD_FOR_THIS_MESSAGE_ALREADY_EXISTS" } - return@thenAsync PubNubException(THREAD_FOR_THIS_MESSAGE_ALREADY_EXISTS).asFuture() + return@thenAsync log.logErrorAndReturnException(THREAD_FOR_THIS_MESSAGE_ALREADY_EXISTS).asFuture() } ThreadChannelImpl( message, @@ -1133,13 +1118,13 @@ class ChatImpl( val actionTimetoken = message.actions?.get("threadRootId")?.get(threadId)?.get(0)?.actionTimetoken - ?: run { - return PubNubException(THERE_IS_NO_ACTION_TIMETOKEN_CORRESPONDING_TO_THE_THREAD).logErrorAndReturnException(log).asFuture() - } + ?: 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) + log.pnError("$THERE_IS_NO_THREAD_WITH_ID$threadId") } awaitAll( chat.pubNub.removeMessageAction(message.channelId, message.timetoken, actionTimetoken), @@ -1179,7 +1164,7 @@ class ChatImpl( runPeriodically(config.storeUserActivityInterval) { saveTimeStampFunc().async { result: Result -> result.onFailure { e -> - log.e(err = e, msg = {e.message}) + log.error(err = e, msg = { e.message }) } } } diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/MembershipImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/MembershipImpl.kt index 3e2d5d54..d62c22ff 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/MembershipImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/MembershipImpl.kt @@ -1,6 +1,5 @@ package com.pubnub.chat.internal -import com.pubnub.api.PubNubException import com.pubnub.api.models.consumer.objects.member.PNMember import com.pubnub.api.models.consumer.objects.membership.PNChannelDetailsLevel import com.pubnub.api.models.consumer.objects.membership.PNChannelMembership diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/UserImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/UserImpl.kt index ce6cd64a..711ebda7 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/UserImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/UserImpl.kt @@ -20,6 +20,7 @@ import com.pubnub.chat.internal.error.PubNubErrorMessage.CAN_NOT_STREAM_USER_UPD import com.pubnub.chat.internal.error.PubNubErrorMessage.MODERATION_CAN_BE_SET_ONLY_BY_CLIENT_HAVING_SECRET_KEY import com.pubnub.chat.internal.error.PubNubErrorMessage.STORE_USER_ACTIVITY_INTERVAL_IS_FALSE import com.pubnub.chat.internal.restrictions.RestrictionImpl +import com.pubnub.chat.internal.util.logErrorAndReturnException import com.pubnub.chat.internal.util.pnError import com.pubnub.chat.membership.IncludeParameters import com.pubnub.chat.membership.MembershipsResponse @@ -115,7 +116,7 @@ data class UserImpl( override fun setRestrictions(channel: Channel, ban: Boolean, mute: Boolean, reason: String?): PNFuture { if (chat.pubNub.configuration.secretKey.isEmpty()) { - log.pnError(MODERATION_CAN_BE_SET_ONLY_BY_CLIENT_HAVING_SECRET_KEY) + return log.logErrorAndReturnException(MODERATION_CAN_BE_SET_ONLY_BY_CLIENT_HAVING_SECRET_KEY).asFuture() } return chat.setRestrictions( Restriction( @@ -170,13 +171,13 @@ data class UserImpl( override fun active(): PNFuture { if (!chat.config.storeUserActivityTimestamps) { - log.pnError(STORE_USER_ACTIVITY_INTERVAL_IS_FALSE) + return log.logErrorAndReturnException(STORE_USER_ACTIVITY_INTERVAL_IS_FALSE).asFuture() } return ( - lastActiveTimestamp?.let { lastActiveTimestampNonNull -> - Clock.System.now() - Instant.fromEpochMilliseconds(lastActiveTimestampNonNull) <= chat.config.storeUserActivityInterval - } ?: false - ).asFuture() + lastActiveTimestamp?.let { lastActiveTimestampNonNull -> + Clock.System.now() - Instant.fromEpochMilliseconds(lastActiveTimestampNonNull) <= chat.config.storeUserActivityInterval + } ?: false + ).asFuture() } override fun report(reason: String): 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 46a89a4c..e8d09768 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 @@ -58,6 +58,7 @@ import com.pubnub.chat.internal.serialization.PNDataEncoder import com.pubnub.chat.internal.timer.PlatformTimer.Companion.runWithDelay import com.pubnub.chat.internal.util.channelsUrlDecoded import com.pubnub.chat.internal.util.getPhraseToLookFor +import com.pubnub.chat.internal.util.logErrorAndReturnException import com.pubnub.chat.internal.util.pnError import com.pubnub.chat.internal.utils.ExponentialRateLimiter import com.pubnub.chat.internal.uuidFilterString @@ -143,7 +144,7 @@ abstract class BaseChannel( override fun startTyping(): PNFuture { if (type == ChannelType.PUBLIC) { - log.pnError(TYPING_INDICATORS_NO_SUPPORTED_IN_PUBLIC_CHATS) + return log.logErrorAndReturnException(TYPING_INDICATORS_NO_SUPPORTED_IN_PUBLIC_CHATS).asFuture() } val now = clock.now() @@ -253,7 +254,7 @@ abstract class BaseChannel( files: List?, ): PNFuture { if (quotedMessage != null && quotedMessage.channelId != id) { - log.pnError(CANNOT_QUOTE_MESSAGE_FROM_OTHER_CHANNELS) + return log.logErrorAndReturnException(CANNOT_QUOTE_MESSAGE_FROM_OTHER_CHANNELS).asFuture() } return sendTextRateLimiter.runWithinLimits( sendFilesForPublish(files).thenAsync { filesData -> @@ -313,7 +314,7 @@ abstract class BaseChannel( override fun invite(user: User): PNFuture { if (this.type == ChannelType.PUBLIC) { - log.pnError(CHANNEL_INVITES_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS) + return log.logErrorAndReturnException(CHANNEL_INVITES_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS).asFuture() } return getMembers(filter = user.uuidFilterString).thenAsync { channelMembers: MembersResponse -> if (channelMembers.members.isNotEmpty()) { @@ -342,7 +343,7 @@ abstract class BaseChannel( override fun inviteMultiple(users: Collection): PNFuture> { if (this.type == ChannelType.PUBLIC) { - log.pnError(CHANNEL_INVITES_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS) + return log.logErrorAndReturnException(CHANNEL_INVITES_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS).asFuture() } return chat.pubNub.setChannelMembers( this.id, @@ -412,7 +413,7 @@ abstract class BaseChannel( } callback(MessageImpl.fromDTO(chat, pnMessageResult)) } catch (e: Exception) { - log.error(err = e, msg= {ERROR_HANDLING_ONMESSAGE_EVENT}) + log.error(err = e, msg = { ERROR_HANDLING_ONMESSAGE_EVENT }) } }, ) @@ -532,7 +533,7 @@ abstract class BaseChannel( reason: String?, ): PNFuture { if (chat.pubNub.configuration.secretKey.isEmpty()) { - log.pnError(MODERATION_CAN_BE_SET_ONLY_BY_CLIENT_HAVING_SECRET_KEY) + return log.logErrorAndReturnException(MODERATION_CAN_BE_SET_ONLY_BY_CLIENT_HAVING_SECRET_KEY).asFuture() } return chat.setRestrictions( Restriction( @@ -703,9 +704,7 @@ abstract class BaseChannel( HistoryResponse( messages = pnFetchMessagesResult.channelsUrlDecoded[channelId]?.map { messageItem: PNFetchMessageItem -> messageFactory(chat, messageItem, channelId) - } ?: run { - log.pnError(UNABLE_TO_READ_MESSAGES) - }, + } ?: log.pnError(UNABLE_TO_READ_MESSAGES), isMore = pnFetchMessagesResult.channelsUrlDecoded[channelId]?.size == count ) }.catch { @@ -818,7 +817,12 @@ abstract class BaseChannel( } } - internal fun updateUserTypingStatus(userId: String, isTyping: Boolean, now: Instant, userLastTyped: MutableMap) { + internal fun updateUserTypingStatus( + userId: String, + isTyping: Boolean, + now: Instant, + userLastTyped: MutableMap + ) { if (isTyping) { userLastTyped[userId] = now } else { 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 491c1ef0..4ace08c5 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,7 +1,6 @@ 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.models.consumer.PNPublishResult import com.pubnub.api.models.consumer.history.PNFetchMessageItem 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 e022a016..e524eb55 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 @@ -51,6 +51,7 @@ data class ThreadMessageImpl( companion object { private val log = logging() + internal fun fromDTO(chat: ChatImpl, pnMessageResult: PNMessageResult, parentChannelId: String): ThreadMessage { return ThreadMessageImpl( chat, 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 fe27e8a1..89bb96b4 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 @@ -24,12 +24,19 @@ internal fun getPhraseToLookFor(text: String, separator: String): String? { internal expect fun urlDecode(encoded: String): String -internal val PNFetchMessagesResult.channelsUrlDecoded: Map> get() = channels.mapKeys { urlDecode(it.key) } +internal val PNFetchMessagesResult.channelsUrlDecoded: Map> + get() = channels.mapKeys { + urlDecode( + it.key + ) + } -inline fun T.logErrorAndReturnException(log: KmLog) = apply { +inline fun PubNubException.logErrorAndReturnException(log: KmLog): PubNubException = apply { log.error(err = this, msg = { this.message.orEmpty() }) } -inline fun pnError(message: String, log: KmLog): Nothing = throw PubNubException(message).logErrorAndReturnException(log) // todo remove - inline fun KmLog.pnError(message: String): Nothing = throw PubNubException(message).logErrorAndReturnException(this) + +inline fun KmLog.logErrorAndReturnException(message: String): PubNubException { + return PubNubException(message).logErrorAndReturnException(this) +} diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/ChannelIntegrationTest.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/ChannelIntegrationTest.kt index cdb9f946..ff8c779b 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/ChannelIntegrationTest.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/ChannelIntegrationTest.kt @@ -2,7 +2,6 @@ package com.pubnub.integration import com.pubnub.api.models.consumer.objects.PNMemberKey import com.pubnub.api.models.consumer.objects.PNSortKey -import com.pubnub.api.v2.callbacks.Result import com.pubnub.chat.Channel import com.pubnub.chat.Membership import com.pubnub.chat.User diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChannelTest.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChannelTest.kt index 866eec71..e93356f4 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChannelTest.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChannelTest.kt @@ -139,11 +139,10 @@ class ChannelTest : BaseTest() { fun whenChannelIsPublicStartTypingShouldResultFailure() { objectUnderTest = createChannel(ChannelType.PUBLIC) - val e = assertFailsWith { - objectUnderTest.startTyping() + objectUnderTest.startTyping().async { resutl -> + assertTrue(resutl.isFailure) + assertEquals("Typing indicators are not supported in Public chats.", resutl.exceptionOrNull()?.message) } - - assertEquals("Typing indicators are not supported in Public chats.", e.message) } @Test @@ -639,10 +638,14 @@ class ChannelTest : BaseTest() { @Test fun shouldThrowExceptionWhenSecretKeyIsNotSet() { val user = UserImpl(chat = chat, id = "userId") - val e = assertFailsWith { - objectUnderTest.setRestrictions(user) + + objectUnderTest.setRestrictions(user).async { result: Result -> + assertTrue(result.isFailure) + assertEquals( + "Moderation restrictions can only be set by clients initialized with a Secret Key.", + result.exceptionOrNull()?.message + ) } - assertEquals("Moderation restrictions can only be set by clients initialized with a Secret Key.", e.message) } @Test diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChatTest.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChatTest.kt index b38e2c62..72a610cd 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChatTest.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/ChatTest.kt @@ -351,11 +351,11 @@ class ChatTest : BaseTest() { val emptyChannelId = "" // when - val e = assertFailsWith { - objectUnderTest.isPresent(id, emptyChannelId) + objectUnderTest.isPresent(id, emptyChannelId).async { result: Result -> + // then + assertTrue(result.isFailure) + assertEquals("Channel Id is required", result.exceptionOrNull()?.message) } - - assertEquals("Channel Id is required", e.message) } @Test @@ -397,11 +397,11 @@ class ChatTest : BaseTest() { val emptyChannelId = "" // when - val e = assertFailsWith { - objectUnderTest.whoIsPresent(emptyChannelId) + objectUnderTest.whoIsPresent(emptyChannelId).async { result: Result> -> + // then + assertTrue(result.isFailure) + assertEquals("Channel Id is required", result.exceptionOrNull()?.message) } - - assertEquals("Channel Id is required", e.message) } @Test @@ -410,11 +410,11 @@ class ChatTest : BaseTest() { val channelId = "" // when - val e = assertFailsWith { - objectUnderTest.updateChannel(id = channelId) + objectUnderTest.updateChannel(id = channelId).async { result: Result -> + // then + assertTrue(result.isFailure) + assertEquals("Channel Id is required", result.exceptionOrNull()?.message) } - - assertEquals("Channel Id is required", e.message) } @Test @@ -597,11 +597,11 @@ class ChatTest : BaseTest() { val message = createMessage() // when - val e = assertFailsWith { - objectUnderTest.forwardMessage(message, channelId) + objectUnderTest.forwardMessage(message, channelId).async { result: Result -> + // then + assertTrue(result.isFailure) + assertEquals("You cannot forward the message to the same channel.", result.exceptionOrNull()!!.message) } - - assertEquals("You cannot forward the message to the same channel.", e.message) } @Test @@ -679,12 +679,10 @@ class ChatTest : BaseTest() { @Test fun whenChannelIdIsEmptyThenGetChannelShouldResultFailure() { val emptyChannelId = "" - - val e = assertFailsWith { - objectUnderTest.getChannel(emptyChannelId) + objectUnderTest.getChannel(emptyChannelId).async { result -> + assertTrue(result.isFailure) + assertEquals("Channel Id is required", result.exceptionOrNull()?.message) } - - assertEquals("Channel Id is required", e.message) } @Test @@ -791,11 +789,10 @@ class ChatTest : BaseTest() { fun whenUserIdIsEmptyThenGetChannelShouldResultFailure() { val emptyUserId = "" - val e = assertFailsWith { - objectUnderTest.getUser(emptyUserId) + objectUnderTest.getUser(emptyUserId).async { result: Result -> + assertTrue(result.isFailure) + assertEquals("Id is required", result.exceptionOrNull()?.message) } - - assertEquals("Id is required", e.message) } @Test @@ -1240,12 +1237,10 @@ class ChatTest : BaseTest() { @Test fun shouldThrowExceptionWhenGetCurrentUserMentionsWithCountBiggerThan100() { - - val e = assertFailsWith { - objectUnderTest.getCurrentUserMentions(count = 200) + objectUnderTest.getCurrentUserMentions(count = 200).async { result -> + assertTrue(result.isFailure) + assertEquals("Count should not exceed 100", result.exceptionOrNull()?.message) } - - assertEquals("Count should not exceed 100", e.message) } @Test diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/UserTest.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/UserTest.kt index 8dc02776..ee5283da 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/UserTest.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/kmp/UserTest.kt @@ -1,7 +1,6 @@ package com.pubnub.kmp import com.pubnub.api.PubNub -import com.pubnub.api.PubNubException import com.pubnub.api.endpoints.objects.membership.GetMemberships import com.pubnub.api.models.consumer.objects.PNMembershipKey import com.pubnub.api.models.consumer.objects.PNPage @@ -29,7 +28,6 @@ import dev.mokkery.verify import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.test.assertFailsWith import kotlin.test.assertTrue import kotlin.time.Duration.Companion.milliseconds @@ -266,9 +264,26 @@ class UserTest { val sort = listOf(PNSortKey.PNAsc(PNMembershipKey.CHANNEL_ID)) val getMemberships: GetMemberships = mock(MockMode.strict) every { chat.pubNub } returns pubNub - every { pubNub.getMemberships(any(), any(), any(), any(), any(), any(), any(), any(), any()) } returns getMemberships + every { + pubNub.getMemberships( + any(), + any(), + any(), + any(), + any(), + any(), + any(), + any(), + any() + ) + } returns getMemberships - (objectUnderTest as UserImpl).getRestrictions(channel = noChannelProvided, limit = limit, page = page, sort = sort) + (objectUnderTest as UserImpl).getRestrictions( + channel = noChannelProvided, + limit = limit, + page = page, + sort = sort + ) val expectedFilter = "channel.id LIKE 'PUBNUB_INTERNAL_MODERATION_*'" verify { @@ -295,7 +310,19 @@ class UserTest { val sort = listOf(PNSortKey.PNAsc(PNMembershipKey.CHANNEL_ID)) val getMemberships: GetMemberships = mock(MockMode.strict) every { chat.pubNub } returns pubNub - every { pubNub.getMemberships(any(), any(), any(), any(), any(), any(), any(), any(), any()) } returns getMemberships + every { + pubNub.getMemberships( + any(), + any(), + any(), + any(), + any(), + any(), + any(), + any(), + any() + ) + } returns getMemberships (objectUnderTest as UserImpl).getRestrictions(channel = channel, limit = limit, page = page, sort = sort) @@ -318,10 +345,13 @@ class UserTest { @Test fun shouldThrowExceptionWhenSecretKeyIsNotSet() { val channel = ChannelImpl(chat = chat, id = "channelId") - val e = assertFailsWith { - objectUnderTest.setRestrictions(channel) + objectUnderTest.setRestrictions(channel).async { result -> + assertTrue(result.isFailure) + assertEquals( + "Moderation restrictions can only be set by clients initialized with a Secret Key.", + result.exceptionOrNull()?.message + ) } - assertEquals("Moderation restrictions can only be set by clients initialized with a Secret Key.", e.message) } private fun getPNChannelMembershipArrayResult(): PNChannelMembershipArrayResult {