Files
orca/src/shared/native-chat-href-routing.test.ts
T
Brennan BensonandMerge Sim 5a1acfec17 fix(native-chat): make document paths and links clickable in chat (#18712)
* fix(chat): make assistant file paths clickable

* fix(chat): tighten native file link handling

* fix(chat): link prose-joined relative paths separately

* fix(chat): preserve complete Unicode file links

* fix(chat): preserve links before sentence punctuation

* test(chat): align structured session link props

* fix(native-chat): harden generated file links

* fix(native-chat): reject reference-number false positives

* test(native-chat): align structured session parity

* perf(native-chat): bound file-link detection

---------

Co-authored-by: Merge Sim <sim@local>
2026-09-04 20:03:51 -07:00

87 lines
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { createNativeChatFileHref, routeNativeChatHref } from './native-chat-href-routing'
describe('routeNativeChatHref', () => {
it('classifies web and mail links', () => {
expect(routeNativeChatHref('https://example.com/docs')).toEqual({
kind: 'web',
url: 'https://example.com/docs'
})
expect(routeNativeChatHref(' mailto:dev@example.com ')).toEqual({
kind: 'web',
url: 'mailto:dev@example.com'
})
})
it('parses relative file hrefs and line fragments', () => {
expect(routeNativeChatHref('docs/plan.md?plain=1#line-7')).toEqual({
kind: 'file',
pathText: 'docs/plan.md',
line: 7
})
expect(routeNativeChatHref('docs/plan.md#usage')).toEqual({
kind: 'file',
pathText: 'docs/plan.md',
line: null
})
})
it('decodes relative and file URI paths', () => {
expect(routeNativeChatHref('docs/release%20notes.md')).toEqual({
kind: 'file',
pathText: 'docs/release notes.md',
line: null
})
expect(routeNativeChatHref('file:///Users/me/wt/My%20File.tsx#L12')).toEqual({
kind: 'file',
pathText: '/Users/me/wt/My File.tsx',
line: 12
})
})
it('keeps Windows drive paths out of the scheme filter', () => {
expect(routeNativeChatHref(String.raw`C:\repo\src\index.ts`)).toEqual({
kind: 'file',
pathText: String.raw`C:\repo\src\index.ts`,
line: null
})
})
it('routes encoded renderer file targets without treating Windows drives as schemes', () => {
expect(
routeNativeChatHref(createNativeChatFileHref(String.raw`C:\repo\report.docx:12`))
).toEqual({
kind: 'file',
pathText: String.raw`C:\repo\report.docx:12`,
line: null
})
expect(routeNativeChatHref(createNativeChatFileHref('/tmp/report.html'))).toEqual({
kind: 'file',
pathText: '/tmp/report.html',
line: null
})
})
it('bounds nested renderer file target decoding', () => {
let href = '/tmp/report.html'
for (let depth = 0; depth < 4; depth += 1) {
href = createNativeChatFileHref(` ${href}`)
}
expect(routeNativeChatHref(href)).toEqual({
kind: 'file',
pathText: '/tmp/report.html',
line: null
})
expect(routeNativeChatHref(createNativeChatFileHref(` ${href}`))).toEqual({ kind: 'none' })
})
it('drops anchors, unknown schemes, malformed file URIs, and empty hrefs', () => {
expect(routeNativeChatHref('#section')).toEqual({ kind: 'none' })
expect(routeNativeChatHref(undefined)).toEqual({ kind: 'none' })
expect(routeNativeChatHref('editor://file/x.ts')).toEqual({ kind: 'none' })
expect(routeNativeChatHref('javascript:alert(1)')).toEqual({ kind: 'none' })
expect(routeNativeChatHref('file:///tmp/%E0%A4%A.txt')).toEqual({ kind: 'none' })
})
})