// 编辑区右键菜单:条目随模式/选区变化,点击回传动作并关闭。 import { describe, it, expect, vi } from 'vitest' import { createRoot } from 'react-dom/client' import { act } from 'react-dom/test-utils' import EditorContextMenu from '../src/components/EditorContextMenu' async function renderMenu(props: Record = {}) { const container = document.createElement('div') document.body.appendChild(container) const root = createRoot(container) const actions: string[] = [] let closed = 0 await act(async () => { root.render( actions.push(a)} onClose={() => { closed += 1 }} {...props} />, ) }) return { container, root, actions, closedCount: () => closed } } const btn = (c: HTMLElement, text: string) => [...c.querySelectorAll('button')].find((b) => b.textContent === text) describe('编辑区右键菜单', () => { it('无选区时剪切/复制禁用,点加粗回传 bold 并关闭', async () => { const { container, root, actions, closedCount } = await renderMenu() expect(btn(container, '剪切')?.disabled).toBe(true) expect(btn(container, '复制')?.disabled).toBe(true) expect(btn(container, '粘贴')?.disabled).toBe(false) await act(async () => { btn(container, '加粗')?.dispatchEvent(new MouseEvent('click', { bubbles: true })) }) expect(actions).toEqual(['bold']) expect(closedCount()).toBe(1) await act(async () => { root.unmount() }) container.remove() }) it('命中本地图片时多一项「上传到 S3」;网络图片不出现', async () => { const local = await renderMenu({ imageSrc: 'doc.assets/a.png' }) const up = btn(local.container, '上传到 S3') expect(up).toBeTruthy() await act(async () => { up?.dispatchEvent(new MouseEvent('click', { bubbles: true })) }) expect(local.actions).toEqual(['uploadS3']) await act(async () => { local.root.unmount() }) local.container.remove() const remote = await renderMenu({ imageSrc: 'https://cdn.example.com/a.png' }) expect(btn(remote.container, '上传到 S3')).toBeUndefined() await act(async () => { remote.root.unmount() }) remote.container.remove() }) it('命中图片时是精简专用菜单:无格式项/全选/源码模式,有超链接与调整大小', async () => { const { container, root, actions } = await renderMenu({ imageSrc: 'https://cdn.example.com/a.png', hasSelection: true }) for (const t of ['加粗', '斜体', '删除线', '行内代码', '全选', '源码模式', '上传到 S3']) { expect(btn(container, t)).toBeUndefined() } for (const t of ['超链接…', '调整图片大小…', '剪切', '复制', '粘贴']) { expect(btn(container, t)).toBeTruthy() } await act(async () => { btn(container, '调整图片大小…')?.dispatchEvent(new MouseEvent('click', { bubbles: true })) }) expect(actions).toEqual(['imageSize']) await act(async () => { root.unmount() }) container.remove() }) it('源码模式只出编辑命令与「即时渲染」', async () => { const { container, root } = await renderMenu({ sourceMode: true, hasSelection: true }) expect(btn(container, '加粗')).toBeUndefined() expect(btn(container, '即时渲染')).toBeTruthy() expect(btn(container, '剪切')?.disabled).toBe(false) await act(async () => { root.unmount() }) container.remove() }) })