Automatic Merge
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
7eda0e799c
Коммит
6cbcf4e290
@@ -12,6 +12,8 @@ import PostAttachmentContainer from './post_attachment_container';
|
|||||||
import type {Props} from './post_attachment_container';
|
import type {Props} from './post_attachment_container';
|
||||||
|
|
||||||
describe('PostAttachmentContainer', () => {
|
describe('PostAttachmentContainer', () => {
|
||||||
|
const mockHistoryPush = jest.fn();
|
||||||
|
|
||||||
const baseProps: Props = {
|
const baseProps: Props = {
|
||||||
children: <p>{'some children'}</p>,
|
children: <p>{'some children'}</p>,
|
||||||
className: 'permalink',
|
className: 'permalink',
|
||||||
@@ -31,11 +33,19 @@ describe('PostAttachmentContainer', () => {
|
|||||||
},
|
},
|
||||||
posts: {posts: {}},
|
posts: {posts: {}},
|
||||||
preferences: {myPreferences: {}},
|
preferences: {myPreferences: {}},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockHistoryPush.mockClear();
|
||||||
|
|
||||||
|
// Mock useHistory
|
||||||
|
jest.doMock('react-router-dom', () => ({
|
||||||
|
...jest.requireActual('react-router-dom'),
|
||||||
|
useHistory: () => ({push: mockHistoryPush}),
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
test('should render correctly', () => {
|
test('should render correctly', () => {
|
||||||
renderWithContext(
|
renderWithContext(
|
||||||
<PostAttachmentContainer {...baseProps}/>, initialState,
|
<PostAttachmentContainer {...baseProps}/>, initialState,
|
||||||
@@ -48,4 +58,58 @@ describe('PostAttachmentContainer', () => {
|
|||||||
|
|
||||||
expect(screen.getByText('some children')).toBeInTheDocument();
|
expect(screen.getByText('some children')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should handle clicks on elements with non-string className without throwing error', () => {
|
||||||
|
renderWithContext(
|
||||||
|
<PostAttachmentContainer {...baseProps}/>, 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(
|
||||||
|
<PostAttachmentContainer {...baseProps}/>, 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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,6 +31,22 @@ const getTeamAndPostIdFromLink = (link: string) => {
|
|||||||
return match?.params;
|
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 PostAttachmentContainer = (props: Props) => {
|
||||||
const {children, className, link, preventClickAction} = props;
|
const {children, className, link, preventClickAction} = props;
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -48,11 +64,12 @@ const PostAttachmentContainer = (props: Props) => {
|
|||||||
const {tagName} = e.target;
|
const {tagName} = e.target;
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const elements = ['A', 'IMG', 'BUTTON', 'I'];
|
const elements = ['A', 'IMG', 'BUTTON', 'I'];
|
||||||
|
const targetClassName = getElementClassName(e.target);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!elements.includes(tagName) &&
|
!elements.includes(tagName) &&
|
||||||
e.target.getAttribute('role') !== 'button' &&
|
e.target.getAttribute('role') !== 'button' &&
|
||||||
e.target.className !== `attachment attachment--${className}`
|
targetClassName !== `attachment attachment--${className}`
|
||||||
) {
|
) {
|
||||||
const classNames = [
|
const classNames = [
|
||||||
'icon icon-menu-down',
|
'icon icon-menu-down',
|
||||||
@@ -65,7 +82,7 @@ const PostAttachmentContainer = (props: Props) => {
|
|||||||
dispatch(focusPost(params.postId, link, currentUserId, {skipRedirectReplyPermalink: true}));
|
dispatch(focusPost(params.postId, link, currentUserId, {skipRedirectReplyPermalink: true}));
|
||||||
return;
|
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);
|
history.push(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user