42 lines
1.6 KiB
TypeScript
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);
|
|
});
|
|
});
|