Files
NotesAgentic/frontend/src/features/editor/SourceMarkdownEditor.spec.ts
T

63 lines
3.2 KiB
TypeScript

// @vitest-environment happy-dom
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import { mount, type VueWrapper } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import SourceMarkdownEditor from './SourceMarkdownEditor.vue'
import { executeEditorCommand } from '@/services/editorCommandService'
import { useEditorStore } from '@/stores/editor'
import * as workspace from '@/services/workspaceService'
let wrapper: VueWrapper | undefined
const original = '***\ntitle: 中文\ntags: [一, 二, 一]\ncustom: [1, false]\n---\n# 正文\n'
beforeEach(async () => {
localStorage.clear(); setActivePinia(createPinia())
vi.spyOn(workspace, 'readFileContent').mockResolvedValue(original)
vi.spyOn(workspace, 'getNoteId').mockResolvedValue('note-fixture')
vi.spyOn(workspace, 'saveFileContent').mockResolvedValue()
const store = useEditorStore(); store.setMode('source'); await store.loadFile('/fixture.md')
wrapper = mount(SourceMarkdownEditor, { props: { initialContent: store.content }, attachTo: document.body })
})
afterEach(() => { wrapper?.unmount(); useEditorStore().closeFile(); vi.restoreAllMocks() })
it('完整属性转换是一笔可撤销重做的源码事务', async () => {
const store = useEditorStore()
expect(await executeEditorCommand('editor.import-note-properties')).toEqual({ ok: true })
expect(store.content).toMatch(/^---\n/)
const converted = store.content
expect(store.saveStatus).toBe('dirty')
expect(await executeEditorCommand('editor.undo')).toEqual({ ok: true })
expect(store.content).toBe(original)
expect(await executeEditorCommand('editor.redo')).toEqual({ ok: true })
expect(store.content).toBe(converted)
})
it('保存失败保留转换后的内存正文,仍可撤销', async () => {
const store = useEditorStore()
vi.mocked(workspace.saveFileContent).mockRejectedValue(new Error('fixture disk full'))
await executeEditorCommand('editor.import-note-properties')
await store.save()
expect(store.saveStatus).toBe('save_failed')
expect(store.content).toMatch(/^---/)
await executeEditorCommand('editor.undo')
expect(store.content).toBe(original)
})
it('冲突文档禁用命令,保持原始内容', async () => {
const store = useEditorStore(); store.saveStatus = 'conflict'
expect(await executeEditorCommand('editor.import-note-properties')).toMatchObject({ ok: false, reason: 'unavailable' })
expect(store.content).toBe(original)
})
it('选择图片后写入工作区并插入相对 Markdown 引用', async () => {
vi.spyOn(workspace, 'storeWorkspaceImage').mockResolvedValue({
asset_id: 'asset-fixture', path: 'attachments/aa/hash.png', content_hash: 'hash',
media_type: 'image/png', size: 12, original_name: '截图.png', reference: 'attachments/aa/hash.png',
})
const input = wrapper!.get('input[type="file"]')
const file = new File(['png'], '截图.png', { type: 'image/png' })
Object.defineProperty(input.element, 'files', { configurable: true, value: [file] })
await input.trigger('change')
await vi.waitFor(() => expect(useEditorStore().content).toContain('![截图.png](attachments/aa/hash.png)'))
expect(workspace.storeWorkspaceImage).toHaveBeenCalledWith(file, 'upload', '/fixture.md', 'note-fixture')
})