Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// @ts-nocheck
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "vitest";
import vm from "node:vm";

function mcpTabSourceForTest() {
const source = readFileSync(new URL("./mcp-tab.tsx", import.meta.url), "utf8");
const lines = [];
let skippingImport = false;
for (const line of source.split("\n")) {
if (!skippingImport && line.startsWith("import ")) {
skippingImport = !line.trimEnd().endsWith(";");
continue;
}
if (skippingImport) {
skippingImport = !line.trimEnd().endsWith(";");
continue;
}
lines.push(line.replace(/^export function /, "function "));
}
return `${lines.join("\n")}\nglobalThis.__testExports = { McpTab };`;
}

const LABELS = {
"mcp.installed": "Installed MCP servers",
"mcp.available": "Available MCP servers",
};

function renderMcpTab(props) {
const context = {
ExtensionCard() {},
RegistryCard() {},
React: {},
globalThis: {},
useT: () => (key) => LABELS[key] || key,
};
vm.runInNewContext(mcpTabSourceForTest(), context);
return context.globalThis.__testExports.McpTab(props);
}
Comment thread
italic-jinxin marked this conversation as resolved.

function collectStringValues(node, out = []) {
if (Array.isArray(node)) {
for (const item of node) collectStringValues(item, out);
return out;
}
if (typeof node === "string") {
out.push(node);
return out;
}
if (node && typeof node === "object" && Array.isArray(node.values)) {
for (const value of node.values) collectStringValues(value, out);
}
return out;
}
Comment thread
italic-jinxin marked this conversation as resolved.

test("McpTab available heading renders the label without a stray '$' marker", () => {
const rendered = renderMcpTab({
mcpServers: [],
mcpRegistry: [{ package_ref: { id: "notion" } }],
onActivate: () => {},
onConfigure: () => {},
onRemove: () => {},
onInstall: () => {},
isBusy: false,
});

const strings = collectStringValues(rendered);
assert.ok(
strings.includes("Available MCP servers"),
"expected the translated available-servers label in the heading",
);
assert.ok(
!strings.includes("$"),
"expected no leftover template-literal '$' text node in the heading",
);
});
Comment thread
italic-jinxin marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function McpTab({
<h3
className="mb-4 font-mono text-[11px] uppercase tracking-[0.14em] text-signal"
>
${t("mcp.available")}
{t("mcp.available")}
</h3>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 2xl:grid-cols-3">
{mcpRegistry.map(
Expand Down
Loading