Spaces:
Running
Running
File size: 1,810 Bytes
0ed8124 897170b 0ed8124 897170b 0ed8124 897170b 0ed8124 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import { describe, expect, it } from 'vitest';
import { prepareHtmlArtifact } from './agent-tools';
describe('prepareHtmlArtifact', () => {
it('injects a deny-by-default CSP while preserving source for the code view', () => {
const source = '<html><head><title>x</title></head><body><script>document.body.dataset.ok="1"</script></body></html>';
const artifact = prepareHtmlArtifact(source, 'Demo', 'artifact-1');
expect(artifact.source).toBe(source);
expect(artifact.sandboxedSource).toMatch(/^<meta http-equiv="Content-Security-Policy"/);
expect(artifact.sandboxedSource.indexOf('Content-Security-Policy')).toBeLessThan(artifact.sandboxedSource.indexOf('document.body.dataset.ok'));
expect(artifact.sandboxedSource).toContain("default-src 'none'");
expect(artifact.sandboxedSource).toContain("connect-src 'none'");
expect(artifact.sandboxedSource).toContain("script-src 'unsafe-inline'");
expect(artifact.sandboxedSource).toContain('data-bonsai-artifact-runtime');
expect(artifact.runtimeToken).toBeTruthy();
expect(artifact.title).toBe('Demo');
});
it('rejects artifacts larger than the client-side safety bound', () => {
expect(() => prepareHtmlArtifact('x'.repeat(256 * 1024 + 1), 'large', 'artifact-2')).toThrow(
'exceeds 256 KiB',
);
});
it('rejects direct document navigation while keeping ordinary inline scripts available', () => {
expect(() => prepareHtmlArtifact('<script>location.href="https://example.com"</script>'))
.toThrow('cannot navigate');
expect(() => prepareHtmlArtifact('<meta http-equiv="refresh" content="0;url=https://example.com">'))
.toThrow('navigation or refresh');
expect(() => prepareHtmlArtifact('<script>document.body.textContent = "ok"</script>'))
.not.toThrow();
});
});
|