1import { assert, it } from "@effect/vitest";
2import { ProjectId } from "@t3tools/contracts";
3import * as Effect from "effect/Effect";
4
5import {
6 ProjectConflictError,
7 ProjectNotEmptyError,
8 ProjectNotFoundError,
9 ProjectOperationError,
10} from "./ProjectService.ts";
11import { ServerRuntimeStartupError } from "../serverRuntimeStartup.ts";
12import { failProjectMutation } from "./http.ts";
13
14const projectId = ProjectId.make("project:http-mutation");
15
16it.effect.each([
17 new ProjectNotFoundError({ projectId }),
18 new ProjectNotEmptyError({ projectId }),
19 new ProjectConflictError({
20 projectId,
21 workspaceRoot: "/workspace/project",
22 conflictingProjectId: ProjectId.make("project:http-mutation-conflict"),
23 }),
24])("maps expected project mutation failures to invalid requests", (cause) =>
25 Effect.gen(function* () {
26 const error = yield* failProjectMutation(cause).pipe(Effect.flip);
27
28 assert.equal(error._tag, "EnvironmentRequestInvalidError");
29 assert.equal(error.code, "invalid_request");
30 assert.equal(error.reason, "invalid_command");
31 }),
32);
33
34it.effect.each([
35 new ProjectOperationError({
36 operation: "dispatch-project-command",
37 projectId,
38 cause: "database unavailable",
39 }),
40 new ServerRuntimeStartupError({
41 mode: "web",
42 host: null,
43 port: 0,
44 cause: "startup unavailable",
45 }),
46])("keeps operational and startup failures internal", (cause) =>
47 Effect.gen(function* () {
48 const error = yield* failProjectMutation(cause).pipe(Effect.flip);
49
50 assert.equal(error._tag, "EnvironmentInternalError");
51 assert.equal(error.code, "internal_error");
52 assert.equal(error.reason, "project_mutation_failed");
53 }),
54);