Files
codexpi/frontend/tests/markdownImages.test.ts

81 lines
3.6 KiB
TypeScript
Raw Permalink Normal View History

2026-11-14 20:23:59 +01:00
import assert from 'node:assert/strict'
import test from 'node:test'
import {embeddedAttachmentIds, resolveMarkdownImage, resolveMarkdownLink, stableAttachments} from '../src/markdownImages.ts'
const project={id:'project-1',name:'Demo',path:'/home/config/Demo',full_access:0}
const attachments=[
{id:'shot-1',original_name:'capture navigateur.png',content_type:'image/png',size:42,url:'/api/browser/screenshots/shot-1'},
]
test('messages without attachments reuse one stable empty collection',()=>{
assert.equal(stableAttachments(undefined),stableAttachments(undefined))
})
test('an attachment reference is resolved inside markdown text',()=>{
assert.deepEqual(resolveMarkdownImage('attachment://shot-1',attachments,project),{
url:'/api/browser/screenshots/shot-1',
name:'capture navigateur.png',
attachmentId:'shot-1',
reference:'attachment://shot-1',
})
assert.deepEqual(
embeddedAttachmentIds('Avant\n\n![Résultat](attachment://shot-1)\n\nAprès',attachments),
new Set(['shot-1']),
)
})
test('an attachment can be referenced by its encoded file name',()=>{
assert.equal(
resolveMarkdownImage('attachment://capture%20navigateur.png',attachments,project)?.url,
'/api/browser/screenshots/shot-1',
)
})
test('an absolute project image is served through the authenticated download route',()=>{
const image=resolveMarkdownImage('/home/config/Demo/docs/schema.png',[],project)
assert.equal(image?.url,'/api/projects/project-1/files/download?path=docs%2Fschema.png&inline=true')
assert.equal(image?.name,'schema.png')
})
test('an image created in a conversation worktree uses its authorized workspace route',()=>{
const conversation={id:'conversation-1',title:'Images',status:'idle' as const,updated_at:'',worktree_path:'/app/data/worktrees/conversation-1'}
const image=resolveMarkdownImage('/app/data/worktrees/conversation-1/output/result.webp',[],project,conversation)
assert.equal(image?.url,'/api/conversations/conversation-1/files/image?path=output%2Fresult.webp')
})
test('external images remain external and unrelated absolute paths are rejected',()=>{
assert.equal(resolveMarkdownImage('https://example.com/image.png',[],project)?.url,'https://example.com/image.png')
assert.equal(resolveMarkdownImage('/etc/passwd',[],project),null)
})
test('a project archive link becomes an authenticated download opened outside the PWA',()=>{
const link=resolveMarkdownLink('/home/config/Demo/output/boards.zip',project)
assert.deepEqual(link,{
url:'/api/projects/project-1/files/download?path=output%2Fboards.zip',
name:'boards.zip',
download:true,
external:false,
presentation:'dialog',
})
})
test('a relative artifact created in a conversation uses its private worktree route',()=>{
const conversation={id:'conversation-1',title:'Images',status:'idle' as const,updated_at:'',worktree_path:'/app/data/worktrees/conversation-1'}
const link=resolveMarkdownLink('output/boards.zip',project,conversation)
assert.equal(link.url,'/api/conversations/conversation-1/files/download?path=output%2Fboards.zip')
assert.equal(link.name,'boards.zip')
assert.equal(link.download,true)
assert.equal(link.presentation,'dialog')
})
test('external links are opened separately without pretending to be local downloads',()=>{
assert.deepEqual(resolveMarkdownLink('https://example.com/help',project),{
url:'https://example.com/help',name:'help',download:false,external:true,presentation:'external',
})
})
test('ordinary links keep navigating inside the application',()=>{
assert.equal(resolveMarkdownLink('#details',project).presentation,'navigate')
})