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
5 changes: 3 additions & 2 deletions packages/sdk-embed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
],
"scripts": {
"build": "tsup",
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"dependencies": {},
"peerDependencies": {
"react": ">=18"
},
Expand All @@ -39,6 +39,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"
}
}
38 changes: 38 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,38 @@
import { describe, expect, it } from "vitest";
import { createEmbedUrl } from "./cap-embed";

describe("createEmbedUrl", () => {
it("builds the default embed URL with required SDK parameters", () => {
const url = createEmbedUrl({
videoId: "video-123",
publicKey: "pk_live_123",
});

expect(url).toBe("https://cap.so/embed/video-123?sdk=1&pk=pk_live_123");
});

it("includes optional playback and branding parameters", () => {
const url = new URL(
createEmbedUrl({
apiBase: "https://app.example.com",
videoId: "video-123",
publicKey: "pk_live_123",
autoplay: true,
branding: {
logoUrl: "https://cdn.example.com/logo.svg",
accentColor: "#ff00aa",
},
}),
);

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

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
},
});
8 changes: 6 additions & 2 deletions packages/web-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
"main": "./dist/index.js"
},
"scripts": {
"build": "tsdown"
"build": "tsdown",
"test": "vitest run"
},
"dependencies": {
"@cap/env": "workspace:*",
"@aws-sdk/client-s3": "^3.485.0",
"@aws-sdk/cloudfront-signer": "^3.821.0",
"@aws-sdk/credential-providers": "^3.908.0",
"@aws-sdk/s3-presigned-post": "^3.485.0",
"@aws-sdk/s3-request-presigner": "^3.485.0",
"@cap/database": "workspace:*",
"@cap/env": "workspace:*",
"@cap/utils": "workspace:*",
"@cap/web-domain": "workspace:*",
"@effect/cluster": "^0.50.4",
Expand All @@ -30,5 +31,8 @@
"effect": "^3.18.4",
"next": "15.5.9",
"server-only": "^0.0.1"
},
"devDependencies": {
"vitest": "~2.1.9"
}
}
75 changes: 75 additions & 0 deletions packages/web-backend/src/Videos/EffectiveVideoRules.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, expect, it } from "vitest";
import {
collectPasswordHashes,
resolveEffectiveVideoRules,
} from "./EffectiveVideoRules";

describe("resolveEffectiveVideoRules", () => {
it("lets space settings override video and organization defaults", () => {
const rules = resolveEffectiveVideoRules({
videoSettings: {
disableCaptions: false,
disableComments: true,
},
organizationSettings: {
disableCaptions: true,
disableTranscript: true,
},
spaces: [
{
id: "space-1",
name: "Engineering",
settings: {
disableCaptions: true,
disableSummary: true,
},
},
],
});

expect(rules.settings).toMatchObject({
disableCaptions: true,
disableComments: true,
disableSummary: true,
disableTranscript: true,
});
expect(rules.inheritedSettings.disableCaptions).toEqual([
{ id: "space-1", name: "Engineering" },
]);
expect(rules.inheritedSettings.disableSummary).toEqual([
{ id: "space-1", name: "Engineering" },
]);
});
Comment on lines +8 to +42
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 Precedence between videoSettings and organizationSettings not covered

The test name promises to exercise "space settings override video and organization defaults," but the branch where videoSettings explicitly sets a flag to false while organizationSettings sets the same flag to true (with no space override) is never reached. For disableCaptions, the space provides an override so the videoSettings?.[key] ?? organizationSettings?.[key] line is bypassed entirely.

Because of ??, an explicit false in videoSettings correctly shadows the org-level true. If that operator were ever changed to ||, this test suite would still pass — making it possible to silently invert the intended "video setting wins" precedence. Consider adding a case where a space array is empty (or excludes a key), videoSettings.someKey = false, and organizationSettings.someKey = true, and asserting that the result is false.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/web-backend/src/Videos/EffectiveVideoRules.test.ts
Line: 8-42

Comment:
**Precedence between `videoSettings` and `organizationSettings` not covered**

The test name promises to exercise "space settings override video and organization defaults," but the branch where `videoSettings` explicitly sets a flag to `false` while `organizationSettings` sets the same flag to `true` (with no space override) is never reached. For `disableCaptions`, the space provides an override so the `videoSettings?.[key] ?? organizationSettings?.[key]` line is bypassed entirely.

Because of `??`, an explicit `false` in `videoSettings` correctly shadows the org-level `true`. If that operator were ever changed to `||`, this test suite would still pass — making it possible to silently invert the intended "video setting wins" precedence. Consider adding a case where a space array is empty (or excludes a key), `videoSettings.someKey = false`, and `organizationSettings.someKey = true`, and asserting that the result is `false`.

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


it("collects inherited password sources from flags and hashes", () => {
const rules = resolveEffectiveVideoRules({
spaces: [
{ id: "space-1", name: "Flagged", hasPassword: true },
{ id: "space-2", name: "Has hash", password: "hash-2" },
{ id: "space-3", name: "Open" },
],
});

expect(rules.hasInheritedPassword).toBe(true);
expect(rules.inheritedPasswordSources).toEqual([
{ id: "space-1", name: "Flagged" },
{ id: "space-2", name: "Has hash" },
]);
});
});

describe("collectPasswordHashes", () => {
it("keeps the video password first and removes empty space passwords", () => {
expect(
collectPasswordHashes({
videoPassword: "video-hash",
spacePasswords: [
{ password: "space-hash" },
{ password: "" },
{ password: null },
{},
],
}),
).toEqual(["video-hash", "space-hash"]);
});
});
Comment on lines +61 to +75
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 test for absent / null videoPassword

Only the "happy path" (a truthy videoPassword) is covered. The function also handles videoPassword being undefined or null via ...(videoPassword ? [videoPassword] : []). Adding a test case where videoPassword is omitted or null would confirm the guard works, especially if the function signature changes in the future.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/web-backend/src/Videos/EffectiveVideoRules.test.ts
Line: 61-75

Comment:
**No test for absent / null `videoPassword`**

Only the "happy path" (a truthy `videoPassword`) is covered. The function also handles `videoPassword` being `undefined` or `null` via `...(videoPassword ? [videoPassword] : [])`. Adding a test case where `videoPassword` is omitted or `null` would confirm the guard works, especially if the function signature changes in the future.

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

8 changes: 8 additions & 0 deletions packages/web-backend/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.test.ts"],
},
});
Loading
Loading