|
1 | | -import { act } from 'react' |
| 1 | +import { act, useEffect, useState } from 'react' |
2 | 2 | import { createRoot } from 'react-dom/client' |
3 | 3 | import { MemoryRouter } from 'react-router-dom' |
4 | 4 | import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' |
5 | 5 |
|
6 | | -import { AppUIProvider, useSettingsUI, useSidebarUI } from '../contexts/app-ui' |
| 6 | +import { AppUIProvider, useSettingsUI, useSidebarUI, useTitleBarRightPanelUI } from '../contexts/app-ui' |
7 | 7 | import { AuthContextBridge, type AuthContextValue } from '../contexts/auth' |
8 | 8 | import { DesktopTitleBar } from '../components/DesktopTitleBar' |
9 | 9 | import { LocaleProvider } from '../contexts/LocaleContext' |
@@ -44,6 +44,30 @@ function SettingsProbe() { |
44 | 44 | ) |
45 | 45 | } |
46 | 46 |
|
| 47 | +function RightPanelShortcutProbe() { |
| 48 | + const { rightPanelOpen, setRightPanelOpen } = useSidebarUI() |
| 49 | + const { setTitleBarRightPanelClick } = useTitleBarRightPanelUI() |
| 50 | + const [visible, setVisible] = useState(false) |
| 51 | + |
| 52 | + useEffect(() => { |
| 53 | + setTitleBarRightPanelClick(() => { |
| 54 | + setVisible((open) => !open) |
| 55 | + }) |
| 56 | + return () => setTitleBarRightPanelClick(null) |
| 57 | + }, [setTitleBarRightPanelClick]) |
| 58 | + |
| 59 | + useEffect(() => { |
| 60 | + setRightPanelOpen(visible) |
| 61 | + }, [visible, setRightPanelOpen]) |
| 62 | + |
| 63 | + return ( |
| 64 | + <div> |
| 65 | + <span data-testid="right-panel-visible">{visible ? 'open' : 'closed'}</span> |
| 66 | + <span data-testid="right-panel-icon">{rightPanelOpen ? 'open' : 'closed'}</span> |
| 67 | + </div> |
| 68 | + ) |
| 69 | +} |
| 70 | + |
47 | 71 | describe('AppUIProvider sidebar state', () => { |
48 | 72 | const authValue: AuthContextValue = { |
49 | 73 | me: null, |
@@ -226,6 +250,52 @@ describe('AppUIProvider sidebar state', () => { |
226 | 250 | }) |
227 | 251 | container.remove() |
228 | 252 | }) |
| 253 | + |
| 254 | + it('右侧面板快捷键复用标题栏回调路径', async () => { |
| 255 | + desktopMock.isDesktop.mockReturnValue(false) |
| 256 | + Object.defineProperty(window.navigator, 'platform', { |
| 257 | + configurable: true, |
| 258 | + value: 'Win32', |
| 259 | + }) |
| 260 | + |
| 261 | + const container = document.createElement('div') |
| 262 | + document.body.appendChild(container) |
| 263 | + const root = createRoot(container) |
| 264 | + |
| 265 | + await act(async () => { |
| 266 | + root.render( |
| 267 | + <MemoryRouter initialEntries={['/']}> |
| 268 | + <AuthContextBridge value={authValue}> |
| 269 | + <AppUIProvider> |
| 270 | + <RightPanelShortcutProbe /> |
| 271 | + </AppUIProvider> |
| 272 | + </AuthContextBridge> |
| 273 | + </MemoryRouter>, |
| 274 | + ) |
| 275 | + }) |
| 276 | + |
| 277 | + expect(container.querySelector('[data-testid="right-panel-visible"]')?.textContent).toBe('closed') |
| 278 | + expect(container.querySelector('[data-testid="right-panel-icon"]')?.textContent).toBe('closed') |
| 279 | + |
| 280 | + await act(async () => { |
| 281 | + window.dispatchEvent(new KeyboardEvent('keydown', { |
| 282 | + key: 'b', |
| 283 | + code: 'KeyB', |
| 284 | + altKey: true, |
| 285 | + ctrlKey: true, |
| 286 | + bubbles: true, |
| 287 | + cancelable: true, |
| 288 | + })) |
| 289 | + }) |
| 290 | + |
| 291 | + expect(container.querySelector('[data-testid="right-panel-visible"]')?.textContent).toBe('open') |
| 292 | + expect(container.querySelector('[data-testid="right-panel-icon"]')?.textContent).toBe('open') |
| 293 | + |
| 294 | + act(() => { |
| 295 | + root.unmount() |
| 296 | + }) |
| 297 | + container.remove() |
| 298 | + }) |
229 | 299 | }) |
230 | 300 |
|
231 | 301 | describe('DesktopTitleBar update entry', () => { |
|
0 commit comments