diff --git a/pubnub-chat-api/api/pubnub-chat-api.api b/pubnub-chat-api/api/pubnub-chat-api.api index 1a93230d..3b43177f 100644 --- a/pubnub-chat-api/api/pubnub-chat-api.api +++ b/pubnub-chat-api/api/pubnub-chat-api.api @@ -27,6 +27,7 @@ public abstract interface class com/pubnub/chat/Channel { public abstract fun join (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lcom/pubnub/kmp/PNFuture; public abstract fun leave ()Lcom/pubnub/kmp/PNFuture; public abstract fun pinMessage (Lcom/pubnub/chat/Message;)Lcom/pubnub/kmp/PNFuture; + public abstract fun plus (Lcom/pubnub/api/models/consumer/objects/channel/PNChannelMetadata;)Lcom/pubnub/chat/Channel; public abstract fun registerForPush ()Lcom/pubnub/kmp/PNFuture; public abstract fun sendText (Ljava/lang/String;Ljava/util/Map;ZZLjava/lang/Integer;Ljava/util/Map;Ljava/util/Map;Ljava/util/List;Lcom/pubnub/chat/Message;Ljava/util/List;)Lcom/pubnub/kmp/PNFuture; public abstract fun setRestrictions (Lcom/pubnub/chat/User;ZZLjava/lang/String;)Lcom/pubnub/kmp/PNFuture; @@ -233,6 +234,7 @@ public abstract interface class com/pubnub/chat/User { public abstract fun getType ()Ljava/lang/String; public abstract fun getUpdated ()Ljava/lang/String; public abstract fun isPresentOn (Ljava/lang/String;)Lcom/pubnub/kmp/PNFuture; + public abstract fun plus (Lcom/pubnub/api/models/consumer/objects/uuid/PNUUIDMetadata;)Lcom/pubnub/chat/User; public abstract fun report (Ljava/lang/String;)Lcom/pubnub/kmp/PNFuture; public abstract fun setRestrictions (Lcom/pubnub/chat/Channel;ZZLjava/lang/String;)Lcom/pubnub/kmp/PNFuture; public abstract fun streamUpdates (Lkotlin/jvm/functions/Function1;)Ljava/lang/AutoCloseable; diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Channel.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Channel.kt index 135818bd..7387beb6 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Channel.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/Channel.kt @@ -5,6 +5,7 @@ import com.pubnub.api.models.consumer.files.PNDeleteFileResult import com.pubnub.api.models.consumer.objects.PNMemberKey import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.PNSortKey +import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.push.PNPushAddChannelResult import com.pubnub.api.models.consumer.push.PNPushRemoveChannelResult import com.pubnub.chat.membership.MembersResponse @@ -128,7 +129,11 @@ interface Channel { fun getUserSuggestions(text: String, limit: Int = 10): PNFuture> + /** + * Get a new `Channel` instance that is a copy of this `Channel` with its properties updated with information coming from `update`. + */ + operator fun plus(update: PNChannelMetadata): Channel + // Companion object required for extending this class elsewhere - // toDo Is this needed? Where do we extend this? companion object } diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/ThreadChannel.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/ThreadChannel.kt index 7a803efa..ef0c7bcc 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/ThreadChannel.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/ThreadChannel.kt @@ -8,6 +8,7 @@ interface ThreadChannel : Channel { val parentMessage: Message val parentChannelId: String + // TODO change parameter to ThreadMessage override fun pinMessage(message: Message): PNFuture override fun unpinMessage(): PNFuture diff --git a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/User.kt b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/User.kt index 29847938..2d912ff9 100644 --- a/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/User.kt +++ b/pubnub-chat-api/src/commonMain/kotlin/com/pubnub/chat/User.kt @@ -4,6 +4,7 @@ import com.pubnub.api.models.consumer.PNPublishResult import com.pubnub.api.models.consumer.objects.PNMembershipKey import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.PNSortKey +import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata import com.pubnub.chat.membership.MembershipsResponse import com.pubnub.chat.restrictions.GetRestrictionsResponse import com.pubnub.chat.restrictions.Restriction @@ -67,5 +68,10 @@ interface User { fun report(reason: String): PNFuture + /** + * Get a new `User` instance that is a copy of this `User` with its properties updated with information coming from `update`. + */ + operator fun plus(update: PNUUIDMetadata): User + companion object } 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 711ebda7..370dc383 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 @@ -11,6 +11,7 @@ import com.pubnub.api.models.consumer.objects.membership.PNChannelMembershipArra import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteUUIDMetadataEventMessage import com.pubnub.api.models.consumer.pubsub.objects.PNSetUUIDMetadataEventMessage +import com.pubnub.api.utils.PatchValue import com.pubnub.api.v2.callbacks.Result import com.pubnub.chat.Channel import com.pubnub.chat.Membership @@ -189,6 +190,10 @@ data class UserImpl( return chat.emitEvent(channelId = INTERNAL_ADMIN_CHANNEL, payload = payload) } + override operator fun plus(update: PNUUIDMetadata): User { + return fromDTO(chat, toUUIDMetadata() + update) + } + internal fun getRestrictions( channel: Channel?, limit: Int? = null, @@ -234,21 +239,36 @@ data class UserImpl( return memberships } + private fun toUUIDMetadata(): PNUUIDMetadata { + return PNUUIDMetadata( + id = id, + name = name?.let { PatchValue.of(it) }, + externalId = externalId?.let { PatchValue.of(it) }, + profileUrl = profileUrl?.let { PatchValue.of(it) }, + email = email?.let { PatchValue.of(it) }, + custom = custom?.let { PatchValue.of(it) }, + updated = updated?.let { PatchValue.of(it) }, + eTag = null, + type = type?.let { PatchValue.of(it) }, + status = status?.let { PatchValue.of(it) }, + ) + } + companion object { private val log = logging() internal fun fromDTO(chat: ChatInternal, user: PNUUIDMetadata): User = UserImpl( chat, id = user.id, - name = user.name, - externalId = user.externalId, - profileUrl = user.profileUrl, - email = user.email, - custom = user.custom, - updated = user.updated, - status = user.status, - type = user.type, - lastActiveTimestamp = user.custom?.get("lastActiveTimestamp")?.tryLong() + name = user.name?.value, + externalId = user.externalId?.value, + profileUrl = user.profileUrl?.value, + email = user.email?.value, + custom = user.custom?.value, + updated = user.updated?.value, + status = user.status?.value, + type = user.type?.value, + lastActiveTimestamp = user.custom?.value?.get("lastActiveTimestamp")?.tryLong() ) fun streamUpdatesOn(users: Collection, callback: (users: Collection) -> Unit): AutoCloseable { @@ -259,14 +279,25 @@ data class UserImpl( val chat = users.first().chat as ChatInternal val listener = createEventListener(chat.pubNub, onObjects = { pubNub, event -> val (newUser, newUserId) = when (val message = event.extractedMessage) { - is PNSetUUIDMetadataEventMessage -> fromDTO(chat, message.data) to message.data.id + is PNSetUUIDMetadataEventMessage -> { + val newUserId = message.data.id + val previousUser = latestUsers.firstOrNull { it.id == newUserId } + val newUser = previousUser?.plus(message.data) ?: fromDTO(chat, message.data) + newUser to newUserId + } is PNDeleteUUIDMetadataEventMessage -> null to message.uuid else -> return@createEventListener } - latestUsers = latestUsers.asSequence().filter { - it.id != newUserId - }.run { newUser?.let { plus(it) } ?: this }.toList() + latestUsers = latestUsers.asSequence().filter { user -> + user.id != newUserId + }.let { sequence -> + if (newUser != null) { + sequence + newUser + } else { + sequence + } + }.toList() callback(latestUsers) }) 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 e8d09768..3cd77e81 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 @@ -22,6 +22,7 @@ import com.pubnub.api.models.consumer.objects.membership.PNChannelMembershipArra import com.pubnub.api.models.consumer.pubsub.objects.PNDeleteChannelMetadataEventMessage import com.pubnub.api.models.consumer.pubsub.objects.PNSetChannelMetadataEventMessage import com.pubnub.api.models.consumer.push.payload.PushPayloadHelper +import com.pubnub.api.utils.PatchValue import com.pubnub.api.v2.callbacks.Result import com.pubnub.api.v2.subscriptions.SubscriptionOptions import com.pubnub.chat.Channel @@ -40,7 +41,6 @@ import com.pubnub.chat.internal.METADATA_REFERENCED_CHANNELS import com.pubnub.chat.internal.METADATA_TEXT_LINKS import com.pubnub.chat.internal.MINIMAL_TYPING_INDICATOR_TIMEOUT import com.pubnub.chat.internal.MembershipImpl -import com.pubnub.chat.internal.channel.ChannelImpl.Companion.fromDTO import com.pubnub.chat.internal.defaultGetMessageResponseBody import com.pubnub.chat.internal.error.PubNubErrorMessage.CAN_NOT_STREAM_CHANNEL_UPDATES_ON_EMPTY_LIST import com.pubnub.chat.internal.error.PubNubErrorMessage.CHANNEL_INVITES_ARE_NOT_SUPPORTED_IN_PUBLIC_CHATS @@ -671,6 +671,10 @@ abstract class BaseChannel( ) } + override operator fun plus(update: PNChannelMetadata): Channel { + return channelFactory(chat, toPNChannelMetadata() + update) + } + private fun sendTypingSignal(value: Boolean): PNFuture { return chat.emitEvent( channelId = this.id, @@ -684,6 +688,19 @@ abstract class BaseChannel( internal abstract fun copyWithStatusDeleted(): C + private fun toPNChannelMetadata(): PNChannelMetadata { + return PNChannelMetadata( + id = id, + name = name?.let { PatchValue.of(it) }, + description = description?.let { PatchValue.of(it) }, + custom = custom?.let { PatchValue.of(custom) }, + updated = updated?.let { PatchValue.of(it) }, + eTag = null, + type = type?.let { PatchValue.of(it.stringValue) }, + status = status?.let { PatchValue.of(it) } + ) + } + companion object { private val log = logging() @@ -737,14 +754,25 @@ abstract class BaseChannel( val chat = channels.first().chat as ChatInternal val listener = createEventListener(chat.pubNub, onObjects = { _, event -> val (newChannel, newChannelId) = when (val message = event.extractedMessage) { - is PNSetChannelMetadataEventMessage -> fromDTO(chat, message.data) to message.data.id + is PNSetChannelMetadataEventMessage -> { + val newChannelId = message.data.id + val previousChannel = latestChannels.firstOrNull { it.id == newChannelId } + val newChannel = previousChannel?.plus(message.data) ?: ChannelImpl.fromDTO(chat, message.data) + newChannel to newChannelId + } is PNDeleteChannelMetadataEventMessage -> null to message.channel else -> return@createEventListener } - latestChannels = latestChannels.asSequence().filter { - it.id != newChannelId - }.run { newChannel?.let { plus(it) } ?: this }.toList() + latestChannels = latestChannels.asSequence().filter { channel -> + channel.id != newChannelId + }.let { sequence -> + if (newChannel != null) { + sequence + newChannel + } else { + sequence + } + }.toList() callback(latestChannels) }) diff --git a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ChannelImpl.kt b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ChannelImpl.kt index 59c65f6d..79069ff8 100644 --- a/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ChannelImpl.kt +++ b/pubnub-chat-impl/src/commonMain/kotlin/com/pubnub/chat/internal/channel/ChannelImpl.kt @@ -37,12 +37,12 @@ data class ChannelImpl( return ChannelImpl( chat, id = channel.id, - name = channel.name, - custom = channel.custom, - description = channel.description, - updated = channel.updated, - status = channel.status, - type = ChannelType.from(channel.type) + name = channel.name?.value, + custom = channel.custom?.value, + description = channel.description?.value, + updated = channel.updated?.value, + status = channel.status?.value, + type = ChannelType.from(channel.type?.value) ) } } 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 53c77791..f45ee8b4 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 @@ -137,12 +137,12 @@ data class ThreadChannelImpl( parentMessage, chat, id = channel.id, - name = channel.name, - custom = channel.custom, - description = channel.description, - updated = channel.updated, - status = channel.status, - type = ChannelType.from(channel.type) + name = channel.name?.value, + custom = channel.custom?.value, + description = channel.description?.value, + updated = channel.updated?.value, + status = channel.status?.value, + type = ChannelType.from(channel.type?.value) ) } } 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 a6ea8cb4..0a453c4e 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 @@ -10,7 +10,6 @@ import com.pubnub.chat.internal.UserImpl import com.pubnub.chat.internal.channel.BaseChannel import com.pubnub.chat.internal.channel.ChannelImpl import com.pubnub.chat.restrictions.GetRestrictionsResponse -import com.pubnub.chat.types.ChannelType import com.pubnub.chat.types.JoinResult import com.pubnub.kmp.createCustomObject import com.pubnub.test.await @@ -289,51 +288,21 @@ class ChannelIntegrationTest : BaseChatIntegrationTest() { ).await() delayInMillis(1000) - // todo there are big problems with update handling in PN SDK that prevent this for working in a sane way - // e.g. getting an update to one property (e.g. description) will return an object with all other properties set to null val expectedUpdates = listOf>( listOf( - channel01.asImpl().copy( - name = newName, - custom = null, - description = null, - type = ChannelType.UNKNOWN, - status = null, - updated = null - ), - channel02.asImpl().copy(updated = null) + channel01.asImpl().copy(name = newName), + channel02.asImpl() ).sortedBy { it.id }, listOf( - channel01.asImpl().copy( - name = newName, - custom = null, - description = null, - type = ChannelType.UNKNOWN, - status = null, - updated = null - ), - channel02.asImpl().copy( - custom = null, - name = null, - description = newName, - type = ChannelType.UNKNOWN, - status = null, - updated = null - ) + channel01.asImpl().copy(name = newName), + channel02.asImpl().copy(description = newName) ).sortedBy { it.id }, listOf( - channel02.asImpl().copy( - custom = null, - name = null, - description = newName, - type = ChannelType.UNKNOWN, - status = null, - updated = null - ) + channel02.asImpl().copy(description = newName) ).sortedBy { it.id }, @@ -361,7 +330,7 @@ class ChannelIntegrationTest : BaseChatIntegrationTest() { dispose?.close() } - assertEquals(expectedUpdates, actualUpdates) + assertEquals(expectedUpdates.map { it.map { it.asImpl().copy(updated = null) as Channel } }, actualUpdates) } @Test diff --git a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/UserIntegrationTest.kt b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/UserIntegrationTest.kt index 845a73f4..a9124aff 100644 --- a/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/UserIntegrationTest.kt +++ b/pubnub-chat-impl/src/commonTest/kotlin/com/pubnub/integration/UserIntegrationTest.kt @@ -122,6 +122,7 @@ class UserIntegrationTest : BaseChatIntegrationTest() { val expectedUpdates = listOf( listOf(someUser), listOf(someUser.asImpl().copy(name = newName)), + listOf(someUser.asImpl().copy(name = newName, externalId = newName)), emptyList() ) val actualUpdates = mutableListOf>() @@ -138,6 +139,8 @@ class UserIntegrationTest : BaseChatIntegrationTest() { someUser.update(name = newName).await() + someUser.update(externalId = newName).await() + someUser.delete().await() delayInMillis(2000) 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 e93356f4..f8c755da 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 @@ -14,7 +14,9 @@ import com.pubnub.api.models.consumer.history.PNFetchMessagesResult import com.pubnub.api.models.consumer.objects.PNMemberKey import com.pubnub.api.models.consumer.objects.PNPage import com.pubnub.api.models.consumer.objects.PNSortKey +import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.objects.member.PNUUIDDetailsLevel +import com.pubnub.api.utils.PatchValue import com.pubnub.api.v2.callbacks.Consumer import com.pubnub.api.v2.callbacks.Result import com.pubnub.api.v2.createPNConfiguration @@ -35,6 +37,7 @@ import com.pubnub.chat.types.MessageMentionedUser import com.pubnub.chat.types.MessageReferencedChannel import com.pubnub.kmp.utils.BaseTest import com.pubnub.test.await +import com.pubnub.test.randomString import dev.mokkery.MockMode import dev.mokkery.answering.calls import dev.mokkery.answering.returns @@ -765,6 +768,16 @@ class ChannelTest : BaseTest() { verify { chat.updateChannel(channelId, name, custom, description, status, type) } } + + @Test + fun plus() { + val channel = createChannel(ChannelType.PUBLIC) + val expectedChannel = channel.copy(name = randomString(), description = randomString()) + + val newChannel = channel + PNChannelMetadata(expectedChannel.id, name = PatchValue.of(expectedChannel.name), description = PatchValue.of(expectedChannel.description)) + + assertEquals(expectedChannel, newChannel) + } } private operator fun Any?.get(s: String): Any? { 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 72a610cd..d924441d 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 @@ -42,6 +42,7 @@ import com.pubnub.api.models.consumer.presence.PNHereNowResult import com.pubnub.api.models.consumer.presence.PNWhereNowResult import com.pubnub.api.models.consumer.push.PNPushListProvisionsResult import com.pubnub.api.models.consumer.push.PNPushRemoveAllChannelsResult +import com.pubnub.api.utils.PatchValue import com.pubnub.api.v2.PNConfiguration import com.pubnub.api.v2.callbacks.Consumer import com.pubnub.api.v2.callbacks.Result @@ -1342,13 +1343,13 @@ class ChatTest : BaseTest() { val actualId = updatedId ?: id val pnChannelMetadata = PNChannelMetadata( id = actualId, - name = updatedName, - description = updatedDescription, - custom = updatedCustom, - updated = updatedUpdated, - eTag = "updatedETag", - type = updatedType, - status = updatedStatus + name = PatchValue.of(updatedName), + description = PatchValue.of(updatedDescription), + custom = PatchValue.of(updatedCustom), + updated = PatchValue.of(updatedUpdated), + eTag = PatchValue.of("updatedETag"), + type = PatchValue.of(updatedType), + status = PatchValue.of(updatedStatus) ) return PNChannelMetadataResult(status = 200, data = pnChannelMetadata) } @@ -1370,26 +1371,26 @@ class ChatTest : BaseTest() { private fun getPNUuidMetadata() = PNUUIDMetadata( id = id, - name = name, - externalId = externalId, - profileUrl = profileUrl, - email = email, - custom = customData, - updated = updated, - eTag = "eTag", - type = typeAsString, - status = status + name = PatchValue.of(name), + externalId = PatchValue.of(externalId), + profileUrl = PatchValue.of(profileUrl), + email = PatchValue.of(email), + custom = PatchValue.of(customData), + updated = PatchValue.of(updated), + eTag = PatchValue.of("eTag"), + type = PatchValue.of(typeAsString), + status = PatchValue.of(status), ) private fun getPNChannelMetadata() = PNChannelMetadata( id = id, - name = name, - description = description, - custom = customData, - updated = updated, - eTag = "updatedETag", - type = typeAsString, - status = status + name = PatchValue.of(name), + description = PatchValue.of(description), + custom = PatchValue.of(customData), + updated = PatchValue.of(updated), + eTag = PatchValue.of("updatedETag"), + type = PatchValue.of(typeAsString), + status = PatchValue.of(status) ) private fun getPNUuidMetadataResult(): PNUUIDMetadataResult { 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 ee5283da..15fe4b7a 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 @@ -9,6 +9,8 @@ import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata import com.pubnub.api.models.consumer.objects.membership.PNChannelDetailsLevel import com.pubnub.api.models.consumer.objects.membership.PNChannelMembership import com.pubnub.api.models.consumer.objects.membership.PNChannelMembershipArrayResult +import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata +import com.pubnub.api.utils.PatchValue import com.pubnub.api.v2.PNConfiguration import com.pubnub.api.v2.callbacks.Consumer import com.pubnub.api.v2.callbacks.Result @@ -18,6 +20,7 @@ import com.pubnub.chat.internal.ChatInternal import com.pubnub.chat.internal.UserImpl import com.pubnub.chat.internal.channel.ChannelImpl import com.pubnub.kmp.utils.FakeChat +import com.pubnub.test.randomString import dev.mokkery.MockMode import dev.mokkery.answering.calls import dev.mokkery.answering.returns @@ -354,6 +357,16 @@ class UserTest { } } + @Test + fun plus() { + val user = createUser(chat) + val expectedUser = user.copy(name = randomString(), email = randomString()) + + val newUser = user + PNUUIDMetadata(expectedUser.id, name = PatchValue.of(expectedUser.name), email = PatchValue.of(expectedUser.email)) + + assertEquals(expectedUser, newUser) + } + private fun getPNChannelMembershipArrayResult(): PNChannelMembershipArrayResult { val channelMetadata = PNChannelMetadata( id = channelId, diff --git a/pubnub-kotlin b/pubnub-kotlin index 3e82af34..c4f66404 160000 --- a/pubnub-kotlin +++ b/pubnub-kotlin @@ -1 +1 @@ -Subproject commit 3e82af34d882670d2c25d3785e4af747e7f53807 +Subproject commit c4f664046005502c84869122e09162088b722f70