返回 oh-my-ppt
html-editor-toolbar.test.ts
根目录 / tests / unit / html-editor / html-editor-toolbar.test.ts
1 /**
2 * @vitest-environment happy-dom
3 */
4 import React, { act } from 'react'
5 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
6 import { createRoot, type Root } from 'react-dom/client'
7
8 const state = vi.hoisted(() => ({
9 revealHtmlFile: vi.fn(async () => ({ ok: true })),
10 saveHtmlEdits: vi.fn(async () => ({ saved: false })),
11 navigate: vi.fn()
12 }))
13
14 vi.mock('../../../src/renderer/src/lib/ipc', () => ({
15 ipc: {
16 revealHtmlFile: state.revealHtmlFile,
17 openHtmlInBrowser: vi.fn(async () => ({ ok: true }))
18 }
19 }))
20
21 vi.mock('react-router-dom', () => ({
22 useNavigate: () => state.navigate
23 }))
24
25 vi.mock('../../../src/renderer/src/i18n', () => ({
26 useT: () => (key: string) => key
27 }))
28
29 import { TooltipProvider } from '../../../src/renderer/src/components/ui/Tooltip'
30 import { HtmlEditorToolbar } from '../../../src/renderer/src/components/html-editor/HtmlEditorToolbar'
31 import { useHtmlEditorStore } from '../../../src/renderer/src/store/htmlEditorStore'
32 import { useHtmlEditStore } from '../../../src/renderer/src/store/htmlEditStore'
33
34 const originalSaveHtmlEdits = useHtmlEditStore.getState().save
35
36 async function renderToolbar(): Promise<{ container: HTMLDivElement; root: Root }> {
37 const container = document.createElement('div')
38 document.body.appendChild(container)
39 const root = createRoot(container)
40 await act(async () => {
41 root.render(
42 React.createElement(
43 TooltipProvider,
44 { delayDuration: 0 },
45 React.createElement(HtmlEditorToolbar, { onOpenHistory: vi.fn() })
46 )
47 )
48 })
49 return { container, root }
50 }
51
52 describe('HtmlEditorToolbar', () => {
53 beforeEach(() => {
54 state.revealHtmlFile.mockClear()
55 state.saveHtmlEdits.mockClear()
56 state.navigate.mockClear()
57 useHtmlEditStore.getState().reset()
58 useHtmlEditStore.setState({ save: state.saveHtmlEdits })
59 useHtmlEditorStore.setState({
60 docId: 'hedit-1',
61 title: 'Landing page',
62 sourcePath: '/tmp/landing.html',
63 exporting: false
64 })
65 })
66
67 afterEach(async () => {
68 document.body.innerHTML = ''
69 useHtmlEditStore.getState().reset()
70 useHtmlEditStore.setState({ save: originalSaveHtmlEdits })
71 useHtmlEditorStore.getState().reset()
72 })
73
74 it('reveals the current HTML working file from the toolbar', async () => {
75 const { container, root } = await renderToolbar()
76 try {
77 const revealButton = container.querySelector<HTMLButtonElement>(
78 '[aria-label="htmlEditor.revealFile"]'
79 )
80 expect(revealButton).toBeTruthy()
81
82 await act(async () => {
83 revealButton?.click()
84 })
85
86 expect(state.revealHtmlFile).toHaveBeenCalledWith({ docId: 'hedit-1' })
87 expect(state.saveHtmlEdits).not.toHaveBeenCalled()
88 } finally {
89 await act(async () => {
90 root.unmount()
91 })
92 container.remove()
93 }
94 })
95 })
96
96 lines TYPESCRIPT