Showing the changes to apps/server/src/workspace/WorkspaceFileSystem.test.ts (1 of 20 files). Show all
Unified · Split
| @@ -14,6 +14,7 @@ import * as VcsProcess from "../vcs/VcsProcess.ts"; · 13 unmodified lines | |||
| 14 | import * as WorkspaceEntries from "./WorkspaceEntries.ts"; | 14 | import * as WorkspaceEntries from "./WorkspaceEntries.ts"; |
| 15 | import * as WorkspaceFileSystem from "./WorkspaceFileSystem.ts"; | 15 | import * as WorkspaceFileSystem from "./WorkspaceFileSystem.ts"; |
| 16 | import * as WorkspacePaths from "./WorkspacePaths.ts"; | 16 | import * as WorkspacePaths from "./WorkspacePaths.ts"; |
| 17 | import { symlinksSupported } from "@t3tools/shared/testing/symlinks"; | ||
| 17 | 18 | ||
| 18 | const ProjectLayer = WorkspaceFileSystem.layer.pipe( | 19 | const ProjectLayer = WorkspaceFileSystem.layer.pipe( |
| 19 | Layer.provide(WorkspacePaths.layer), | 20 | Layer.provide(WorkspacePaths.layer), |
| @@ -138,34 +139,36 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceFileSystemLive", (i · 118 unmodified lines | |||
| 138 | }), | 139 | }), |
| 139 | ); | 140 | ); |
| 140 | 141 | ||
| 141 | it.effect("rejects symlinks that resolve outside the workspace root", () => | 142 | it.effect.skipIf(!symlinksSupported)( |
| 142 | Effect.gen(function* () { | 143 | "rejects symlinks that resolve outside the workspace root", |
| 143 | const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem; | 144 | () => |
| 144 | const fileSystem = yield* FileSystem.FileSystem; | 145 | Effect.gen(function* () { |
| 145 | const path = yield* Path.Path; | 146 | const workspaceFileSystem = yield* WorkspaceFileSystem.WorkspaceFileSystem; |
| 146 | const cwd = yield* makeTempDir; | 147 | const fileSystem = yield* FileSystem.FileSystem; |
| 147 | const outsideDir = yield* makeTempDir; | 148 | const path = yield* Path.Path; |
| 148 | yield* writeTextFile(outsideDir, "secret.txt", "outside\n"); | 149 | const cwd = yield* makeTempDir; |
| 149 | yield* fileSystem.symlink( | 150 | const outsideDir = yield* makeTempDir; |
| 150 | path.join(outsideDir, "secret.txt"), | 151 | yield* writeTextFile(outsideDir, "secret.txt", "outside\n"); |
| 151 | path.join(cwd, "linked-secret.txt"), | 152 | yield* fileSystem.symlink( |
| 152 | ); | 153 | path.join(outsideDir, "secret.txt"), |
| 153 | 154 | path.join(cwd, "linked-secret.txt"), | |
| 154 | const error = yield* workspaceFileSystem | 155 | ); |
| 155 | .readFile({ cwd, relativePath: "linked-secret.txt" }) | 156 | |
| 156 | .pipe(Effect.flip); | 157 | const error = yield* workspaceFileSystem |
| 157 | const resolvedWorkspaceRoot = yield* fileSystem.realPath(cwd); | 158 | .readFile({ cwd, relativePath: "linked-secret.txt" }) |
| 158 | const resolvedPath = yield* fileSystem.realPath(path.join(outsideDir, "secret.txt")); | 159 | .pipe(Effect.flip); |
| 159 | 160 | const resolvedWorkspaceRoot = yield* fileSystem.realPath(cwd); | |
| 160 | expect(error).toBeInstanceOf(WorkspaceFileSystem.WorkspaceFilePathEscapeError); | 161 | const resolvedPath = yield* fileSystem.realPath(path.join(outsideDir, "secret.txt")); |
| 161 | expect(error).toMatchObject({ | 162 | |
| 162 | workspaceRoot: cwd, | 163 | expect(error).toBeInstanceOf(WorkspaceFileSystem.WorkspaceFilePathEscapeError); |
| 163 | relativePath: "linked-secret.txt", | 164 | expect(error).toMatchObject({ |
| 164 | resolvedWorkspaceRoot, | 165 | workspaceRoot: cwd, |
| 165 | resolvedPath, | 166 | relativePath: "linked-secret.txt", |
| 166 | }); | 167 | resolvedWorkspaceRoot, |
| 167 | expect("cause" in error).toBe(false); | 168 | resolvedPath, |
| 168 | }), | 169 | }); |
| 170 | expect("cause" in error).toBe(false); | ||
| 171 | }), | ||
| 169 | ); | 172 | ); |
| 170 | 173 | ||
| 171 | it.effect("rejects directories without manufacturing an I/O cause", () => | 174 | it.effect("rejects directories without manufacturing an I/O cause", () => |