From 11022322d67afb45d4c62cfa1df8c26c8f9718be Mon Sep 17 00:00:00 2001 From: Rahim Rahman Date: Mon, 27 Jan 2025 11:01:08 -0700 Subject: [PATCH] fix(MM-60645): missing bookmark emoji (#8518) * fix(MM-60645): missing bookmark emoji * add test --- .../channel_bookmark/bookmark_icon.test.tsx | 117 ++++++++++++++++++ .../channel_bookmark/bookmark_icon.tsx | 7 +- app/components/files/file_icon.tsx | 8 +- 3 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 app/components/channel_bookmarks/channel_bookmark/bookmark_icon.test.tsx diff --git a/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.test.tsx b/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.test.tsx new file mode 100644 index 000000000..3aff159ea --- /dev/null +++ b/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.test.tsx @@ -0,0 +1,117 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {act, renderWithIntl} from '@test/intl-test-helper'; + +import BookmarkIcon from './bookmark_icon'; + +jest.mock('@context/theme', () => ({ + useTheme: () => ({ + centerChannelColor: '#000', + }), +})); +jest.mock('@components/emoji', () => 'Emoji'); + +describe('components/channel_bookmarks/channel_bookmark/BookmarkIcon', () => { + const baseProps = { + emojiSize: 24, + iconSize: 22, + genericStyle: {}, + }; + + it('renders default bookmark icon when no specific content provided', () => { + const {getByTestId} = renderWithIntl( + , + ); + + expect(getByTestId('bookmark-generic-icon')).toBeOnTheScreen(); + }); + + it('renders FileIcon when file prop is provided', () => { + const props = { + ...baseProps, + file: { + id: 'file1', + name: 'test.pdf', + extension: 'pdf', + } as unknown as FileInfo, + }; + + const {getByTestId} = renderWithIntl( + , + ); + + expect(getByTestId('bookmark-file-icon')).toBeOnTheScreen(); + }); + + it('renders Image when imageUrl is provided', () => { + const props = { + ...baseProps, + imageUrl: 'https://example.com/image.jpg', + imageStyle: {width: 40, height: 40}, + }; + + const {getByTestId} = renderWithIntl( + , + ); + + expect(getByTestId('bookmark-image')).toBeOnTheScreen(); + }); + + it('renders Emoji when emoji prop is provided', () => { + const props = { + ...baseProps, + emoji: 'smile', + emojiStyle: {fontSize: 20}, + }; + + const {getByTestId} = renderWithIntl( + , + ); + + const emojiComponent = getByTestId('bookmark-emoji'); + expect(emojiComponent).toBeOnTheScreen(); + expect(emojiComponent.props.emojiName).toBe('smile'); + }); + + it('renders Emoji when emoji prop with `:` is provided', () => { + const props = { + ...baseProps, + emoji: ':computer-rage:', + emojiStyle: {fontSize: 20}, + }; + + const {getByTestId} = renderWithIntl( + , + ); + + const emojiComponent = getByTestId('bookmark-emoji'); + expect(emojiComponent).toBeOnTheScreen(); + expect(emojiComponent.props.emojiName).toBe('computer-rage'); + }); + + it('falls back to default icon when image fails to load', () => { + const props = { + ...baseProps, + imageUrl: 'https://example.com/invalid.jpg', + }; + + const {getByTestId} = renderWithIntl( + , + ); + + const image = getByTestId('bookmark-image'); + const mockErrorEvent = { + nativeEvent: { + error: new Error('Image failed to load'), + }, + }; + act(() => { + image.props.onError(mockErrorEvent); + }); + + expect(getByTestId('bookmark-generic-icon')).toBeOnTheScreen(); + }); +}); diff --git a/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.tsx b/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.tsx index 8ff4333b6..1b30ba721 100644 --- a/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.tsx +++ b/app/components/channel_bookmarks/channel_bookmark/bookmark_icon.tsx @@ -32,6 +32,7 @@ const BookmarkIcon = ({emoji, emojiSize, emojiStyle, file, genericStyle, iconSiz if (file && !emoji && !hasImageError) { return ( ); } else if (emoji) { + const sanitizedEmoji = emoji.replace(/:/g, ''); return ( @@ -61,6 +65,7 @@ const BookmarkIcon = ({emoji, emojiSize, emojiStyle, file, genericStyle, iconSiz size={22} color={theme.centerChannelColor} style={genericStyle} + testID='bookmark-generic-icon' /> ); }; diff --git a/app/components/files/file_icon.tsx b/app/components/files/file_icon.tsx index a47255ace..6c731e70c 100644 --- a/app/components/files/file_icon.tsx +++ b/app/components/files/file_icon.tsx @@ -16,6 +16,7 @@ type FileIconProps = { iconColor?: string; iconSize?: number; smallImage?: boolean; + testID?: string; } const BLUE_ICON = '#338AFF'; @@ -49,7 +50,7 @@ const styles = StyleSheet.create({ const FileIcon = ({ backgroundColor, defaultImage = false, failed = false, file, - iconColor, iconSize = 48, smallImage = false, + iconColor, iconSize = 48, smallImage = false, testID = 'file-icon', }: FileIconProps) => { const theme = useTheme(); const getFileIconNameAndColor = () => { @@ -78,7 +79,10 @@ const FileIcon = ({ const bgColor = backgroundColor || theme?.centerChannelBg || 'transparent'; return ( - +