Automatic Merge
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
7eda0e799c
Коммит
6cbcf4e290
@@ -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: <p>{'some children'}</p>,
|
||||
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(
|
||||
<PostAttachmentContainer {...baseProps}/>, 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(
|
||||
<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;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user