Files
makelore/tests/electron-runtime/coding-files-host.test.ts

42 lines
1.6 KiB
TypeScript

import { mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { afterEach, describe, expect, it } from 'vitest';
import type { CodingProductHost } from '../../electron/api/coding-product-services';
import type { HostApiContext } from '../../electron/api/context';
import { dispatchHostApiRequest } from '../../electron/api/host-api-dispatcher';
import { CodingProjectFileService } from '../../electron/coding-projects/project-files';
const roots: string[] = [];
afterEach(async () => {
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
});
describe('PI-105 Electron Host API seam', () => {
it('reads a project-relative file through the Main dispatcher without loopback or path leakage', async () => {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-host-dispatch-'));
roots.push(root);
await writeFile(path.join(root, 'notes.txt'), 'Main-owned content\n', 'utf8');
const files = new CodingProjectFileService();
const host = {
fileContent: async (filePath: string) => await files.content(root, filePath),
} as CodingProductHost;
const ctx = {
codingProducts: { host, attachments: {}, productTools: {} },
} as HostApiContext;
const response = await dispatchHostApiRequest(ctx, {
path: '/api/coding/files/content?path=notes.txt',
});
expect(response).toMatchObject({
status: 200,
ok: true,
json: {
file: { path: 'notes.txt', content: 'Main-owned content\n', truncated: false },
},
});
expect(JSON.stringify(response.json)).not.toContain(root);
});
});