Files
hapi/web/src/lib/file-markdown-preview.test.ts
T
a82dd49049 feat(web): markdown Source | Preview toggle in session file pane (#957)
* feat(web): markdown Source | Preview toggle in session file pane

Add Source | Preview toggle for .md/.mdx files in the session file route,
defaulting to preview with localStorage persistence. Reuse chat markdown
pipeline via MarkdownRenderer standalone mode (no assistant-ui thread).

Includes unit tests, Playwright smoke, and e2e fixture.

Closes tiann/hapi#954

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): cast standalone MarkdownRenderer components for react-markdown

Soup verify gate: defaultComponents merge type is wider than
react-markdown Components; standalone file-pane path needs explicit cast.

* fix(web): route file-pane markdown fences through SyntaxHighlighter

Standalone file preview now mirrors chat code-block rendering: fenced
blocks use SyntaxHighlighter and MARKDOWN_COMPONENTS_BY_LANGUAGE (mermaid
included) without requiring ThreadPrimitive context.

Addresses HAPI Bot Major on tiann/hapi#957.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): detect fenced vs inline code in standalone markdown preview

Move block detection to the pre override (react-markdown v10 does not pass
inline to custom code components). Add inline-code regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 11:06:38 +08:00

37 lines
1.4 KiB
TypeScript

import { beforeEach, describe, expect, it } from 'vitest'
import {
DEFAULT_MARKDOWN_PREVIEW_MODE,
MARKDOWN_PREVIEW_MODE_STORAGE_KEY,
getInitialMarkdownPreviewMode,
isMarkdownFile,
persistMarkdownPreviewMode,
} from './file-markdown-preview'
describe('file-markdown-preview helpers', () => {
beforeEach(() => {
window.localStorage.clear()
})
it('detects markdown file extensions', () => {
expect(isMarkdownFile('README.md')).toBe(true)
expect(isMarkdownFile('docs/guide/page.mdx')).toBe(true)
expect(isMarkdownFile('src/file.ts')).toBe(false)
expect(isMarkdownFile('noext')).toBe(false)
})
it('defaults to preview when storage is missing or invalid', () => {
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
window.localStorage.setItem(MARKDOWN_PREVIEW_MODE_STORAGE_KEY, 'nope')
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
})
it('reads and persists a valid preview mode', () => {
persistMarkdownPreviewMode('source')
expect(getInitialMarkdownPreviewMode()).toBe('source')
persistMarkdownPreviewMode('preview')
expect(window.localStorage.getItem(MARKDOWN_PREVIEW_MODE_STORAGE_KEY)).toBeNull()
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
})
})