Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apps/web-cluster/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"scripts": {
"dev_": "pnpm dotenv -e ../../.env -- concurrently \"deno run --allow-all --watch ./src/runner/index.ts\" \"deno run --allow-all --watch ./src/shard-manager.ts\"",
"build": "pnpm run --filter @cap/web-cluster^... build",
"build:docker": "cd ../.. && docker build -f apps/web-cluster/Dockerfile -t ghcr.io/brendonovich/cap-web-cluster:latest ."
"build:docker": "cd ../.. && docker build -f apps/web-cluster/Dockerfile -t ghcr.io/brendonovich/cap-web-cluster:latest .",
"test": "pnpm exec vitest run"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 vitest missing from devDependencies

pnpm exec vitest run resolves the binary from the local node_modules/.bin. Since vitest is not declared as a devDependency here (or in any of the other three affected packages), the command will fail on a clean install or in CI. It likely passes locally only because vitest is hoisted from another workspace package (e.g. apps/web), which is an implicit, unreliable dependency. The same gap affects packages/sdk-recorder, packages/web-api-contract, and packages/web-domain.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web-cluster/package.json
Line: 8

Comment:
**`vitest` missing from devDependencies**

`pnpm exec vitest run` resolves the binary from the local `node_modules/.bin`. Since `vitest` is not declared as a `devDependency` here (or in any of the other three affected packages), the command will fail on a clean install or in CI. It likely passes locally only because vitest is hoisted from another workspace package (e.g. `apps/web`), which is an implicit, unreliable dependency. The same gap affects `packages/sdk-recorder`, `packages/web-api-contract`, and `packages/web-domain`.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No vitest.config file for the new test suites

None of the four new workspaces ship a vitest.config.ts, while every existing workspace that has a test script (apps/desktop, apps/discord-bot, apps/web) provides one. Without a config, Vitest uses default settings — no TypeScript path-alias resolution, no custom environment, and no globals injection. Adding at least a minimal config file per package aligns with the project's existing pattern.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web-cluster/package.json
Line: 8

Comment:
**No `vitest.config` file for the new test suites**

None of the four new workspaces ship a `vitest.config.ts`, while every existing workspace that has a `test` script (`apps/desktop`, `apps/discord-bot`, `apps/web`) provides one. Without a config, Vitest uses default settings — no TypeScript path-alias resolution, no custom environment, and no `globals` injection. Adding at least a minimal config file per package aligns with the project's existing pattern.

How can I resolve this? If you propose a fix, please make it concise.

},
"dependencies": {
"@cap/web-backend": "workspace:*",
Expand All @@ -26,6 +27,7 @@
},
"devDependencies": {
"concurrently": "^9.2.1",
"dotenv-cli": "^10.0.0"
"dotenv-cli": "^10.0.0",
"vitest": "~2.1.9"
}
}
45 changes: 45 additions & 0 deletions apps/web-cluster/src/cluster/container-metadata.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Effect } from "effect";
import { afterEach, describe, expect, it, vi } from "vitest";

import { ContainerMetadata } from "./container-metadata";

afterEach(() => {
delete process.env.ECS_CONTAINER_METADATA_URI_V4;
vi.unstubAllGlobals();
vi.restoreAllMocks();
});

describe("container metadata", () => {
it("falls back to 0.0.0.0 when metadata URI is not configured", async () => {
delete process.env.ECS_CONTAINER_METADATA_URI_V4;

const ip = await Effect.runPromise(
Effect.gen(function* () {
const metadata = yield* ContainerMetadata;
return metadata.ipAddress;
}).pipe(Effect.provide(ContainerMetadata.Default)),
);
expect(ip).toBe("0.0.0.0");
});

it("uses ECS metadata endpoint when URI is configured", async () => {
process.env.ECS_CONTAINER_METADATA_URI_V4 = "http://metadata";

const fetchMock = vi.fn().mockResolvedValue({
json: async () => ({
Containers: [{ Networks: [{ IPv4Addresses: ["10.0.0.7"] }] }],
}),
});
vi.stubGlobal("fetch", fetchMock);

const ip = await Effect.runPromise(
Effect.gen(function* () {
const metadata = yield* ContainerMetadata;
return metadata.ipAddress;
}).pipe(Effect.provide(ContainerMetadata.Default)),
);

expect(fetchMock).toHaveBeenCalledWith("http://metadata/task");
expect(ip).toBe("10.0.0.7");
});
});
7 changes: 7 additions & 0 deletions apps/web-cluster/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
},
});
6 changes: 4 additions & 2 deletions packages/sdk-recorder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
],
"scripts": {
"build": "tsup",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"test": "pnpm exec vitest run"
},
"dependencies": {},
"peerDependencies": {
Expand All @@ -35,6 +36,7 @@
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"tsup": "^8.0.0",
"typescript": "^5.7.3"
"typescript": "^5.7.3",
"vitest": "~2.1.9"
}
}
30 changes: 30 additions & 0 deletions packages/sdk-recorder/src/core/mime-types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, it, vi } from "vitest";

import { getSupportedMimeType } from "./mime-types";

describe("sdk-recorder mime type selection", () => {
it("prioritizes higher quality preferred codecs first", () => {
const isTypeSupported = vi.fn((mimeType: string) =>
[
"video/webm;codecs=vp9,opus",
"video/webm;codecs=vp8,opus",
"video/webm",
].includes(mimeType),
);
vi.stubGlobal("MediaRecorder", { isTypeSupported });

expect(getSupportedMimeType()).toBe("video/webm;codecs=vp9,opus");
expect(isTypeSupported).toHaveBeenCalledTimes(1);
expect(isTypeSupported).toHaveBeenCalledWith("video/webm;codecs=vp9,opus");

vi.unstubAllGlobals();
});

it("returns empty string when no preferred mime type is supported", () => {
vi.stubGlobal("MediaRecorder", { isTypeSupported: vi.fn(() => false) });

expect(getSupportedMimeType()).toBe("");

vi.unstubAllGlobals();
});
});
7 changes: 7 additions & 0 deletions packages/sdk-recorder/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
},
});
6 changes: 6 additions & 0 deletions packages/web-api-contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@
"dependencies": {
"@ts-rest/core": "^3.52.1",
"zod": "^3.25.76"
},
"scripts": {
"test": "pnpm exec vitest run"
},
"devDependencies": {
"vitest": "~2.1.9"
}
}
25 changes: 25 additions & 0 deletions packages/web-api-contract/src/desktop.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from "vitest";

import { OrganizationHexColor, OrganizationLogoUpdate } from "./desktop";

describe("desktop API contract schemas", () => {
it("accepts valid org brand hex colors", () => {
expect(OrganizationHexColor.parse("#A1b2C3")).toBe("#A1b2C3");
});

it("rejects invalid org brand hex colors", () => {
expect(() => OrganizationHexColor.parse("#GGGGGG")).toThrow();
expect(() => OrganizationHexColor.parse("123456")).toThrow();
});

it("validates logo update variants", () => {
expect(OrganizationLogoUpdate.parse({ action: "keep" }).action).toBe("keep");
expect(() =>
OrganizationLogoUpdate.parse({
action: "upload",
contentType: "image/png",
data: "",
}),
).toThrow();
});
});
7 changes: 7 additions & 0 deletions packages/web-api-contract/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
},
});
6 changes: 4 additions & 2 deletions packages/web-domain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
},
"scripts": {
"build": "tsdown",
"generate-openapi": "node scripts/generate-openapi.ts"
"generate-openapi": "node scripts/generate-openapi.ts",
"test": "pnpm exec vitest run"
},
"dependencies": {
"@effect/platform": "^0.92.1",
Expand All @@ -18,6 +19,7 @@
"effect": "^3.18.4"
},
"devDependencies": {
"@effect/platform-node": "^0.98.3"
"@effect/platform-node": "^0.98.3",
"vitest": "~2.1.9"
}
}
24 changes: 24 additions & 0 deletions packages/web-domain/src/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Option, Schema } from "effect";
import { describe, expect, it } from "vitest";

import { optional } from "./utils";

describe("web-domain optional schema helper", () => {
it("maps nullish values to Option.none and concrete values to Option.some", () => {
const schema = Schema.Struct({
value: optional(Schema.String),
});
const decode = Schema.decodeUnknownSync(schema);

const someValue = decode({ value: "cap" }).value;
const missingValue = decode({}).value;
const noneFromNull = decode({ value: null }).value;

expect(Option.isSome(someValue)).toBe(true);
if (Option.isSome(someValue)) {
expect(someValue.value).toBe("cap");
}
expect(missingValue).toBeUndefined();
expect(Option.isNone(noneFromNull)).toBe(true);
});
});
7 changes: 7 additions & 0 deletions packages/web-domain/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
},
});
Loading