Skip to content

Fix autocomplete filter predicate not matching diacritic variants#3977

Merged
laevandus merged 2 commits intodevelopfrom
fix/diacritic-matching-in-autocomplete
Feb 25, 2026
Merged

Fix autocomplete filter predicate not matching diacritic variants#3977
laevandus merged 2 commits intodevelopfrom
fix/diacritic-matching-in-autocomplete

Conversation

@laevandus
Copy link
Contributor

@laevandus laevandus commented Feb 23, 2026

🔗 Issue Links

Fixes: IOS-1443

🎯 Goal

Fix autocomplete filter predicate not matching diacritic variants

📝 Summary

API returned correct results, but some results got filtered out on the CoreData level

🛠 Implementation

🎨 Showcase

🧪 Manual Testing Notes

Changing default channel list query:

diff --git a/DemoApp/StreamChat/DemoAppCoordinator+DemoApp.swift b/DemoApp/StreamChat/DemoAppCoordinator+DemoApp.swift
index 5eff98b53..29f75820c 100644
--- a/DemoApp/StreamChat/DemoAppCoordinator+DemoApp.swift
+++ b/DemoApp/StreamChat/DemoAppCoordinator+DemoApp.swift
@@ -123,8 +123,18 @@ extension DemoAppCoordinator {
         let channelListQuery: ChannelListQuery
         switch user {
         case let .credentials(userCredentials):
+            let searchText = "Joao"
             channelListQuery = .init(
-                filter: .containMembers(userIds: [userCredentials.id]),
+                filter: .and([
+                    .and([
+                        .containMembers(userIds: [userCredentials.id]),
+                        .equal(.archived, to: false)
+                    ]),
+                    .or([
+                        .autocomplete(.memberName, text: searchText),
+                        .autocomplete(.name, text: searchText)
+                    ])
+                ]),
                 sort: sorting
             )
         case let .custom(userCredentials):

And then creating some groups with users who name contains "João" (I added some using channel explorer).
r2-d2 has one matching group currently which I used for testing.

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Documentation has been updated in the docs-content repo

Summary by CodeRabbit

  • Bug Fixes

    • Autocomplete filtering now matches names with diacritic variants—searches for "Joao" match "João", "Jõao", etc., improving search accuracy.
  • Tests

    • Added tests verifying diacritic-insensitive autocomplete matching across variant names.
  • Documentation

    • CHANGELOG updated to note the diacritic-insensitive autocomplete fix.

@laevandus laevandus requested a review from a team as a code owner February 23, 2026 10:49
@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d2056ed and bd4281e.

📒 Files selected for processing (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Changed the autocomplete filter predicate to be diacritic-insensitive (CONTAINS[cd]) so queries like "Joao" match accented variants (e.g., "João"). Added a test exercising diacritic matching and updated the changelog to document the fix.

Changes

Cohort / File(s) Summary
Autocomplete Filter Logic
Sources/StreamChat/Query/Filter+predicate.swift
Replaced CONTAINS[c] with CONTAINS[cd] in the autocomplete predicate to make matching both case- and diacritic-insensitive.
Tests
Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift
Added test_filterPredicate_autocomplete_matchesDiacriticVariants which verifies that "Joao" and "Jõao" match channels named with accented variants. Note: the new test appears duplicated within the file (two insertions).
Changelog
CHANGELOG.md
Inserted a Fixed entry under StreamChat's Upcoming section documenting the diacritic-insensitive autocomplete predicate change.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudge the letters, soft and fleet,
João and Joao at last shall meet.
Accents and dots no longer hide,
Search hops forward, wide-eyed and spry—
A tiny fix, a joyful try!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing the autocomplete filter predicate to match diacritic variants, which is the core objective addressed across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/diacritic-matching-in-autocomplete

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@laevandus laevandus force-pushed the fix/diacritic-matching-in-autocomplete branch from c9433a1 to d2056ed Compare February 23, 2026 10:50
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift`:
- Around line 1270-1297: Extend the existing
test_filterPredicate_autocomplete_matchesDiacriticVariants test to also exercise
the collection-field branch by adding assertions that use the
.autocomplete(.memberName, text: ...) predicate (which uses ANY) and verify it
matches the same allMatchingCids; reuse the same channelsInDB setup and call try
assertFilterPredicate(.autocomplete(.memberName, text: "Joao"), channelsInDB:
channelsInDB, expectedResult: allMatchingCids) and similarly for "Jõao" to cover
both diacritic-insensitive paths.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 94dac10 and d2056ed.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • Sources/StreamChat/Query/Filter+predicate.swift
  • Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift

Comment on lines +1270 to +1297
func test_filterPredicate_autocomplete_matchesDiacriticVariants() throws {
let cidPlain = ChannelId.unique
let cidAccentA = ChannelId.unique
let cidTildeO = ChannelId.unique

let channelsInDB: [ChannelPayload] = [
.dummy(channel: .dummy(cid: cidPlain, name: "Joao Silva")),
.dummy(channel: .dummy(cid: cidAccentA, name: "João Silva")),
.dummy(channel: .dummy(cid: cidTildeO, name: "Jõao Silva")),
.dummy(channel: .dummy(name: "Random"))
]
let allMatchingCids = [cidPlain, cidAccentA, cidTildeO]

// Autocomplete uses CONTAINS[cd] (case and diacritic insensitive),
// so "Joao" matches "João", "Jõao", and "Joao".
try assertFilterPredicate(
.autocomplete(.name, text: "Joao"),
channelsInDB: channelsInDB,
expectedResult: allMatchingCids
)

// "Jõao" also matches all variants thanks to diacritic insensitivity.
try assertFilterPredicate(
.autocomplete(.name, text: "Jõao"),
channelsInDB: channelsInDB,
expectedResult: allMatchingCids
)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add collection-field coverage for diacritic matching.

This test only exercises .name (non-collection). The reported bug also affects the memberName autocomplete path (collection + ANY). Add a memberName assertion to cover that predicate branch.

✅ Suggested test extension
@@
     // "Jõao" also matches all variants thanks to diacritic insensitivity.
     try assertFilterPredicate(
         .autocomplete(.name, text: "Jõao"),
         channelsInDB: channelsInDB,
         expectedResult: allMatchingCids
     )
+
+    let memberChannels: [ChannelPayload] = [
+        .dummy(channel: .dummy(cid: cidPlain, members: [.dummy(user: .dummy(userId: .unique, name: "Joao Silva"))])),
+        .dummy(channel: .dummy(cid: cidAccentA, members: [.dummy(user: .dummy(userId: .unique, name: "João Silva"))])),
+        .dummy(channel: .dummy(cid: cidTildeO, members: [.dummy(user: .dummy(userId: .unique, name: "Jõao Silva"))])),
+        .dummy(channel: .dummy(name: "Random"))
+    ]
+    try assertFilterPredicate(
+        .autocomplete(.memberName, text: "Joao"),
+        channelsInDB: memberChannels,
+        expectedResult: allMatchingCids
+    )

As per coding guidelines: "Tests/**/*.swift: Add and extend tests in the matching module's Tests/ folder, covering core models, API surface, and UI behaviors using fakes/mocks from test helpers".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift`
around lines 1270 - 1297, Extend the existing
test_filterPredicate_autocomplete_matchesDiacriticVariants test to also exercise
the collection-field branch by adding assertions that use the
.autocomplete(.memberName, text: ...) predicate (which uses ANY) and verify it
matches the same allMatchingCids; reuse the same channelsInDB setup and call try
assertFilterPredicate(.autocomplete(.memberName, text: "Joao"), channelsInDB:
channelsInDB, expectedResult: allMatchingCids) and similarly for "Jõao" to cover
both diacritic-insensitive paths.

Copy link
Member

@nuno-vieira nuno-vieira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laevandus laevandus enabled auto-merge (squash) February 25, 2026 07:25
@github-actions
Copy link

Public Interface

🚀 No changes affecting the public interface.

@Stream-SDK-Bot
Copy link
Collaborator

SDK Size

title develop branch diff status
StreamChat 8.58 MB 8.58 MB 0 KB 🟢
StreamChatUI 4.91 MB 4.91 MB 0 KB 🟢

@sonarqubecloud
Copy link

@laevandus laevandus merged commit 5fd4430 into develop Feb 25, 2026
14 checks passed
@laevandus laevandus deleted the fix/diacritic-matching-in-autocomplete branch February 25, 2026 08:14
@Stream-SDK-Bot Stream-SDK-Bot mentioned this pull request Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants