Repository: thunderbird/thunderbird-android (language: kotlin)

Issue:
Recipients matching an identity email address with mismatched case are displayed multiple times
### Checklist

- [X] I have used the search function to see if someone else has already submitted the same bug report.
- [X] I will describe the problem with as much detail as possible.

### App version

6.704

### Where did you get the app from?

Google Play

### Android version

13

### Device model

_No response_

### Steps to reproduce

For an identity with email address `example@example.com` and description "Example" use the following recipients header in an email:
#### 1
```
To: <Example@example.com>
```
#### 2
```
To: <EXAMPLE@EXAMPLE.COM>
```
#### 3
```
To: <example@EXAMPLE.COM>
```

### Expected behavior

The list of recipients for the email is:
#### 1
```
to Example
```
#### 2
```
to Example
```
#### 3
```
to Example
```

### Actual behavior

The list of recipients for the email is:
#### 1
```
to Example, Example
```
#### 2
```
to Example, Example
```
#### 3
```
to Example, Example
```

### Logs

_No response_


Discussion hints:
nan

Pull request: Fix recipients being displayed multiple times
The problem was caused by inconsistent email address equality checks. This change leaves the comparison to `Account.isAnIdentity()`.

Fixes #6933

Test command: ./gradlew :app:ui:legacy:testDebugUnitTest --tests "com.fsck.k9.ui.messageview.DisplayRecipientsExtractorTest"

Fix patch:
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractor.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractor.kt
index 95a10e4925f..d56e02eadbb 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractor.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractor.kt
@@ -1,7 +1,6 @@
 package com.fsck.k9.ui.messageview
 
 import com.fsck.k9.Account
-import com.fsck.k9.mail.Address
 import com.fsck.k9.mail.Message
 
 /**
@@ -21,13 +20,12 @@ internal class DisplayRecipientsExtractor(
 
         val numberOfRecipients = toRecipients.size + ccRecipients.size + bccRecipients.size
 
-        val identity = sequenceOf(toRecipients, ccRecipients, bccRecipients)
+        val identityAddress = sequenceOf(toRecipients, ccRecipients, bccRecipients)
             .flatMap { addressArray -> addressArray.asSequence() }
-            .mapNotNull { address -> account.findIdentity(address) }
+            .filter { address -> account.isAnIdentity(address) }
             .firstOrNull()
 
-        val identityEmail = identity?.email
-        val maxAdditionalRecipients = if (identity != null) {
+        val maxAdditionalRecipients = if (identityAddress != null) {
             maxNumberOfDisplayRecipients - 1
         } else {
             maxNumberOfDisplayRecipients
@@ -35,13 +33,12 @@ internal class DisplayRecipientsExtractor(
 
         val recipientNames = sequenceOf(toRecipients, ccRecipients, bccRecipients)
             .flatMap { addressArray -> addressArray.asSequence() }
-            .filter { address -> address.address != identityEmail }
+            .filter { address -> address !== identityAddress }
             .map { address -> recipientFormatter.getDisplayName(address, account) }
             .take(maxAdditionalRecipients)
             .toList()
 
-        return if (identity != null) {
-            val identityAddress = Address(identity.email)
+        return if (identityAddress != null) {
             val meName = recipientFormatter.getDisplayName(identityAddress, account)
             val recipients = listOf(meName) + recipientNames
 


Test patch:
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractorTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractorTest.kt
index 1ed5ec70658..3ede76992d2 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractorTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messageview/DisplayRecipientsExtractorTest.kt
@@ -19,13 +19,16 @@ class DisplayRecipientsExtractorTest {
 
     private val recipientFormatter = object : MessageViewRecipientFormatter {
         override fun getDisplayName(address: Address, account: Account): CharSequence {
-            return when (address.address) {
-                IDENTITY_ADDRESS -> "me"
-                "user1@domain.example" -> "Contact One"
-                "user2@domain.example" -> "Contact Two"
-                "user3@domain.example" -> "Contact Three"
-                "user4@domain.example" -> "Contact Four"
-                else -> address.personal ?: address.address
+            return if (account.isAnIdentity(address)) {
+                "me"
+            } else {
+                when (address.address) {
+                    "user1@domain.example" -> "Contact One"
+                    "user2@domain.example" -> "Contact Two"
+                    "user3@domain.example" -> "Contact Three"
+                    "user4@domain.example" -> "Contact Four"
+                    else -> address.personal ?: address.address
+                }
             }
         }
     }
@@ -48,6 +51,45 @@ class DisplayRecipientsExtractorTest {
         )
     }
 
+    @Test
+    fun `single recipient is identity address with different local part case`() {
+        val message = buildMessage {
+            header("To", "Test User <ME@domain.example>")
+        }
+
+        val displayRecipients = displayRecipientsExtractor.extractDisplayRecipients(message, account)
+
+        assertThat(displayRecipients).isEqualTo(
+            DisplayRecipients(recipientNames = listOf("me"), numberOfRecipients = 1),
+        )
+    }
+
+    @Test
+    fun `single recipient is identity address with different domain case`() {
+        val message = buildMessage {
+            header("To", "Test User <me@DOMAIN.EXAMPLE>")
+        }
+
+        val displayRecipients = displayRecipientsExtractor.extractDisplayRecipients(message, account)
+
+        assertThat(displayRecipients).isEqualTo(
+            DisplayRecipients(recipientNames = listOf("me"), numberOfRecipients = 1),
+        )
+    }
+
+    @Test
+    fun `single recipient is identity address with different local part and domain case`() {
+        val message = buildMessage {
+            header("To", "Test User <ME@DOMAIN.EXAMPLE>")
+        }
+
+        val displayRecipients = displayRecipientsExtractor.extractDisplayRecipients(message, account)
+
+        assertThat(displayRecipients).isEqualTo(
+            DisplayRecipients(recipientNames = listOf("me"), numberOfRecipients = 1),
+        )
+    }
+
     @Test
     fun `single recipient is a contact`() {
         val message = buildMessage {