Skip to content
Closed
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
4 changes: 3 additions & 1 deletion packages/sdk-embed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"dist"
],
"scripts": {
"test": "vitest run",
"build": "tsup",
"typecheck": "tsc --noEmit"
},
Expand All @@ -39,6 +40,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"
}
}
37 changes: 37 additions & 0 deletions packages/sdk-embed/src/vanilla/cap-embed.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, expect, it } from "vitest";
import { createEmbedUrl } from "./cap-embed";

describe("createEmbedUrl", () => {
it("builds a default Cap embed URL with SDK and public-key markers", () => {
const url = new URL(
createEmbedUrl({ videoId: "video-123", publicKey: "pk_test" }),
);

expect(url.origin).toBe("https://cap.so");
expect(url.pathname).toBe("/embed/video-123");
expect(url.searchParams.get("sdk")).toBe("1");
expect(url.searchParams.get("pk")).toBe("pk_test");
});

it("includes autoplay and branding options when provided", () => {
const url = new URL(
createEmbedUrl({
videoId: "video-123",
publicKey: "pk_live",
apiBase: "https://app.example.com",
autoplay: true,
branding: {
logoUrl: "https://cdn.example.com/logo.png",
accentColor: "#ff00aa",
},
}),
);

expect(url.origin).toBe("https://app.example.com");
expect(url.searchParams.get("autoplay")).toBe("1");
expect(url.searchParams.get("logo")).toBe(
"https://cdn.example.com/logo.png",
);
expect(url.searchParams.get("accent")).toBe("#ff00aa");
});
});
9 changes: 9 additions & 0 deletions packages/sdk-embed/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
exclude: ["**/node_modules/**", "**/dist/**"],
},
});
4 changes: 3 additions & 1 deletion packages/sdk-recorder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dist"
],
"scripts": {
"test": "vitest run",
"build": "tsup",
"typecheck": "tsc --noEmit"
},
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"
}
}
25 changes: 25 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,25 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { getSupportedMimeType } from "./mime-types";

describe("getSupportedMimeType", () => {
afterEach(() => {
vi.unstubAllGlobals();
});

it("returns the first supported preferred MIME type", () => {
vi.stubGlobal("MediaRecorder", {
isTypeSupported: (mimeType: string) =>
mimeType === "video/webm;codecs=vp8,opus",
});

expect(getSupportedMimeType()).toBe("video/webm;codecs=vp8,opus");
});

it("returns an empty string when the browser supports none of the preferred types", () => {
vi.stubGlobal("MediaRecorder", {
isTypeSupported: () => false,
});

expect(getSupportedMimeType()).toBe("");
});
});
4 changes: 3 additions & 1 deletion packages/sdk-recorder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export class CapRecorder {
const set = this.listeners.get(event);
if (set) set.add(handler as EventHandler<keyof RecorderEventMap>);
return () => {
this.listeners.get(event)?.delete(handler);
this.listeners
.get(event)
?.delete(handler as EventHandler<keyof RecorderEventMap>);
};
}

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

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
exclude: ["**/node_modules/**", "**/dist/**"],
},
});
6 changes: 6 additions & 0 deletions packages/web-api-contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"scripts": {
"test": "vitest run"
},
"dependencies": {
"@ts-rest/core": "^3.52.1",
"zod": "^3.25.76"
},
"devDependencies": {
"vitest": "~2.1.9"
}
}
110 changes: 110 additions & 0 deletions packages/web-api-contract/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { describe, expect, it } from "vitest";
import {
contract,
DesktopOrganization,
licenseContract,
Notification,
OrganizationBrandingPatchBody,
orgCustomDomainContract,
} from "./index";

describe("desktop contract schemas", () => {
it("parses organization branding payloads with uploaded logos", () => {
const parsed = OrganizationBrandingPatchBody.parse({
brandColors: {
primary: "#111111",
secondary: null,
accent: "#BADA55",
background: "#ffffff",
},
logo: {
action: "upload",
contentType: "image/png",
data: "base64-logo",
},
});

expect(parsed.logo?.action).toBe("upload");
expect(
OrganizationBrandingPatchBody.safeParse({
brandColors: {
primary: "111111",
secondary: null,
accent: null,
background: null,
},
}).success,
).toBe(false);
});

it("validates desktop organizations with nullable brand fields", () => {
expect(
DesktopOrganization.parse({
id: "org_123",
name: "Cap Team",
ownerId: "user_123",
role: "owner",
canEditBrand: true,
iconUrl: null,
brandColors: {
primary: null,
secondary: "#123ABC",
accent: null,
background: "#000000",
},
}),
).toMatchObject({ role: "owner", canEditBrand: true });
});
});

describe("notification contract schema", () => {
it("coerces notification timestamps and rejects unknown notification types", () => {
const parsed = Notification.parse({
id: "notification_123",
readAt: null,
createdAt: "2026-05-14T20:00:00.000Z",
type: "comment",
videoId: "video_123",
author: { id: "user_123", name: "Ada", avatar: null },
comment: { id: "comment_123", content: "Looks good" },
});

expect(parsed.createdAt).toBeInstanceOf(Date);
expect(Notification.safeParse({ ...parsed, type: "mention" }).success).toBe(
false,
);
});
});

describe("route contracts", () => {
it("keeps core video and notification routes stable", () => {
expect(contract.video.getTranscribeStatus).toMatchObject({
method: "GET",
path: "/video/transcribe/status",
});
expect(contract.video.delete).toMatchObject({
method: "DELETE",
path: "/video/delete",
});
expect(contract.notifications.get).toMatchObject({
method: "GET",
path: "/notifications",
});
});

it("keeps commercial license and custom domain routes stable", () => {
expect(licenseContract.activateCommercialLicense).toMatchObject({
method: "POST",
path: "/commercial/activate",
});
expect(
licenseContract.createCommercialCheckoutUrl.body.safeParse({
type: "monthly",
}).success,
).toBe(false);
expect(orgCustomDomainContract.getOrgCustomDomain).toMatchObject({
method: "GET",
path: "/org-custom-domain",
});
});
});
9 changes: 9 additions & 0 deletions packages/web-api-contract/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
exclude: ["**/node_modules/**", "**/dist/**"],
},
});
4 changes: 3 additions & 1 deletion packages/web-domain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"main": "./dist/index.js"
},
"scripts": {
"test": "vitest run",
"build": "tsdown",
"generate-openapi": "node scripts/generate-openapi.ts"
},
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"
}
}
28 changes: 28 additions & 0 deletions packages/web-domain/src/Policy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Cause, Effect, Option } from "effect";
import { describe, expect, it } from "vitest";
import { publicPolicy, withPublicPolicy } from "./Policy";

describe("publicPolicy", () => {
it("allows an effect when the public predicate succeeds", async () => {
const result = await Effect.runPromise(
Effect.succeed("allowed").pipe(
withPublicPolicy(
publicPolicy((user) => Effect.succeed(Option.isNone(user))),
),
),
);

expect(result).toBe("allowed");
});

it("fails with PolicyDeniedError when the public predicate denies access", async () => {
const exit = await Effect.runPromiseExit(
publicPolicy(() => Effect.succeed(false)),
);

expect(exit._tag).toBe("Failure");
if (exit._tag === "Failure") {
expect(Cause.pretty(exit.cause)).toContain("PolicyDenied");
}
});
});
9 changes: 9 additions & 0 deletions packages/web-domain/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
exclude: ["**/node_modules/**", "**/dist/**"],
},
});
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.