Skip to content

Commit c41ed97

Browse files
committed
boxes: Use user_ids in autocomplete for ambiguous user mentions.
Prior to this commit, user mentions through autocomplete used only names in the typeahead. This commit appends `user_id`s to all the multiple instances of the same name to use the **Name|User_id** format of user mentions. The appended user_id would serve as a distinction between users having the same name. Tests added and updated.
1 parent 7443839 commit c41ed97

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

tests/ui_tools/test_boxes.py

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,19 @@ def test_generic_autocomplete_set_footer(self, mocker, write_box,
128128
('@Human', 0, '@**Human Myself**'),
129129
('@Human', 1, '@**Human 1**'),
130130
('@Human', 2, '@**Human 2**'),
131-
('@Human', 3, '@**Human Duplicate**'),
132-
('@Human', 4, '@**Human Duplicate**'),
133-
('@Human', -1, '@**Human Duplicate**'),
134-
('@Human', -2, '@**Human Duplicate**'),
131+
('@Human', 3, '@**Human Duplicate|13**'),
132+
('@Human', 4, '@**Human Duplicate|14**'),
133+
('@Human', -1, '@**Human Duplicate|14**'),
134+
('@Human', -2, '@**Human Duplicate|13**'),
135135
('@Human', -3, '@**Human 2**'),
136136
('@Human', -4, '@**Human 1**'),
137137
('@Human', -5, '@**Human Myself**'),
138138
('@Human', -6, None),
139139
('@_Human', 0, '@_**Human Myself**'),
140140
('@_Human', 1, '@_**Human 1**'),
141141
('@_Human', 2, '@_**Human 2**'),
142-
('@_Human', 3, '@_**Human Duplicate**'),
143-
('@_Human', 4, '@_**Human Duplicate**'),
142+
('@_Human', 3, '@_**Human Duplicate|13**'),
143+
('@_Human', 4, '@_**Human Duplicate|14**'),
144144
('@H', 1, '@**Human 1**'),
145145
('@Hu', 1, '@**Human 1**'),
146146
('@Hum', 1, '@**Human 1**'),
@@ -167,8 +167,8 @@ def test_generic_autocomplete_set_footer(self, mocker, write_box,
167167
('@', 0, '@**Human Myself**'),
168168
('@', 1, '@**Human 1**'),
169169
('@', 2, '@**Human 2**'),
170-
('@', 3, '@**Human Duplicate**'),
171-
('@', 4, '@**Human Duplicate**'),
170+
('@', 3, '@**Human Duplicate|13**'),
171+
('@', 4, '@**Human Duplicate|14**'),
172172
('@', 5, '@*Group 1*'),
173173
('@', 6, '@*Group 2*'),
174174
('@', 7, '@*Group 3*'),
@@ -179,8 +179,8 @@ def test_generic_autocomplete_set_footer(self, mocker, write_box,
179179
('@**', 0, '@**Human Myself**'),
180180
('@**', 1, '@**Human 1**'),
181181
('@**', 2, '@**Human 2**'),
182-
('@', 3, '@**Human Duplicate**'),
183-
('@', 4, '@**Human Duplicate**'),
182+
('@', 3, '@**Human Duplicate|13**'),
183+
('@', 4, '@**Human Duplicate|14**'),
184184
('@**', 5, None), # Reached last match
185185
('@**', 6, None), # Beyond end
186186
# Expected sequence of autocompletes from '@*' (only groups)
@@ -194,11 +194,11 @@ def test_generic_autocomplete_set_footer(self, mocker, write_box,
194194
('@_', 0, '@_**Human Myself**'), # NOTE: No silent group mention
195195
('@_', 1, '@_**Human 1**'),
196196
('@_', 2, '@_**Human 2**'),
197-
('@_', 3, '@_**Human Duplicate**'),
198-
('@_', 4, '@_**Human Duplicate**'),
197+
('@_', 3, '@_**Human Duplicate|13**'),
198+
('@_', 4, '@_**Human Duplicate|14**'),
199199
('@_', 5, None), # Reached last match
200200
('@_', 6, None), # Beyond end
201-
('@_', -1, '@_**Human Duplicate**'),
201+
('@_', -1, '@_**Human Duplicate|14**'),
202202
# Complex autocomplete prefixes.
203203
('(@H', 0, '(@**Human Myself**'),
204204
('(@H', 1, '(@**Human 1**'),
@@ -242,6 +242,49 @@ def test_generic_autocomplete_mentions_subscribers(self, write_box, text,
242242
typeahead_string = write_box.generic_autocomplete(text, state)
243243
assert typeahead_string == required_typeahead
244244

245+
@pytest.mark.parametrize('text', [
246+
'@H', '@Hu', '@Hum', '@Huma', '@Human',
247+
'@**', '@**H', '@**Hu', '@**Hum', '@**Huma', '@**Human'
248+
])
249+
@pytest.mark.parametrize('matching_users, distinct_matching_users', [
250+
(['Human Myself', 'Human 1', 'Human 2', 'Human Duplicate',
251+
'Human Duplicate'],
252+
['@**Human Myself**', '@**Human 1**', '@**Human 2**',
253+
'@**Human Duplicate|13**', '@**Human Duplicate|14**'])
254+
])
255+
def test_generic_autocomplete_user_mentions(self, write_box, text, mocker,
256+
distinct_matching_users,
257+
matching_users, state=1):
258+
_process_typeaheads = mocker.patch(BOXES
259+
+ '.WriteBox._process_typeaheads')
260+
261+
write_box.generic_autocomplete(text, state)
262+
263+
_process_typeaheads.assert_called_once_with(distinct_matching_users,
264+
state, matching_users)
265+
266+
@pytest.mark.parametrize('text', [
267+
'@_', '@_H', '@_Hu', '@_Hum', '@_Huma', '@_Human'
268+
])
269+
@pytest.mark.parametrize('matching_users, distinct_matching_users', [
270+
(['Human Myself', 'Human 1', 'Human 2', 'Human Duplicate',
271+
'Human Duplicate'],
272+
['@_**Human Myself**', '@_**Human 1**', '@_**Human 2**',
273+
'@_**Human Duplicate|13**', '@_**Human Duplicate|14**'])
274+
])
275+
def test_generic_autocomplete_silent_user_mentions(self, write_box, text,
276+
mocker,
277+
matching_users,
278+
distinct_matching_users,
279+
state=1):
280+
_process_typeaheads = mocker.patch(BOXES
281+
+ '.WriteBox._process_typeaheads')
282+
283+
write_box.generic_autocomplete(text, state)
284+
285+
_process_typeaheads.assert_called_once_with(distinct_matching_users,
286+
state, matching_users)
287+
245288
@pytest.mark.parametrize('text, state, required_typeahead, to_pin', [
246289
# With no streams pinned.
247290
('#Stream', 0, '#**Stream 1**', []), # 1st-word startswith match.

zulipterminal/ui_tools/boxes.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,11 +445,23 @@ def autocomplete_users(self, text: str, prefix_string: str
445445
reverse=True)
446446

447447
user_names = [user['full_name'] for user in sorted_matching_users]
448+
449+
user_name_duplicates = [user_name
450+
for count, user_name in enumerate(user_names)
451+
if user_name in user_names[:count]]
452+
453+
user_names_with_distinct_duplicates = [
454+
f"{user['full_name']}|{user['user_id']}"
455+
if user['full_name'] in user_name_duplicates
456+
else user['full_name']
457+
for user in sorted_matching_users
458+
]
459+
448460
extra_prefix = "{}{}".format(
449461
'*' if prefix_string[-1] != '*' else '',
450462
'*' if prefix_string[-2:] != '**' else '',
451463
)
452-
user_typeahead = format_string(user_names,
464+
user_typeahead = format_string(user_names_with_distinct_duplicates,
453465
prefix_string + extra_prefix + '{}**')
454466

455467
return user_typeahead, user_names

0 commit comments

Comments
 (0)