Commit 727a285f authored by Miguel de la Cruz's avatar Miguel de la Cruz Committed by Miguel de la Cruz

[MM-14881] Modify filterProfilesMatchingTerm to match split parts of the username (#808)

parent e2cf2b18
......@@ -18,6 +18,7 @@ export default {
STATUS_INTERVAL: 60000,
AUTOCOMPLETE_LIMIT_DEFAULT: 25,
AUTOCOMPLETE_SPLIT_CHARACTERS: ['.', '-', '_'],
MENTION: 'mention',
......
......@@ -6,4 +6,4 @@ export default {
IGNORE_CHANNEL_MENTIONS_ON: 'on',
IGNORE_CHANNEL_MENTIONS_OFF: 'off',
IGNORE_CHANNEL_MENTIONS_DEFAULT: 'default',
};
\ No newline at end of file
};
......@@ -96,6 +96,22 @@ export function removeUserFromList(userId: $ID<UserProfile>, list: Array<UserPro
return list;
}
// Splits the term by a splitStr and composes a list of the parts of
// the split concatenated with the rest, forming a set of suggesitons
// matchable with startsWith
//
// E.g.: for "one.two.three" by "." it would yield
// ["one.two.three", "two.three", "three"]
export function getSuggestionsSplitBy(term: string, splitStr: string): Array<string> {
const splitTerm = term.split(splitStr);
return splitTerm.map((st, i) => splitTerm.slice(i).join(splitStr));
}
export function getSuggestionsSplitByMultiple(term: string, splitStrs: Array<string>): Array<string> {
// $FlowFixMe - Array.flatMap is not yet implemented in Flow
return [...new Set(splitStrs.flatMap((splitStr) => getSuggestionsSplitBy(term, splitStr)))];
}
export function filterProfilesMatchingTerm(users: Array<UserProfile>, term: string): Array<UserProfile> {
const lowercasedTerm = term.toLowerCase();
let trimmedTerm = lowercasedTerm;
......@@ -107,25 +123,27 @@ export function filterProfilesMatchingTerm(users: Array<UserProfile>, term: stri
if (!user) {
return false;
}
const username = (user.username || '').toLowerCase();
const profileSuggestions = [];
const usernameSuggestions = getSuggestionsSplitByMultiple((user.username || '').toLowerCase(), General.AUTOCOMPLETE_SPLIT_CHARACTERS);
profileSuggestions.push(...usernameSuggestions);
const first = (user.first_name || '').toLowerCase();
const last = (user.last_name || '').toLowerCase();
const full = first + ' ' + last;
profileSuggestions.push(first, last, full);
profileSuggestions.push((user.nickname || '').toLowerCase());
const email = (user.email || '').toLowerCase();
const nickname = (user.nickname || '').toLowerCase();
profileSuggestions.push(email);
profileSuggestions.push((user.nickname || '').toLowerCase());
let emailDomain = '';
const split = email.split('@');
if (split.length > 1) {
emailDomain = split[1];
profileSuggestions.push(split[1]);
}
return username.startsWith(trimmedTerm) ||
full.startsWith(trimmedTerm) ||
last.startsWith(lowercasedTerm) ||
nickname.startsWith(trimmedTerm) ||
email.startsWith(lowercasedTerm) ||
emailDomain.startsWith(trimmedTerm);
return profileSuggestions.
filter((suggestion) => suggestion !== '').
some((suggestion) => suggestion.startsWith(trimmedTerm));
});
}
......
......@@ -4,7 +4,12 @@
import assert from 'assert';
import {Preferences} from 'constants';
import {displayUsername, filterProfilesMatchingTerm} from 'utils/user_utils';
import {
displayUsername,
filterProfilesMatchingTerm,
getSuggestionsSplitBy,
getSuggestionsSplitByMultiple,
} from 'utils/user_utils';
describe('user utils', () => {
describe('displayUsername', () => {
......@@ -53,14 +58,14 @@ describe('user utils', () => {
describe('filterProfilesMatchingTerm', () => {
const userA = {
id: 100,
username: 'testUser',
username: 'testUser.split_10-',
nickname: 'nick',
first_name: 'First',
last_name: 'Last1',
};
const userB = {
id: 101,
username: 'extraPerson',
username: 'extraPerson-split',
nickname: 'somebody',
first_name: 'First',
last_name: 'Last2',
......@@ -80,6 +85,11 @@ describe('user utils', () => {
assert.deepEqual(filterProfilesMatchingTerm(users, 'testUser'), [userA]);
});
it('should match by split part of the username', () => {
assert.deepEqual(filterProfilesMatchingTerm(users, 'split'), [userA, userB]);
assert.deepEqual(filterProfilesMatchingTerm(users, '10'), [userA]);
});
it('should match by firstname', () => {
assert.deepEqual(filterProfilesMatchingTerm(users, 'First'), [userA, userB]);
});
......@@ -132,4 +142,22 @@ describe('user utils', () => {
assert.deepEqual(filterProfilesMatchingTerm(users, '@first'), [userA, userB]);
});
});
describe('Utils.getSuggestionsSplitBy', () => {
test('correct suggestions when splitting by a character', () => {
const term = 'one.two.three';
const expectedSuggestions = ['one.two.three', 'two.three', 'three'];
expect(getSuggestionsSplitBy(term, '.')).toEqual(expectedSuggestions);
});
});
describe('Utils.getSuggestionsSplitByMultiple', () => {
test('correct suggestions when splitting by multiple characters', () => {
const term = 'one.two-three';
const expectedSuggestions = ['one.two-three', 'two-three', 'three'];
expect(getSuggestionsSplitByMultiple(term, ['.', '-'])).toEqual(expectedSuggestions);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment