Files
new-markdown/tests/editor-context-menu.test.tsx
Muse 492051cef0 feat(editor): 图片右键换精简专用菜单(docs/31)
用户要求去掉多余菜单。右键命中图片时只出:超链接…/调整图片
大小…/上传到 S3(未上传图才有)/剪切/复制/粘贴;加粗、斜体、
删除线、行内代码等文本格式项与全选、源码模式对图片没意义,
不再出现(文本右键菜单不变)。配套:右键图片先把它设为节点
选区,描边/手柄随之出现,剪切/复制/Delete 都作用在这张图上。
vitest 153+2、构建通过。
2026-11-15 13:49:19 +08:00

78 lines
3.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 编辑区右键菜单:条目随模式/选区变化,点击回传动作并关闭。
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<string, unknown> = {}) {
const container = document.createElement('div')
document.body.appendChild(container)
const root = createRoot(container)
const actions: string[] = []
let closed = 0
await act(async () => {
root.render(
<EditorContextMenu
x={10} y={10} hasSelection={false} imageSrc={null} sourceMode={false}
onAction={(a) => 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()
})
})