1import { describe, expect, it } from 'vitest'2import { readFileSync } from 'node:fs'3import { fileURLToPath } from 'node:url'4import { dirname, resolve } from 'node:path'5import { FRAME_URLS, RenderInputError, validateRenderRequest } from '../src/contracts'67describe('browser-run render contract', () => {8 it('accepts only the two pinned engines and validates the source', () => {9 const request = validateRenderRequest({ engine: 'mermaid', requestId: 'r-1', source: 'graph TD' })10 expect(request.engine).toBe('mermaid')11 expect(FRAME_URLS.mermaid).toBe('https://mermaid.render.diagram.zip/index.html?v=2')12 })1314 it('rejects unknown engines, malformed ids, and oversized input', () => {15 expect(() => validateRenderRequest({ engine: 'evil', requestId: 'r', source: '' })).toThrow(RenderInputError)16 expect(() => validateRenderRequest({ engine: 'mermaid', requestId: 'r bad', source: '' })).toThrow(RenderInputError)17 expect(() => validateRenderRequest({ engine: 'mermaid', requestId: 'r', source: 'x'.repeat(524_289) })).toThrow(/512 KiB/)18 })1920 it('pins Mermaid to SVG labels and protects that setting from directives', () => {21 const frame = readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../frames/mermaid/src/frame.js'), 'utf8')22 expect(frame).toMatch(/htmlLabels:\s*false/)23 expect(frame).toMatch(/secure:\s*\[[\s\S]*['"]htmlLabels['"]/) 24 })25})