diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index c5628d3e3b..b9930402bb 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -177,7 +177,7 @@ object Versions { object Proton { - const val rustCore = "0.11.56" + const val rustCore = "0.14.0" const val core = "27.1.0" const val corePlugin = "1.3.0" } diff --git a/mail-conversation/data-rust/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationDataSourceImpl.kt b/mail-conversation/data-rust/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationDataSourceImpl.kt index e71c15fcf7..1ac19a8d87 100644 --- a/mail-conversation/data-rust/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationDataSourceImpl.kt +++ b/mail-conversation/data-rust/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationDataSourceImpl.kt @@ -90,9 +90,9 @@ class RustConversationDataSourceImpl @Inject constructor( } override suspend fun markRead(userId: UserId, conversations: List) { - executeUserSessionAction( + executeMailboxAction( userId = userId, - action = { userSession -> markConversationsAsRead(userSession, conversations) }, + action = { markConversationsAsRead(it, conversations) }, actionName = "mark as read" ) } diff --git a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImpl.kt b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImpl.kt index ceeb7fd566..903e1a9adf 100644 --- a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImpl.kt +++ b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImpl.kt @@ -133,19 +133,13 @@ class RustMessageDataSourceImpl @Inject constructor( @MissingRustApi override suspend fun markRead(userId: UserId, messages: List): Either { return try { - val session = userSessionRepository.getUserSession(userId) - if (session == null) { - Timber.e("rust-message: trying to mark message read with a null session") + val mailbox = rustMailbox.observeMailbox().firstOrNull() + if (mailbox == null) { + Timber.e("rust-message: trying to mark message read with a null mailbox") return DataError.Local.Unknown.left() } - val currentLabelId = rustMailbox.observeCurrentLabelId().firstOrNull() - if (currentLabelId == null) { - Timber.e("rust-message: trying to mark message read with a null labelId") - return DataError.Local.Unknown.left() - } - - rustMarkMessagesRead(session, currentLabelId, messages).right() + rustMarkMessagesRead(mailbox, messages).right() } catch (e: MailSessionException) { Timber.e(e, "rust-message: Failed to mark message read") DataError.Local.Unknown.left() @@ -154,19 +148,13 @@ class RustMessageDataSourceImpl @Inject constructor( override suspend fun markUnread(userId: UserId, messages: List): Either { return try { - val session = userSessionRepository.getUserSession(userId) - if (session == null) { - Timber.e("rust-message: trying to mark message unread with a null session") - return DataError.Local.Unknown.left() + val mailbox = rustMailbox.observeMailbox().firstOrNull() + if (mailbox == null) { + Timber.e("rust-message: trying to mark unread with null Mailbox! failing") + return DataError.Local.NoDataCached.left() } - val currentLabelId = rustMailbox.observeCurrentLabelId().firstOrNull() - if (currentLabelId == null) { - Timber.e("rust-message: trying to mark message unread with a null labelId") - return DataError.Local.Unknown.left() - } - - rustMarkMessagesUnread(session, currentLabelId, messages).right() + rustMarkMessagesUnread(mailbox, messages).right() } catch (e: MailSessionException) { Timber.e(e, "rust-message: Failed to mark message unread") DataError.Local.Unknown.left() diff --git a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesRead.kt b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesRead.kt index 09726966b7..17fde319a4 100644 --- a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesRead.kt +++ b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesRead.kt @@ -18,17 +18,13 @@ package ch.protonmail.android.mailmessage.data.usecase -import ch.protonmail.android.mailcommon.datarust.mapper.LocalLabelId import ch.protonmail.android.mailcommon.datarust.mapper.LocalMessageId -import uniffi.proton_mail_uniffi.MailUserSession +import uniffi.proton_mail_uniffi.Mailbox import uniffi.proton_mail_uniffi.markMessagesRead import javax.inject.Inject class RustMarkMessagesRead @Inject constructor() { - suspend operator fun invoke( - mailUserSession: MailUserSession, - currentLabelId: LocalLabelId, - messageIds: List - ) = markMessagesRead(mailUserSession, currentLabelId, messageIds) + suspend operator fun invoke(mailbox: Mailbox, messageIds: List) = + markMessagesRead(mailbox, messageIds) } diff --git a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesUnread.kt b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesUnread.kt index 9ec67b7c9b..44c93145e3 100644 --- a/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesUnread.kt +++ b/mail-message/data-rust/src/main/kotlin/ch/protonmail/android/mailmessage/data/usecase/RustMarkMessagesUnread.kt @@ -18,17 +18,13 @@ package ch.protonmail.android.mailmessage.data.usecase -import ch.protonmail.android.mailcommon.datarust.mapper.LocalLabelId import ch.protonmail.android.mailcommon.datarust.mapper.LocalMessageId -import uniffi.proton_mail_uniffi.MailUserSession +import uniffi.proton_mail_uniffi.Mailbox import uniffi.proton_mail_uniffi.markMessagesUnread import javax.inject.Inject class RustMarkMessagesUnread @Inject constructor() { - suspend operator fun invoke( - mailUserSession: MailUserSession, - currentLabelId: LocalLabelId, - messageIds: List - ) = markMessagesUnread(mailUserSession, currentLabelId, messageIds) + suspend operator fun invoke(mailbox: Mailbox, messageIds: List) = + markMessagesUnread(mailbox, messageIds) } diff --git a/mail-message/data-rust/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImplTest.kt b/mail-message/data-rust/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImplTest.kt index 6f148b4250..52d1805c09 100644 --- a/mail-message/data-rust/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImplTest.kt +++ b/mail-message/data-rust/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageDataSourceImplTest.kt @@ -35,6 +35,7 @@ import ch.protonmail.android.mailsession.domain.repository.UserSessionRepository import ch.protonmail.android.testdata.message.rust.LocalMessageIdSample import ch.protonmail.android.testdata.message.rust.LocalMessageTestData import ch.protonmail.android.testdata.user.UserIdTestData +import io.mockk.Called import io.mockk.Runs import io.mockk.coEvery import io.mockk.coVerify @@ -42,7 +43,6 @@ import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.verify -import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Test @@ -254,93 +254,69 @@ class RustMessageDataSourceImplTest { fun `should mark messages as read when session and labelId are available`() = runTest { // Given val userId = UserIdTestData.userId - val mailSession = mockk() - val currentLabelId = LocalLabelId(123uL) + val mailbox = mockk() val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } returns mailSession - coEvery { rustMailbox.observeCurrentLabelId() } returns flowOf(currentLabelId) - coEvery { rustMarkMessagesRead(mailSession, currentLabelId, messageIds) } just Runs + coEvery { rustMailbox.observeMailbox() } returns flowOf(mailbox) + coEvery { rustMarkMessagesRead(mailbox, messageIds) } just Runs // When val result = dataSource.markRead(userId, messageIds) // Then assertTrue(result.isRight()) - coVerify { rustMarkMessagesRead(mailSession, currentLabelId, messageIds) } + coVerify { rustMarkMessagesRead(mailbox, messageIds) } } @Test - fun `should not mark messages as read when session is null`() = runTest { + fun `should not mark messages as read when mailbox is null`() = runTest { // Given val userId = UserIdTestData.userId val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } returns null + coEvery { rustMailbox.observeMailbox() } returns flowOf() // When val result = dataSource.markRead(userId, messageIds) // Then assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesRead(any(), any(), any()) } - } - - @Test - fun `should not mark messages as read when labelId is null`() = runTest { - // Given - val userId = UserIdTestData.userId - val mailSession = mockk() - val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - - coEvery { userSessionRepository.getUserSession(userId) } returns mailSession - coEvery { rustMailbox.observeCurrentLabelId() } returns flowOf() - - // When - val result = dataSource.markRead(userId, messageIds) - - // Then - assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesRead(mailSession, any(), messageIds) } + verify { rustMarkMessagesRead wasNot Called } } @Test fun `should handle exception when marking messages as read`() = runTest { // Given val userId = UserIdTestData.userId - val mailSession = mockk() - val currentLabelId = LocalLabelId(123uL) + val mailbox = mockk() val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } throws MailSessionException.Other("Error") - coEvery { rustMailbox.observeCurrentLabelId().firstOrNull() } returns currentLabelId + coEvery { rustMarkMessagesRead(mailbox, messageIds) } throws MailSessionException.Other("Error") + coEvery { rustMailbox.observeMailbox() } returns flowOf(mailbox) // When val result = dataSource.markRead(userId, messageIds) // Then assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesRead(mailSession, currentLabelId, messageIds) } } @Test fun `should mark messages as unread when session and labelId are available`() = runTest { // Given val userId = UserIdTestData.userId - val mailSession = mockk() - val currentLabelId = LocalLabelId(123uL) + val mailbox = mockk() val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } returns mailSession - coEvery { rustMailbox.observeCurrentLabelId() } returns flowOf(currentLabelId) - coEvery { rustMarkMessagesUnread(mailSession, currentLabelId, messageIds) } just Runs + coEvery { rustMailbox.observeMailbox() } returns flowOf(mailbox) + coEvery { rustMarkMessagesUnread(mailbox, messageIds) } just Runs // When val result = dataSource.markUnread(userId, messageIds) // Then assertTrue(result.isRight()) - coVerify { rustMarkMessagesUnread(mailSession, currentLabelId, messageIds) } + coVerify { rustMarkMessagesUnread(mailbox, messageIds) } } @Test @@ -362,56 +338,36 @@ class RustMessageDataSourceImplTest { } @Test - fun `should not mark messages as unread when session is null`() = runTest { + fun `should not mark messages as unread when mailbox is not available`() = runTest { // Given val userId = UserIdTestData.userId val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } returns null + coEvery { rustMailbox.observeMailbox() } returns flowOf() // When val result = dataSource.markUnread(userId, messageIds) // Then assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesUnread(any(), any(), any()) } - } - - @Test - fun `should not mark messages as unread when labelId is null`() = runTest { - // Given - val userId = UserIdTestData.userId - val mailSession = mockk() - val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - - coEvery { userSessionRepository.getUserSession(userId) } returns mailSession - coEvery { rustMailbox.observeCurrentLabelId() } returns flowOf() - - // When - val result = dataSource.markUnread(userId, messageIds) - - // Then - assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesUnread(mailSession, any(), messageIds) } + verify { rustMarkMessagesUnread wasNot Called } } @Test fun `should handle exception when marking messages as unread`() = runTest { // Given val userId = UserIdTestData.userId - val mailSession = mockk() - val currentLabelId = LocalLabelId(123uL) + val mailbox = mockk() val messageIds = listOf(LocalMessageId(1uL), LocalMessageId(2uL)) - coEvery { userSessionRepository.getUserSession(userId) } throws MailSessionException.Other("Error") - coEvery { rustMailbox.observeCurrentLabelId().firstOrNull() } returns currentLabelId + coEvery { rustMarkMessagesUnread(mailbox, messageIds) } throws MailSessionException.Other("Error") + coEvery { rustMailbox.observeMailbox() } returns flowOf(mailbox) // When val result = dataSource.markUnread(userId, messageIds) // Then assertTrue(result.isLeft()) - coVerify(exactly = 0) { rustMarkMessagesUnread(mailSession, currentLabelId, messageIds) } } @Test