diff --git a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx
index 87ca407d2e..d9678ffead 100644
--- a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx
+++ b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx
@@ -12,6 +12,8 @@ import PostAttachmentContainer from './post_attachment_container';
import type {Props} from './post_attachment_container';
describe('PostAttachmentContainer', () => {
+ const mockHistoryPush = jest.fn();
+
const baseProps: Props = {
children:
{'some children'}
,
className: 'permalink',
@@ -31,11 +33,19 @@ describe('PostAttachmentContainer', () => {
},
posts: {posts: {}},
preferences: {myPreferences: {}},
-
},
-
};
+ beforeEach(() => {
+ mockHistoryPush.mockClear();
+
+ // Mock useHistory
+ jest.doMock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useHistory: () => ({push: mockHistoryPush}),
+ }));
+ });
+
test('should render correctly', () => {
renderWithContext(
, initialState,
@@ -48,4 +58,58 @@ describe('PostAttachmentContainer', () => {
expect(screen.getByText('some children')).toBeInTheDocument();
});
+
+ test('should handle clicks on elements with non-string className without throwing error', () => {
+ renderWithContext(
+ , initialState,
+ );
+
+ const button = screen.getByRole('button');
+
+ // Create a real DOM element and modify its className to be an object
+ const mockElement = document.createElement('div');
+ Object.defineProperty(mockElement, 'className', {
+ value: {baseVal: 'some-class'},
+ writable: false,
+ });
+ Object.defineProperty(mockElement, 'tagName', {
+ value: 'DIV',
+ writable: false,
+ });
+
+ const mockEvent = {
+ target: mockElement,
+ stopPropagation: jest.fn(),
+ } as any;
+
+ // This should not throw the "className.includes is not a function" error
+ expect(() => {
+ button.onclick?.(mockEvent);
+ }).not.toThrow();
+ });
+
+ test('should handle clicks on elements without className property', () => {
+ renderWithContext(
+ , initialState,
+ );
+
+ const button = screen.getByRole('button');
+
+ // Create a real DOM element and remove its className
+ const mockElement = document.createElement('div');
+ delete (mockElement as any).className;
+ Object.defineProperty(mockElement, 'tagName', {
+ value: 'DIV',
+ writable: false,
+ });
+
+ const mockEvent = {
+ target: mockElement,
+ stopPropagation: jest.fn(),
+ } as any;
+
+ expect(() => {
+ button.onclick?.(mockEvent);
+ }).not.toThrow();
+ });
});
diff --git a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.tsx b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.tsx
index 7d546288cf..027dc62504 100644
--- a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.tsx
+++ b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.tsx
@@ -31,6 +31,22 @@ const getTeamAndPostIdFromLink = (link: string) => {
return match?.params;
};
+const getElementClassName = (element: EventTarget | null): string => {
+ if (!element || !(element instanceof Element)) {
+ return '';
+ }
+
+ if (typeof element.className === 'object' && 'baseVal' in element.className) {
+ return (element.className as any).baseVal;
+ }
+
+ if (typeof element.className === 'string') {
+ return element.className;
+ }
+
+ return '';
+};
+
const PostAttachmentContainer = (props: Props) => {
const {children, className, link, preventClickAction} = props;
const history = useHistory();
@@ -48,11 +64,12 @@ const PostAttachmentContainer = (props: Props) => {
const {tagName} = e.target;
e.stopPropagation();
const elements = ['A', 'IMG', 'BUTTON', 'I'];
+ const targetClassName = getElementClassName(e.target);
if (
!elements.includes(tagName) &&
e.target.getAttribute('role') !== 'button' &&
- e.target.className !== `attachment attachment--${className}`
+ targetClassName !== `attachment attachment--${className}`
) {
const classNames = [
'icon icon-menu-down',
@@ -65,7 +82,7 @@ const PostAttachmentContainer = (props: Props) => {
dispatch(focusPost(params.postId, link, currentUserId, {skipRedirectReplyPermalink: true}));
return;
}
- if (!classNames.some((className) => e.target.className.includes(className)) && e.target.id !== 'image-name-text') {
+ if (!classNames.some((className) => targetClassName.includes(className)) && e.target.id !== 'image-name-text') {
history.push(link);
}
}