Skip to content

Commit 3793804

Browse files
committed
test: cover esc fallback and capture-phase listener
1 parent d1bbe3b commit 3793804

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

src/Preview/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,10 @@ const Preview: React.FC<PreviewProps> = props => {
357357

358358
useEffect(() => {
359359
if (open) {
360-
window.addEventListener('keydown', onKeyDown);
360+
window.addEventListener('keydown', onKeyDown, true);
361361

362362
return () => {
363-
window.removeEventListener('keydown', onKeyDown);
363+
window.removeEventListener('keydown', onKeyDown, true);
364364
};
365365
}
366366
}, [open]);

tests/preview.portal.test.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { act, fireEvent, render } from '@testing-library/react';
2+
import React from 'react';
3+
4+
jest.mock('@rc-component/motion', () => {
5+
const MockCSSMotion = ({ children }: any) => children({ className: '', style: {} });
6+
return {
7+
__esModule: true,
8+
default: MockCSSMotion,
9+
};
10+
});
11+
12+
jest.mock('@rc-component/portal', () => {
13+
const React = require('react');
14+
15+
const MockPortal = (props: any) => {
16+
(global as any).__portalProps = props;
17+
return <>{props.children}</>;
18+
};
19+
20+
return {
21+
__esModule: true,
22+
default: MockPortal,
23+
};
24+
});
25+
26+
import Preview from '../src/Preview';
27+
28+
describe('Preview portal esc fallback', () => {
29+
it('uses capture phase for window keydown listener', () => {
30+
const addSpy = jest.spyOn(window, 'addEventListener');
31+
const removeSpy = jest.spyOn(window, 'removeEventListener');
32+
33+
const { unmount } = render(
34+
<Preview prefixCls="rc-image-preview" open src="x" mousePosition={null} onClose={jest.fn()} />,
35+
);
36+
37+
expect(addSpy).toHaveBeenCalledWith('keydown', expect.any(Function), true);
38+
39+
unmount();
40+
expect(removeSpy).toHaveBeenCalledWith('keydown', expect.any(Function), true);
41+
42+
addSpy.mockRestore();
43+
removeSpy.mockRestore();
44+
});
45+
46+
it('keeps portal onEsc as fallback', () => {
47+
const onClose = jest.fn();
48+
49+
render(
50+
<Preview prefixCls="rc-image-preview" open src="x" mousePosition={null} onClose={onClose} />,
51+
);
52+
53+
act(() => {
54+
(global as any).__portalProps.onEsc({ top: true });
55+
});
56+
57+
expect(onClose).toHaveBeenCalledTimes(1);
58+
});
59+
60+
it('avoids duplicate close when keydown esc already handled', () => {
61+
const onClose = jest.fn();
62+
63+
render(
64+
<Preview prefixCls="rc-image-preview" open src="x" mousePosition={null} onClose={onClose} />,
65+
);
66+
67+
fireEvent.keyDown(window, { key: 'Escape', keyCode: 27 });
68+
69+
act(() => {
70+
(global as any).__portalProps.onEsc({ top: true });
71+
});
72+
73+
expect(onClose).toHaveBeenCalledTimes(1);
74+
});
75+
});

0 commit comments

Comments
 (0)