History

feat(files): open markdown, HTML, and PDF files outside the workspace (#9140)

Julius Marminge committed 2 months ago

Commit f46a7091 parent f2a914b26 files · +394 −89Browse files

Showing the changes to apps/server/src/workspace/WorkspaceFileSystem.test.ts (1 of 26 files). Show all

Unified · Split

apps/server/src/workspace/WorkspaceFileSystem.test.ts+66−0
@@ -1,3 +1,6 @@
1+// @effect-diagnostics nodeBuiltinImport:off - FileSystem cannot create a FIFO.
2+import * as NodeChildProcess from "node:child_process";
3+
14 import * as NodeServices from "@effect/platform-node/NodeServices";
25 import { it, describe, expect } from "@effect/vitest";
36 import * as Effect from "effect/Effect";
@@ -73,6 +76,53 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceFileSystemLive", (i · 69 unmodified lines
7376 }),
7477 );
7578
79+ it.effect("reads host files outside the workspace root by absolute path", () =>
80+ Effect.gen(function* () {
81+ const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;
82+ const path = yield* Path.Path;
83+ const cwd = yield* makeTempDir;
84+ const outsideDir = yield* makeTempDir;
85+ yield* writeTextFile(outsideDir, "cleanup-report.md", "# Report\n");
86+ const absolutePath = path.join(outsideDir, "cleanup-report.md");
87+
88+ const result = yield* workspaceFileSystem.readFile({
89+ cwd,
90+ relativePath: absolutePath,
91+ });
92+
93+ expect(result).toEqual({
94+ relativePath: absolutePath,
95+ contents: "# Report\n",
96+ byteLength: 9,
97+ truncated: false,
98+ });
99+ }),
100+ );
101+
102+ it.effect("rejects a FIFO without blocking on open", () =>
103+ Effect.gen(function* () {
104+ const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;
105+ const path = yield* Path.Path;
106+ const cwd = yield* makeTempDir;
107+ const outsideDir = yield* makeTempDir;
108+ const fifoPath = path.join(outsideDir, "pipe");
109+ yield* Effect.promise(
110+ () =>
111+ new Promise<void>((resolve, reject) =>
112+ NodeChildProcess.execFile("mkfifo", [fifoPath], (error) =>
113+ error ? reject(error) : resolve(),
114+ ),
115+ ),
116+ );
117+
118+ const error = yield* workspaceFileSystem
119+ .readFile({ cwd, relativePath: fifoPath })
120+ .pipe(Effect.flip);
121+
122+ expect(error).toBeInstanceOf(WorkspaceFileSystem.WorkspacePathNotFileError);
123+ }),
124+ );
125+
76126 it.effect("rejects reads outside the workspace root", () =>
77127 Effect.gen(function* () {
78128 const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;
@@ -212,6 +262,22 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceFileSystemLive", (i · 133 unmodified lines
212262 }),
213263 );
214264
265+ it.effect("rejects writes by absolute path", () =>
266+ Effect.gen(function* () {
267+ const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;
268+ const path = yield* Path.Path;
269+ const cwd = yield* makeTempDir;
270+ const outsideDir = yield* makeTempDir;
271+ const absolutePath = path.join(outsideDir, "cleanup-report.md");
272+
273+ const error = yield* workspaceFileSystem
274+ .writeFile({ cwd, relativePath: absolutePath, contents: "# Edited\n" })
275+ .pipe(Effect.flip);
276+
277+ expect(error).toBeInstanceOf(WorkspacePaths.WorkspacePathOutsideRootError);
278+ }),
279+ );
280+
215281 it.effect("invalidates workspace entry search cache after writes", () =>
216282 Effect.gen(function* () {
217283 const workspaceEntries = yield* WorkspaceEntries.WorkspaceEntries;