Merge pull request #6777 from thundernest/fix_DefaultMessageCountsProvider_NPE

Fix crash in `DefaultMessageCountsProvider`
This commit is contained in:
cketti 2023-03-22 14:50:32 +01:00 committed by GitHub
commit 276f8ead83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 8 deletions

View file

@ -61,7 +61,7 @@ internal class DefaultMessageCountsProvider(
}
}
private fun getMessageCounts(account: Account, conditions: ConditionsTreeNode): MessageCounts {
private fun getMessageCounts(account: Account, conditions: ConditionsTreeNode?): MessageCounts {
return try {
val messageStore = messageStoreManager.getMessageStore(account)
return MessageCounts(

View file

@ -235,12 +235,12 @@ interface MessageStore {
/**
* Retrieve the number of unread messages matching [conditions].
*/
fun getUnreadMessageCount(conditions: ConditionsTreeNode): Int
fun getUnreadMessageCount(conditions: ConditionsTreeNode?): Int
/**
* Retrieve the number of starred messages matching [conditions].
*/
fun getStarredMessageCount(conditions: ConditionsTreeNode): Int
fun getStarredMessageCount(conditions: ConditionsTreeNode?): Int
/**
* Update a folder's name and type.

View file

@ -0,0 +1,48 @@
package com.fsck.k9.controller
import assertk.assertThat
import assertk.assertions.isEqualTo
import com.fsck.k9.Account
import com.fsck.k9.Account.FolderMode
import com.fsck.k9.Preferences
import com.fsck.k9.mailstore.ListenableMessageStore
import com.fsck.k9.mailstore.MessageStoreManager
import com.fsck.k9.search.ConditionsTreeNode
import org.junit.Test
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val ACCOUNT_UUID = "irrelevant"
private const val UNREAD_COUNT = 2
private const val STARRED_COUNT = 3
class DefaultMessageCountsProviderTest {
private val preferences = mock<Preferences>()
private val account = Account(ACCOUNT_UUID)
private val messageStore = mock<ListenableMessageStore> {
on { getUnreadMessageCount(anyOrNull<ConditionsTreeNode>()) } doReturn UNREAD_COUNT
on { getStarredMessageCount(anyOrNull()) } doReturn STARRED_COUNT
}
private val messageStoreManager = mock<MessageStoreManager> {
on { getMessageStore(account) } doReturn messageStore
}
private val messageCountsProvider = DefaultMessageCountsProvider(preferences, messageStoreManager)
@Test
fun `getMessageCounts() without any special folders and displayMode = ALL`() {
account.inboxFolderId = null
account.trashFolderId = null
account.draftsFolderId = null
account.spamFolderId = null
account.outboxFolderId = null
account.sentFolderId = null
account.folderDisplayMode = FolderMode.ALL
val messageCounts = messageCountsProvider.getMessageCounts(account)
assertThat(messageCounts.unread).isEqualTo(UNREAD_COUNT)
assertThat(messageCounts.starred).isEqualTo(STARRED_COUNT)
}
}

View file

@ -185,11 +185,11 @@ class K9MessageStore(
return retrieveFolderOperations.getUnreadMessageCount(folderId)
}
override fun getUnreadMessageCount(conditions: ConditionsTreeNode): Int {
override fun getUnreadMessageCount(conditions: ConditionsTreeNode?): Int {
return retrieveFolderOperations.getUnreadMessageCount(conditions)
}
override fun getStarredMessageCount(conditions: ConditionsTreeNode): Int {
override fun getStarredMessageCount(conditions: ConditionsTreeNode?): Int {
return retrieveFolderOperations.getStarredMessageCount(conditions)
}

View file

@ -172,15 +172,15 @@ $displayModeSelection
}
}
fun getUnreadMessageCount(conditions: ConditionsTreeNode): Int {
fun getUnreadMessageCount(conditions: ConditionsTreeNode?): Int {
return getMessageCount(condition = "messages.read = 0", conditions)
}
fun getStarredMessageCount(conditions: ConditionsTreeNode): Int {
fun getStarredMessageCount(conditions: ConditionsTreeNode?): Int {
return getMessageCount(condition = "messages.flagged = 1", conditions)
}
private fun getMessageCount(condition: String, extraConditions: ConditionsTreeNode): Int {
private fun getMessageCount(condition: String, extraConditions: ConditionsTreeNode?): Int {
val whereBuilder = StringBuilder()
val queryArgs = mutableListOf<String>()
SqlQueryBuilder.buildWhereClause(extraConditions, whereBuilder, queryArgs)

View file

@ -413,12 +413,27 @@ class RetrieveFolderOperationsTest : RobolectricTest() {
val folderId2 = sqliteDatabase.createFolder(integrate = true)
sqliteDatabase.createMessage(folderId = folderId2, read = false)
sqliteDatabase.createMessage(folderId = folderId2, read = true)
val folderId3 = sqliteDatabase.createFolder(integrate = false)
sqliteDatabase.createMessage(folderId = folderId3, read = false)
val result = retrieveFolderOperations.getUnreadMessageCount(unifiedInboxConditions)
assertThat(result).isEqualTo(3)
}
@Test
fun `get unread message count without condition`() {
val folderId1 = sqliteDatabase.createFolder(integrate = true)
sqliteDatabase.createMessage(folderId = folderId1, read = false)
val folderId2 = sqliteDatabase.createFolder(integrate = false)
sqliteDatabase.createMessage(folderId = folderId2, read = false)
sqliteDatabase.createMessage(folderId = folderId2, read = true)
val result = retrieveFolderOperations.getUnreadMessageCount(conditions = null)
assertThat(result).isEqualTo(2)
}
@Test
fun `get starred message count with condition from empty folder`() {
sqliteDatabase.createFolder(integrate = true)
@ -444,12 +459,27 @@ class RetrieveFolderOperationsTest : RobolectricTest() {
sqliteDatabase.createMessage(folderId = folderId2, flagged = true)
sqliteDatabase.createMessage(folderId = folderId2, flagged = true)
sqliteDatabase.createMessage(folderId = folderId2, flagged = false)
val folderId3 = sqliteDatabase.createFolder(integrate = false)
sqliteDatabase.createMessage(folderId = folderId3, flagged = true)
val result = retrieveFolderOperations.getStarredMessageCount(unifiedInboxConditions)
assertThat(result).isEqualTo(3)
}
@Test
fun `get starred message count without condition`() {
val folderId1 = sqliteDatabase.createFolder(integrate = true)
sqliteDatabase.createMessage(folderId = folderId1, flagged = true)
val folderId2 = sqliteDatabase.createFolder(integrate = false)
sqliteDatabase.createMessage(folderId = folderId2, flagged = true)
sqliteDatabase.createMessage(folderId = folderId2, flagged = false)
val result = retrieveFolderOperations.getStarredMessageCount(conditions = null)
assertThat(result).isEqualTo(2)
}
@Test
fun `get 'more messages' value from non-existent folder`() {
assertThat {