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.
2import * as NodeChildProcess from "node:child_process";
3
1import * as NodeServices from "@effect/platform-node/NodeServices";4import * as NodeServices from "@effect/platform-node/NodeServices";
2import { it, describe, expect } from "@effect/vitest";5import { it, describe, expect } from "@effect/vitest";
3import * as Effect from "effect/Effect";6import * as Effect from "effect/Effect";
@@ -73,6 +76,53 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceFileSystemLive", (i · 69 unmodified lines
73 }),76 }),
74 );77 );
75 78
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
76 it.effect("rejects reads outside the workspace root", () =>126 it.effect("rejects reads outside the workspace root", () =>
77 Effect.gen(function* () {127 Effect.gen(function* () {
78 const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;128 const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem;
@@ -212,6 +262,22 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceFileSystemLive", (i · 133 unmodified lines
212 }),262 }),
213 );263 );
214 264
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
215 it.effect("invalidates workspace entry search cache after writes", () =>281 it.effect("invalidates workspace entry search cache after writes", () =>
216 Effect.gen(function* () {282 Effect.gen(function* () {
217 const workspaceEntries = yield* WorkspaceEntries.WorkspaceEntries;283 const workspaceEntries = yield* WorkspaceEntries.WorkspaceEntries;