Issue 19058 - Sort user-mentions suggestions by prefix first, then alphabetically#19218
Conversation
516c39d to
3f8c2ce
Compare
…s sorted correctly
hassaanelgarem
left a comment
There was a problem hiding this comment.
I think we can do two things differently:
- Doing a case insensitive search instead of case-sensitive
- Look for the prefix in both the username and the display name
@igoriols What do you think?
| @@ -0,0 +1,7 @@ | |||
| extension UserSuggestion: Comparable { | |||
| public static func < (lus: UserSuggestion, rus: UserSuggestion) -> Bool { | |||
There was a problem hiding this comment.
[Nit]
| public static func < (lus: UserSuggestion, rus: UserSuggestion) -> Bool { | |
| public static func < (lhs: UserSuggestion, rhs: UserSuggestion) -> Bool { |
There was a problem hiding this comment.
I'm curious, what do lus and ldn stand for?
There was a problem hiding this comment.
lus: left user suggestion
rus: right user suggestion
ldn: left display name
rdn: right display name
I thought it would be better than the standard lhs (left-hand side) and rhs (right-hand side), but I can change to use lhs and rhs. I can apply more meaningful names to the unwrapped display names, also.
| var otherUserSuggestions = [UserSuggestion]() | ||
|
|
||
| userSuggestions.forEach { suggestion in | ||
| guard let displayName = suggestion.displayName else { return } |
There was a problem hiding this comment.
This is a corner case, but if the user doesn't have a display name for some reason, they will be filtered out completely. I think we should add them to otherUserSuggestions in that case. Wdyt?
There was a problem hiding this comment.
Yes, that is a good idea. I'm going to apply it.
| } | ||
| } | ||
|
|
||
| private static func sort(userSuggestions: [UserSuggestion], by searchQuery: String) -> [UserSuggestion] { |
There was a problem hiding this comment.
Can you add a brief documentation of what's happening here? 🙏
There was a problem hiding this comment.
Sure. It's done. Thank you for reminding me.
…and add documentation to the method sort
Hi @hassaanelgarem. Just to make sure I understand.
|
| if let displayName = suggestion.displayName, | ||
| (username.beginsWith(prefix: prefix) || displayName.beginsWith(prefix: prefix)) { | ||
| prefixedUserSuggestions.append(suggestion) |
There was a problem hiding this comment.
This will skip users with a nil displayName… even if they have a username that begins with the prefix.
So {"ID":102,"user_login":"carlosdiaz","display_name":null} will not be found even if prefix is carl here, because let displayName = suggestion.displayName will be false and exit the condition already.
Is that intentional? Do we want to prioritize only the users who have a non-nil display name?
If not, this condition will need to be adjusted accordingly 🙂 (and it would be nice to use the occasion to add a test case for this while we're at it 😉 )
There was a problem hiding this comment.
Nice catch. The idea was to have users with a username or a displayName beginning with the prefix first. I think your dictionary approach suggestion will cover that. I will add a new entry to test this scenario, also.
hassaanelgarem
left a comment
There was a problem hiding this comment.
Works as expected 🚀
AliSoftware
left a comment
There was a problem hiding this comment.
Overall good, nice job!
Left a couple of nitpick suggestions (up to you to apply or not), and also a suggestion for additional test cases. But other than that this LGTM 👍
| @@ -119,7 +119,7 @@ class SuggestionsListViewModelTests: CoreDataTestCase { | |||
| func testSearchSuggestionsWithPartialMatch() throws { | |||
| // Given | |||
| let word = "@ca" | |||
There was a problem hiding this comment.
💡 I notice that you don't have tests that contains diacritics or uppercase letters as prefix. Which means we don't cover the cases of things like @Ca, or ensure that e.g. @Caa would match user with display name "Caárla Diaz".
Could be nice to add some coverage for that, especially given you were thoughtful in the implementation to implement case-insensitive and diacritics-insensitive comparison for display Name (but not for user name), so would be nice to test for it to ensure there won't be an accidental regression for that aspect in the future.
There was a problem hiding this comment.
Nice catch. I added more tests to cover more scenarios. Thank you!
WordPress/WordPressTest/Mention/SuggestionsListViewModelTests.swift
Outdated
Show resolved
Hide resolved
|
Just thought of some edge cases (though that one should probably be for a separate PR rather than this one): how does this whole thing behaves with RTL and non-Latin languages?
To be clear, all of those cases/open questions are (1) likely out of scope for this PR (2) might not all be worth actually fixing or even investigating, even in a separate PR — as I'm probably overthinking some of those cases. Still, I just thought I'd braindump those here to raise the question and see if it's worth checking/ investigating those cases or not. 🙃 |
There was a problem hiding this comment.
Apart from the small 💄 typo in the test comments, this looks ready to merge to me now. Nice work 👍
|
@igoriols I updated the milestone to 20.8 since we won't catch the code freeze. Please update the release note accordingly 🙏 |
|
@igoriols just wanted to let you know that WordPress 20.8, the first version with your changes from this PR, just started rolling out to users. Thank you so much for your contribution! 🎉 |
Closes #19058
Description
In this PR, I'm addressing the sorting change requested. I'm displaying first the users whose names begin with a prefix provided by the user, then alphabetically. The first criteria are to sort alphabetically by users whose usernames or display names begin with the provided prefix. If both username and display name begin with the prefix, the display name will be prioritized in the sorting.
Details
I’m using localizedCaseInsensitiveCompare to compare
displayNames, because the user can have the displayName in different languages. The comparison is localizable and case-insensitive.I’m using
<to compare usernames because they are very restricted, and the lexicographical comparison should work for them.I'm looping through the
UserSuggestionsarray to create two sub-arrays. The first one has the users whose display names begin with a prefix provided by the user. The second one has the users whose display names don't begin with the prefix provided by the user.I'm sorting both arrays alphabetically, then I combine the sorted arrays.
I updated the tests to conform with the new sorting criteria.
Preview
Testing Instructions
N.B: The user-mentions suggestions feature is not enabled in self-hosted sites ( wordpress.org ).
There are other scenarios to display the user-mentions suggestions list described in #18979.
Regression Notes
Potential unintended areas of impact
N/A
What I did to test those areas of impact (or what existing automated tests I relied on)
N/A
What automated tests I added (or what prevented me from doing so)
I updated the existing tests related to the user-mentions suggestions list.
PR submission checklist:
RELEASE-NOTES.txtif necessary.