diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt index 2c1483f9e74..da1c101c7dc 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt @@ -24,8 +24,8 @@ import com.wire.kalium.logger.obfuscateDomain import com.wire.kalium.logger.obfuscateId import com.wire.kalium.logic.data.client.Client import com.wire.kalium.logic.data.conversation.ClientId -import com.wire.kalium.logic.data.conversation.Conversation.Member import com.wire.kalium.logic.data.conversation.Conversation.Protocol +import com.wire.kalium.logic.data.conversation.Conversation.Member import com.wire.kalium.logic.data.conversation.Conversation.ReceiptMode import com.wire.kalium.logic.data.conversation.Conversation.TypingIndicatorMode import com.wire.kalium.logic.data.conversation.MutedConversationStatus @@ -447,6 +447,38 @@ sealed class Event(open val id: String, open val transient: Boolean, open val li ) } + data class MemberJoin( + override val id: String, + override val teamId: String, + override val transient: Boolean, + override val live: Boolean, + val memberId: String, + ) : Team(id, teamId, transient, live) { + override fun toLogMap(): Map = mapOf( + typeKey to "Team.MemberJoin", + idKey to id.obfuscateId(), + teamIdKey to teamId.obfuscateId(), + memberIdKey to memberId.obfuscateId(), + ) + } + + data class MemberLeave( + override val id: String, + override val transient: Boolean, + override val live: Boolean, + override val teamId: String, + val memberId: String, + val timestampIso: String, + ) : Team(id, teamId, transient, live) { + override fun toLogMap(): Map = mapOf( + typeKey to "Team.MemberLeave", + idKey to id.obfuscateId(), + teamIdKey to teamId.obfuscateId(), + timestampIsoKey to timestampIso, + memberIdKey to memberId.obfuscateId(), + ) + } + data class MemberUpdate( override val id: String, override val teamId: String, diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt index 3016f6ab03c..9cf1b0dcd7b 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt @@ -96,6 +96,8 @@ class EventMapper( is EventContentDTO.Conversation.AccessUpdate -> unknown(id, transient, live, eventContentDTO) is EventContentDTO.Conversation.DeletedConversationDTO -> conversationDeleted(id, eventContentDTO, transient, live) is EventContentDTO.Conversation.ConversationRenameDTO -> conversationRenamed(id, eventContentDTO, transient, live) + is EventContentDTO.Team.MemberJoin -> teamMemberJoined(id, eventContentDTO, transient, live) + is EventContentDTO.Team.MemberLeave -> teamMemberLeft(id, eventContentDTO, transient, live) is EventContentDTO.Team.MemberUpdate -> teamMemberUpdate(id, eventContentDTO, transient, live) is EventContentDTO.Team.Update -> teamUpdate(id, eventContentDTO, transient, live) is EventContentDTO.User.UpdateDTO -> userUpdate(id, eventContentDTO, transient, live) @@ -655,6 +657,33 @@ class EventMapper( timestampIso = event.time, ) + private fun teamMemberJoined( + id: String, + event: EventContentDTO.Team.MemberJoin, + transient: Boolean, + live: Boolean + ) = Event.Team.MemberJoin( + id = id, + teamId = event.teamId, + transient = transient, + live = live, + memberId = event.teamMember.nonQualifiedUserId + ) + + private fun teamMemberLeft( + id: String, + event: EventContentDTO.Team.MemberLeave, + transient: Boolean, + live: Boolean + ) = Event.Team.MemberLeave( + id = id, + teamId = event.teamId, + memberId = event.teamMember.nonQualifiedUserId, + transient = transient, + live = live, + timestampIso = event.time + ) + private fun teamMemberUpdate( id: String, event: EventContentDTO.Team.MemberUpdate, diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/team/TeamRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/team/TeamRepository.kt index fe52f36de74..ef1108dfc17 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/team/TeamRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/team/TeamRepository.kt @@ -26,6 +26,7 @@ import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.TeamId import com.wire.kalium.logic.data.service.ServiceMapper import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.data.user.UserMapper import com.wire.kalium.logic.data.user.type.UserEntityTypeMapper import com.wire.kalium.logic.di.MapperProvider import com.wire.kalium.logic.functional.Either @@ -39,7 +40,10 @@ import com.wire.kalium.logic.wrapApiRequest import com.wire.kalium.logic.wrapStorageRequest import com.wire.kalium.network.api.base.authenticated.TeamsApi import com.wire.kalium.network.api.base.authenticated.notification.EventContentDTO +import com.wire.kalium.network.api.base.authenticated.userDetails.UserDetailsApi import com.wire.kalium.network.api.base.model.LegalHoldStatusDTO +import com.wire.kalium.network.api.base.model.QualifiedID +import com.wire.kalium.persistence.dao.ConnectionEntity import com.wire.kalium.persistence.dao.QualifiedIDEntity import com.wire.kalium.persistence.dao.ServiceDAO import com.wire.kalium.persistence.dao.TeamDAO @@ -55,6 +59,8 @@ interface TeamRepository { suspend fun getTeam(teamId: TeamId): Flow suspend fun deleteConversation(conversationId: ConversationId, teamId: TeamId): Either suspend fun updateMemberRole(teamId: String, userId: String, permissionCode: Int?): Either + suspend fun fetchTeamMember(teamId: String, userId: String): Either + suspend fun removeTeamMember(teamId: String, userId: String): Either suspend fun updateTeam(team: Team): Either suspend fun syncServices(teamId: TeamId): Either suspend fun approveLegalHoldRequest(teamId: TeamId, password: String?): Either @@ -67,10 +73,12 @@ internal class TeamDataSource( private val userConfigDAO: UserConfigDAO, private val teamDAO: TeamDAO, private val teamsApi: TeamsApi, + private val userDetailsApi: UserDetailsApi, private val selfUserId: UserId, private val serviceDAO: ServiceDAO, private val legalHoldHandler: LegalHoldHandler, private val legalHoldRequestHandler: LegalHoldRequestHandler, + private val userMapper: UserMapper = MapperProvider.userMapper(), private val teamMapper: TeamMapper = MapperProvider.teamMapper(), private val serviceMapper: ServiceMapper = MapperProvider.serviceMapper(), private val userTypeEntityTypeMapper: UserEntityTypeMapper = MapperProvider.userTypeEntityMapper(), @@ -146,6 +154,34 @@ internal class TeamDataSource( } } + override suspend fun fetchTeamMember(teamId: String, userId: String): Either { + return wrapApiRequest { + teamsApi.getTeamMember( + teamId = teamId, + userId = userId, + ) + }.flatMap { member -> + wrapApiRequest { userDetailsApi.getUserInfo(userId = QualifiedID(userId, selfUserId.domain)) } + .flatMap { userProfileDTO -> + wrapStorageRequest { + val userEntity = userMapper.fromUserProfileDtoToUserEntity( + userProfile = userProfileDTO, + connectionState = ConnectionEntity.State.ACCEPTED, + userTypeEntity = userTypeEntityTypeMapper.teamRoleCodeToUserType(member.permissions?.own) + ) + userDAO.upsertUser(userEntity) + userDAO.upsertConnectionStatuses(mapOf(userEntity.id to userEntity.connectionStatus)) + } + } + } + } + + override suspend fun removeTeamMember(teamId: String, userId: String): Either { + return wrapStorageRequest { + userDAO.markUserAsDeleted(QualifiedIDEntity(userId, selfUserId.domain)) + } + } + override suspend fun updateTeam(team: Team): Either { return wrapStorageRequest { teamDAO.updateTeam(teamMapper.fromModelToEntity(team)) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt index c1e8ed6f33d..e017d795ae0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt @@ -234,8 +234,6 @@ import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldChangeNotifiedFor import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldChangeNotifiedForSelfUseCaseImpl import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldForSelfUserUseCase import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldForSelfUserUseCaseImpl -import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCase -import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCaseImpl import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldStateForUserUseCase import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldStateForUserUseCaseImpl import com.wire.kalium.logic.feature.message.AddSystemMessageToAllConversationsUseCase @@ -728,6 +726,7 @@ class UserSessionScope internal constructor( userStorage.database.userConfigDAO, userStorage.database.teamDAO, authenticatedNetworkContainer.teamsApi, + authenticatedNetworkContainer.userDetailsApi, userId, userStorage.database.serviceDAO, legalHoldHandler, @@ -1443,7 +1442,7 @@ class UserSessionScope internal constructor( ) private val teamEventReceiver: TeamEventReceiver - get() = TeamEventReceiverImpl(teamRepository) + get() = TeamEventReceiverImpl(teamRepository, conversationRepository, userRepository, persistMessage, userId) private val guestRoomConfigHandler get() = GuestRoomConfigHandler(userConfigRepository, kaliumConfigs) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiver.kt index fdf7f64a320..f88075f8469 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiver.kt @@ -18,26 +18,39 @@ package com.wire.kalium.logic.sync.receiver +import com.benasher44.uuid.uuid4 import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.data.conversation.ConversationRepository import com.wire.kalium.logic.data.event.Event import com.wire.kalium.logic.data.event.EventLoggingStatus import com.wire.kalium.logic.data.event.logEventProcessing +import com.wire.kalium.logic.data.message.Message +import com.wire.kalium.logic.data.message.MessageContent +import com.wire.kalium.logic.data.message.PersistMessageUseCase import com.wire.kalium.logic.data.team.Team import com.wire.kalium.logic.data.team.TeamRepository +import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.data.user.UserRepository import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.onFailure import com.wire.kalium.logic.functional.onSuccess import com.wire.kalium.logic.kaliumLogger +import kotlinx.coroutines.flow.first internal interface TeamEventReceiver : EventReceiver internal class TeamEventReceiverImpl( - private val teamRepository: TeamRepository - + private val teamRepository: TeamRepository, + private val conversationRepository: ConversationRepository, + private val userRepository: UserRepository, + private val persistMessage: PersistMessageUseCase, + private val selfUserId: UserId, ) : TeamEventReceiver { override suspend fun onEvent(event: Event.Team): Either { when (event) { + is Event.Team.MemberJoin -> handleMemberJoin(event) + is Event.Team.MemberLeave -> handleMemberLeave(event) is Event.Team.MemberUpdate -> handleMemberUpdate(event) is Event.Team.Update -> handleUpdate(event) } @@ -48,6 +61,97 @@ internal class TeamEventReceiverImpl( return Either.Right(Unit) } + private suspend fun handleMemberJoin(event: Event.Team.MemberJoin) = + teamRepository.fetchTeamMember( + teamId = event.teamId, + userId = event.memberId, + ) + .onSuccess { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.SUCCESS, + event + ) + } + .onFailure { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.FAILURE, + event, + Pair("errorInfo", "$it") + ) + } + + @Suppress("LongMethod") + private suspend fun handleMemberLeave(event: Event.Team.MemberLeave) { + val userId = UserId(event.memberId, selfUserId.domain) + teamRepository.removeTeamMember( + teamId = event.teamId, + userId = event.memberId, + ) + .onSuccess { + val knownUser = userRepository.getKnownUser(userId).first() + if (knownUser?.name != null) { + conversationRepository.getConversationsByUserId(userId) + .onSuccess { + it.forEach { conversation -> + val message = Message.System( + id = uuid4().toString(), // We generate a random uuid for this new system message + content = MessageContent.TeamMemberRemoved(knownUser.name), + conversationId = conversation.id, + date = event.timestampIso, + senderUserId = userId, + status = Message.Status.Sent, + visibility = Message.Visibility.VISIBLE, + expirationData = null + ) + persistMessage(message) + } + + conversationRepository.deleteUserFromConversations(userId) + .onSuccess { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.SUCCESS, + event + ) + } + .onFailure { deleteFailure -> + kaliumLogger + .logEventProcessing( + EventLoggingStatus.FAILURE, + event, + Pair("errorInfo", "$deleteFailure") + ) + } + + }.onFailure { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.FAILURE, + event, + Pair("errorInfo", "$it") + ) + } + } else { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.SKIPPED, + event, + Pair("info", "User or User name is null") + ) + } + } + .onFailure { + kaliumLogger + .logEventProcessing( + EventLoggingStatus.FAILURE, + event, + Pair("errorInfo", "$it") + ) + } + } + private suspend fun handleMemberUpdate(event: Event.Team.MemberUpdate) = teamRepository.updateMemberRole( teamId = event.teamId, diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt index f1b05d9c7fd..882149e7a3d 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt @@ -52,7 +52,6 @@ internal interface UserEventReceiver : EventReceiver internal class UserEventReceiverImpl internal constructor( private val clientRepository: ClientRepository, private val connectionRepository: ConnectionRepository, - private val conversationRepository: ConversationRepository, private val userRepository: UserRepository, private val logout: LogoutUseCase, private val oneOnOneResolver: OneOnOneResolver, diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/team/TeamRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/team/TeamRepositoryTest.kt index fac6016b2fb..405138d2201 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/team/TeamRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/team/TeamRepositoryTest.kt @@ -18,7 +18,7 @@ package com.wire.kalium.logic.data.team -import app.cash.turbine.test +import app.cash.turbine.test import com.wire.kalium.logic.NetworkFailure import com.wire.kalium.logic.data.user.LegalHoldStatus import com.wire.kalium.logic.data.id.TeamId @@ -225,6 +225,27 @@ class TeamRepositoryTest { .wasInvoked(once) } + @Test + fun givenTeamIdAndUserId_whenFetchingTeamMember_thenTeamMemberShouldBeSuccessful() = runTest { + val teamMemberDTO = TestTeam.memberDTO( + nonQualifiedUserId = "teamMember1" + ) + + val (arrangement, teamRepository) = Arrangement() + .withApiGetTeamMemberSuccess(teamMemberDTO) + .withGetUsersInfoSuccess() + .arrange() + + val result = teamRepository.fetchTeamMember("teamId", "userId") + + result.shouldSucceed() + + verify(arrangement.userDAO) + .suspendFunction(arrangement.userDAO::upsertUser) + .with(any()) + .wasInvoked(once) + } + @Test fun givenTeamId_whenSyncingWhitelistedServices_thenInsertIntoDatabase() = runTest { // given @@ -384,9 +405,14 @@ class TeamRepositoryTest { stubsUnitByDefault = true } + val teamMapper = MapperProvider.teamMapper() + @Mock val teamsApi = mock(classOf()) + @Mock + val userDetailsApi = mock(classOf()) + @Mock val serviceDAO = configure(mock(classOf())) { stubsUnitByDefault = true @@ -402,6 +428,7 @@ class TeamRepositoryTest { teamDAO = teamDAO, teamMapper = teamMapper, teamsApi = teamsApi, + userDetailsApi = userDetailsApi, userDAO = userDAO, selfUserId = TestUser.USER_ID, serviceDAO = serviceDAO, diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt index c3353478a66..17e6c3a5687 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt @@ -31,6 +31,7 @@ import com.wire.kalium.logic.data.user.Connection import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.util.DateTimeUtil.toIsoDateTimeString +import com.wire.kalium.util.time.Second import io.ktor.util.encodeBase64 import kotlinx.datetime.Instant @@ -157,6 +158,23 @@ object TestEvent { icon = "icon", ) + fun teamMemberJoin(eventId: String = "eventId") = Event.Team.MemberJoin( + eventId, + teamId = "teamId", + transient = false, + live = false, + memberId = "memberId" + ) + + fun teamMemberLeave(eventId: String = "eventId") = Event.Team.MemberLeave( + eventId, + teamId = "teamId", + memberId = "memberId", + timestampIso = "2022-03-30T15:36:00.000Z", + transient = false, + live = false + ) + fun teamMemberUpdate(eventId: String = "eventId", permissionCode: Int) = Event.Team.MemberUpdate( eventId, teamId = "teamId", diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiverTest.kt index 88e4407310c..fb93dcac92b 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/TeamEventReceiverTest.kt @@ -18,9 +18,15 @@ package com.wire.kalium.logic.sync.receiver +import com.wire.kalium.logic.data.conversation.Conversation +import com.wire.kalium.logic.data.conversation.ConversationRepository +import com.wire.kalium.logic.data.message.PersistMessageUseCase import com.wire.kalium.logic.data.team.TeamRepository import com.wire.kalium.logic.data.team.TeamRole +import com.wire.kalium.logic.data.user.UserRepository +import com.wire.kalium.logic.framework.TestConversation import com.wire.kalium.logic.framework.TestEvent +import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either import io.mockative.Mock import io.mockative.any @@ -29,6 +35,7 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import kotlin.test.Test @@ -49,6 +56,49 @@ class TeamEventReceiverTest { .wasInvoked(exactly = once) } + @Test + fun givenMemberJoinEvent_repoIsInvoked() = runTest { + val event = TestEvent.teamMemberJoin() + val (arrangement, eventReceiver) = Arrangement() + .withMemberJoinSuccess() + .arrange() + + eventReceiver.onEvent(event) + + verify(arrangement.teamRepository) + .suspendFunction(arrangement.teamRepository::fetchTeamMember) + .with(any(), any()) + .wasInvoked(exactly = once) + } + + @Test + fun givenMemberLeaveEvent_RepoAndPersisMessageAreInvoked() = runTest { + val event = TestEvent.teamMemberLeave() + val (arrangement, eventReceiver) = Arrangement() + .withMemberLeaveSuccess() + .withConversationsByUserId(listOf(TestConversation.CONVERSATION)) + .withPersistMessageSuccess() + .arrange() + + eventReceiver.onEvent(event) + + verify(arrangement.teamRepository) + .suspendFunction(arrangement.teamRepository::removeTeamMember) + .with(any(), any()) + .wasInvoked(exactly = once) + + verify(arrangement.conversationRepository) + .suspendFunction(arrangement.conversationRepository::deleteUserFromConversations) + .with(any()) + .wasInvoked(exactly = once) + + verify(arrangement.persistMessageUseCase) + .suspendFunction(arrangement.persistMessageUseCase::invoke) + .with(any()) + .wasInvoked(exactly = once) + + } + @Test fun givenMemberUpdateEvent_RepoIsInvoked() = runTest { val event = TestEvent.teamMemberUpdate(permissionCode = TeamRole.Member.value) @@ -68,20 +118,60 @@ class TeamEventReceiverTest { @Mock val teamRepository = mock(classOf()) + @Mock + val conversationRepository = mock(classOf()) + + @Mock + val userRepository = mock(classOf()) + + @Mock + val persistMessageUseCase = mock(classOf()) + private val teamEventReceiver: TeamEventReceiver = TeamEventReceiverImpl( - teamRepository + teamRepository, conversationRepository, userRepository, persistMessageUseCase, + TestUser.USER_ID ) + init { + apply { + given(userRepository).suspendFunction(userRepository::getKnownUser) + .whenInvokedWith(any()) + .thenReturn(flowOf(TestUser.OTHER)) + } + } + fun withUpdateTeamSuccess() = apply { given(teamRepository).suspendFunction(teamRepository::updateTeam).whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } + fun withMemberJoinSuccess() = apply { + given(teamRepository).suspendFunction(teamRepository::fetchTeamMember) + .whenInvokedWith(any(), any()).thenReturn(Either.Right(Unit)) + } + + fun withMemberLeaveSuccess() = apply { + given(teamRepository).suspendFunction(teamRepository::removeTeamMember) + .whenInvokedWith(any(), any()).thenReturn(Either.Right(Unit)) + given(conversationRepository).suspendFunction(conversationRepository::deleteUserFromConversations) + .whenInvokedWith(any()).thenReturn(Either.Right(Unit)) + } + fun withMemberUpdateSuccess() = apply { given(teamRepository).suspendFunction(teamRepository::updateMemberRole) .whenInvokedWith(any(), any(), any()).thenReturn(Either.Right(Unit)) } + fun withConversationsByUserId(conversationIds: List) = apply { + given(conversationRepository).suspendFunction(conversationRepository::getConversationsByUserId) + .whenInvokedWith(any()).thenReturn(Either.Right(conversationIds)) + } + + fun withPersistMessageSuccess() = apply { + given(persistMessageUseCase).suspendFunction(persistMessageUseCase::invoke) + .whenInvokedWith(any()).thenReturn(Either.Right(Unit)) + } + fun arrange() = this to teamEventReceiver } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/authenticated/notification/EventContentDTO.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/authenticated/notification/EventContentDTO.kt index e6b2bf62d8d..91c3b2adce9 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/authenticated/notification/EventContentDTO.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/authenticated/notification/EventContentDTO.kt @@ -37,6 +37,7 @@ import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureFlag import com.wire.kalium.network.api.base.authenticated.keypackage.LastPreKeyDTO import com.wire.kalium.network.api.base.authenticated.notification.conversation.MessageEventData import com.wire.kalium.network.api.base.authenticated.notification.team.PermissionsData +import com.wire.kalium.network.api.base.authenticated.notification.team.TeamMemberIdData import com.wire.kalium.network.api.base.authenticated.notification.team.TeamUpdateData import com.wire.kalium.network.api.base.authenticated.notification.user.RemoveClientEventData import com.wire.kalium.network.api.base.authenticated.notification.user.UserUpdateEventData @@ -289,6 +290,22 @@ sealed class EventContentDTO { @SerialName("time") val time: String, ) : Team() + @Serializable + @SerialName("team.member-join") + data class MemberJoin( + @SerialName("data") val teamMember: TeamMemberIdData, + @SerialName("team") val teamId: TeamId, + val time: String, + ) : Team() + + @Serializable + @SerialName("team.member-leave") + data class MemberLeave( + @SerialName("data") val teamMember: TeamMemberIdData, + @SerialName("team") val teamId: TeamId, + val time: String, + ) : Team() + @Serializable @SerialName("team.member-update") data class MemberUpdate( diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt index 52b029d26de..0b94a5a189f 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt @@ -339,8 +339,6 @@ sealed class MessageEntityContent { data object MissedCall : System() data object CryptoSessionReset : System() data class ConversationRenamed(val conversationName: String) : System() - - @Deprecated("not maintained and will be deleted") data class TeamMemberRemoved(val userName: String) : System() data class NewConversationReceiptMode(val receiptMode: Boolean) : System() data class ConversationReceiptModeChanged(val receiptMode: Boolean) : System()