@@ -313,6 +313,78 @@ describe("Markdown file-like href behavior", () => {
313313 expect ( onOpenFileLink ) . not . toHaveBeenCalled ( ) ;
314314 } ) ;
315315
316+ it ( "keeps workspace settings #L anchors as local routes" , ( ) => {
317+ const onOpenFileLink = vi . fn ( ) ;
318+ render (
319+ < Markdown
320+ value = "See [settings](/workspace/settings#L12)"
321+ className = "markdown"
322+ workspacePath = "/Users/sotiriskaniras/Documents/Development/Forks/CodexMonitor"
323+ onOpenFileLink = { onOpenFileLink }
324+ /> ,
325+ ) ;
326+
327+ const link = screen . getByText ( "settings" ) . closest ( "a" ) ;
328+ expect ( link ?. getAttribute ( "href" ) ) . toBe ( "/workspace/settings#L12" ) ;
329+
330+ const clickEvent = createEvent . click ( link as Element , {
331+ bubbles : true ,
332+ cancelable : true ,
333+ } ) ;
334+ fireEvent ( link as Element , clickEvent ) ;
335+ expect ( clickEvent . defaultPrevented ) . toBe ( true ) ;
336+ expect ( onOpenFileLink ) . not . toHaveBeenCalled ( ) ;
337+ } ) ;
338+
339+ it ( "keeps workspace reviews #L anchors as local routes" , ( ) => {
340+ const onOpenFileLink = vi . fn ( ) ;
341+ render (
342+ < Markdown
343+ value = "See [reviews](/workspace/reviews#L9)"
344+ className = "markdown"
345+ workspacePath = "/Users/sotiriskaniras/Documents/Development/Forks/CodexMonitor"
346+ onOpenFileLink = { onOpenFileLink }
347+ /> ,
348+ ) ;
349+
350+ const link = screen . getByText ( "reviews" ) . closest ( "a" ) ;
351+ expect ( link ?. getAttribute ( "href" ) ) . toBe ( "/workspace/reviews#L9" ) ;
352+
353+ const clickEvent = createEvent . click ( link as Element , {
354+ bubbles : true ,
355+ cancelable : true ,
356+ } ) ;
357+ fireEvent ( link as Element , clickEvent ) ;
358+ expect ( clickEvent . defaultPrevented ) . toBe ( true ) ;
359+ expect ( onOpenFileLink ) . not . toHaveBeenCalled ( ) ;
360+ } ) ;
361+
362+ it ( "does not linkify workspace settings #L anchors in plain text" , ( ) => {
363+ const { container } = render (
364+ < Markdown
365+ value = "See /workspace/settings#L12 for app settings."
366+ className = "markdown"
367+ workspacePath = "/Users/sotiriskaniras/Documents/Development/Forks/CodexMonitor"
368+ /> ,
369+ ) ;
370+
371+ expect ( container . querySelector ( ".message-file-link" ) ) . toBeNull ( ) ;
372+ expect ( container . textContent ) . toContain ( "/workspace/settings#L12" ) ;
373+ } ) ;
374+
375+ it ( "does not turn workspace review #L anchors in inline code into file links" , ( ) => {
376+ const { container } = render (
377+ < Markdown
378+ value = "Use `/workspace/reviews#L9` to reference the reviews route."
379+ className = "markdown"
380+ workspacePath = "/Users/sotiriskaniras/Documents/Development/Forks/CodexMonitor"
381+ /> ,
382+ ) ;
383+
384+ expect ( container . querySelector ( ".message-file-link" ) ) . toBeNull ( ) ;
385+ expect ( container . querySelector ( "code" ) ?. textContent ) . toBe ( "/workspace/reviews#L9" ) ;
386+ } ) ;
387+
316388 it ( "does not turn natural-language slash phrases into file links" , ( ) => {
317389 const { container } = render (
318390 < Markdown
0 commit comments