Commit 984d8383 authored by Eulyeon Ko's avatar Eulyeon Ko

Add guard for falsey values

gl-emoji, a web component, may lack data-name attribute sometimes
and this can cause getEmoji()/searchEmoji() -
to receive undefined value when initializing emoji,
leading "toLowerCase()" to be called on undefined value.
(which in turn causes console error)

Returning null when query isn't defined in these functions -
solves the above problem.
parent 49b0576d
...@@ -82,6 +82,12 @@ export function getAllEmoji() { ...@@ -82,6 +82,12 @@ export function getAllEmoji() {
* @returns {Object} The matching emoji. * @returns {Object} The matching emoji.
*/ */
export function getEmoji(query, fallback = false) { export function getEmoji(query, fallback = false) {
// TODO https://gitlab.com/gitlab-org/gitlab/-/issues/268208
const fallbackEmoji = emojiMap.grey_question;
if (!query) {
return fallback ? fallbackEmoji : null;
}
if (!emojiMap) { if (!emojiMap) {
// eslint-disable-next-line @gitlab/require-i18n-strings // eslint-disable-next-line @gitlab/require-i18n-strings
throw new Error('The emoji map is uninitialized or initialization has not completed'); throw new Error('The emoji map is uninitialized or initialization has not completed');
...@@ -94,11 +100,7 @@ export function getEmoji(query, fallback = false) { ...@@ -94,11 +100,7 @@ export function getEmoji(query, fallback = false) {
return emojiMap[name]; return emojiMap[name];
} }
if (fallback) { return fallback ? fallbackEmoji : null;
return emojiMap.grey_question;
}
return null;
} }
const searchMatchers = { const searchMatchers = {
...@@ -178,6 +180,15 @@ export function searchEmoji(query, opts) { ...@@ -178,6 +180,15 @@ export function searchEmoji(query, opts) {
raw = false, raw = false,
} = opts || {}; } = opts || {};
const fallbackEmoji = emojiMap.grey_question;
if (!query) {
if (fallback) {
return raw ? [{ emoji: fallbackEmoji }] : [fallbackEmoji];
}
return [];
}
// optimization for an exact match in name and alias // optimization for an exact match in name and alias
if (match === 'exact' && new Set([...fields, 'name', 'alias']).size === 2) { if (match === 'exact' && new Set([...fields, 'name', 'alias']).size === 2) {
const emoji = getEmoji(query, fallback); const emoji = getEmoji(query, fallback);
...@@ -193,16 +204,10 @@ export function searchEmoji(query, opts) { ...@@ -193,16 +204,10 @@ export function searchEmoji(query, opts) {
// Fallback to question mark for unknown emojis // Fallback to question mark for unknown emojis
if (fallback && results.length === 0) { if (fallback && results.length === 0) {
if (raw) { return raw ? [{ emoji: fallbackEmoji }] : [fallbackEmoji];
return [{ emoji: emojiMap.grey_question }];
}
return [emojiMap.grey_question];
} }
if (raw) { return raw ? results : results.map(r => r.emoji);
return results;
}
return results.map(r => r.emoji);
} }
let emojiCategoryMap; let emojiCategoryMap;
......
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import { emojiFixtureMap, initEmojiMock, describeEmojiFields } from 'helpers/emoji'; import { emojiFixtureMap, initEmojiMock, describeEmojiFields } from 'helpers/emoji';
import { glEmojiTag, searchEmoji } from '~/emoji'; import { glEmojiTag, searchEmoji, getEmoji } from '~/emoji';
import isEmojiUnicodeSupported, { import isEmojiUnicodeSupported, {
isFlagEmoji, isFlagEmoji,
isRainbowFlagEmoji, isRainbowFlagEmoji,
...@@ -352,6 +352,20 @@ describe('gl_emoji', () => { ...@@ -352,6 +352,20 @@ describe('gl_emoji', () => {
}); });
}); });
describe('getEmoji', () => {
const { grey_question } = emojiFixtureMap;
describe('when query is undefined', () => {
it('should return null by default', () => {
expect(getEmoji()).toBe(null);
});
it('should return fallback emoji when fallback is true', () => {
expect(getEmoji(undefined, true).name).toEqual(grey_question.name);
});
});
});
describe('searchEmoji', () => { describe('searchEmoji', () => {
const { atom, grey_question } = emojiFixtureMap; const { atom, grey_question } = emojiFixtureMap;
const search = (query, opts) => searchEmoji(query, opts).map(({ name }) => name); const search = (query, opts) => searchEmoji(query, opts).map(({ name }) => name);
...@@ -382,6 +396,10 @@ describe('gl_emoji', () => { ...@@ -382,6 +396,10 @@ describe('gl_emoji', () => {
it('should not return a fallback value', () => { it('should not return a fallback value', () => {
expect(subject('foo bar baz')).toHaveLength(0); expect(subject('foo bar baz')).toHaveLength(0);
}); });
it('should not return a fallback value when query is falsey', () => {
expect(subject()).toHaveLength(0);
});
}); });
describe('with fuzzy match', () => { describe('with fuzzy match', () => {
...@@ -427,8 +445,12 @@ describe('gl_emoji', () => { ...@@ -427,8 +445,12 @@ describe('gl_emoji', () => {
describe('with fallback', () => { describe('with fallback', () => {
const subject = query => search(query, { fallback: true }); const subject = query => search(query, { fallback: true });
it('should return a fallback value', () => it.each`
expect(subject('foo bar baz')).toContain(grey_question.name)); query
${'foo bar baz'} | ${undefined}
`('should return a fallback value when given $query', ({ query }) => {
expect(subject(query)).toContain(grey_question.name);
});
}); });
describe('with name and alias fields', () => { describe('with name and alias fields', () => {
......
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