import { describe, expect, it } from 'vitest'; import { openableConversationLocalWebPath, previewableConversationRelativePath, revealableConversationPath, resolveConversationMarkdownWebPath, safeConversationExternalUrl, } from '@/lib/conversation-links'; describe('conversation links', () => { it('accepts browser-safe HTTP links and rejects executable or credential-bearing URLs', () => { expect(safeConversationExternalUrl('https://example.com/docs')) .toBe('https://example.com/docs'); expect(safeConversationExternalUrl('http://localhost:4173/')) .toBe('http://localhost:4173/'); expect(safeConversationExternalUrl('file:///tmp/private.txt')).toBeNull(); expect(safeConversationExternalUrl('javascript:alert(1)')).toBeNull(); expect(safeConversationExternalUrl('https://user:secret@example.com/')).toBeNull(); }); it('recognizes absolute local paths on macOS, Linux, and Windows without guessing relative code', () => { expect(revealableConversationPath('~/Desktop/site/index.html')) .toBe('~/Desktop/site/index.html'); expect(revealableConversationPath('/Users/example/site/index.html')) .toBe('/Users/example/site/index.html'); expect(revealableConversationPath('C:\\Users\\example\\site\\index.html')) .toBe('C:\\Users\\example\\site\\index.html'); expect(revealableConversationPath('\\\\server\\share\\index.html')) .toBe('\\\\server\\share\\index.html'); expect(revealableConversationPath('src/index.html')).toBeNull(); expect(revealableConversationPath('index.html')).toBeNull(); expect(openableConversationLocalWebPath('~/Desktop/site/index.html')) .toBe('~/Desktop/site/index.html'); expect(openableConversationLocalWebPath('/Users/example/site/readme.md')).toBeNull(); }); it('resolves a relative HTML viewing path only when the same reply names one matching absolute file', () => { const markdown = [ '文件位于 `~/Desktop/123/guiyang/index.html`。', '查看时打开 `guiyang/index.html` 或 `index.html`。', ].join('\n'); expect(previewableConversationRelativePath('guiyang/index.html')) .toBe('guiyang/index.html'); expect(resolveConversationMarkdownWebPath('guiyang/index.html', markdown)) .toBe('~/Desktop/123/guiyang/index.html'); expect(resolveConversationMarkdownWebPath('index.html', markdown)) .toBe('~/Desktop/123/guiyang/index.html'); expect(resolveConversationMarkdownWebPath('../index.html', markdown)).toBeNull(); expect(resolveConversationMarkdownWebPath('scripts/start.sh', markdown)).toBeNull(); expect(resolveConversationMarkdownWebPath('other/index.html', markdown)).toBeNull(); }); });