[MM-63582] Recent Mentions Not Properly Handling Hyphenated Custom Keywords (#30578)

* quote all terms for better recent mentions accuracy

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Vishal 2025-04-09 16:08:25 +05:30 committed by GitHub
parent a6492b5b9f
commit 204fec42e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 11 additions and 17 deletions

1
webapp/.gitignore vendored
View file

@ -12,3 +12,4 @@ platform/*/dist
platform/*/lib
config.override.mk
build

View file

@ -13,6 +13,7 @@ import type {IDMappedObjects} from '@mattermost/types/utilities';
import {SearchTypes} from 'mattermost-redux/action_types';
import * as SearchActions from 'mattermost-redux/actions/search';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {trackEvent} from 'actions/telemetry_actions.jsx';
import {
@ -45,7 +46,7 @@ import {
import mockStore from 'tests/test_store';
import {ActionTypes, RHSStates, Constants} from 'utils/constants';
import {TestHelper} from 'utils/test_helper';
import {getBrowserUtcOffset} from 'utils/timezone';
import {getUtcOffsetForTimeZone} from 'utils/timezone';
import type {GlobalState} from 'types/store';
import type {RhsState} from 'types/store/rhs';
@ -109,7 +110,7 @@ describe('rhs view actions', () => {
first_name: currentUserFirstName,
timezone: {
useAutomaticTimezone: true,
automaticTimezone: '',
automaticTimezone: 'UTC+3', // set an arbitrary timezone
manualTimezone: '',
},
} as UserProfile,
@ -221,7 +222,7 @@ describe('rhs view actions', () => {
describe('performSearch', () => {
// timezone offset in seconds
let timeZoneOffset = getBrowserUtcOffset() * 60;
let timeZoneOffset = getUtcOffsetForTimeZone(getCurrentTimezone(initialState)) * 60;
// Avoid problems with negative cero
if (timeZoneOffset === 0) {
@ -263,10 +264,10 @@ describe('rhs view actions', () => {
});
test('it dispatches searchPosts correctly for Recent Mentions', () => {
const terms = `@here test search ${currentUsername} @${currentUsername} ${currentUserFirstName}`;
const terms = `@here test search ${currentUsername} @${currentUsername} ${currentUserFirstName} custom-hyphenated-term`;
store.dispatch(performSearch(terms, '', true));
const mentionsQuotedTerms = `@here test search "${currentUsername}" "@${currentUsername}" "${currentUserFirstName}"`;
const mentionsQuotedTerms = `"@here" "test" "search" "${currentUsername}" "@${currentUsername}" "${currentUserFirstName}" "custom-hyphenated-term"`;
const compareStore = mockStore(initialState);
compareStore.dispatch(SearchActions.searchPostsWithParams('', {include_deleted_channels: false, terms: mentionsQuotedTerms, is_or_search: true, time_zone_offset: timeZoneOffset, page: 0, per_page: 20}));
compareStore.dispatch(SearchActions.searchFilesWithParams('', {include_deleted_channels: false, terms, is_or_search: true, time_zone_offset: timeZoneOffset, page: 0, per_page: 20}));

View file

@ -22,7 +22,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getLatestInteractablePostId, getPost} from 'mattermost-redux/selectors/entities/posts';
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUser, getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
import {getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
import {trackEvent} from 'actions/telemetry_actions.jsx';
import {
@ -222,19 +222,11 @@ export function performSearch(terms: string, teamId: string, isMentionSearch?: b
}
if (isMentionSearch) {
// Username and FirstName should be quoted to allow specific search
// in case the name is made with multiple words splitted by dashes or other symbols.
const user = getCurrentUser(getState());
// For mentions, perform a specific search by quoting all terms.
// This ensures terms split by dashes or other symbols are treated as a single unit.
const termsArr = searchTerms.split(' ').filter((t) => Boolean(t && t.trim()));
const atUsername = '@' + user.username;
for (let i = 0; i < termsArr.length; i++) {
if (termsArr[i] === atUsername) {
termsArr[i] = `"${atUsername}"`;
} else if (termsArr[i] === user.username) {
termsArr[i] = `"${user.username}"`;
} else if (termsArr[i] === user.first_name) {
termsArr[i] = `"${user.first_name}"`;
}
termsArr[i] = `"${termsArr[i]}"`;
}
searchTerms = termsArr.join(' ');
}