← back to Kickbacks Ai Upstream

test/insidersLocate.test.ts

75 lines

import { describe, it, expect, vi, beforeEach } from "vitest";
import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

// Regression for the public-mirror bug report (kickbacks.ai PR #3 / issue #2):
// Claude Code installed under local VS Code Insiders (~/.vscode-insiders)
// was invisible to target discovery — activation logged target:false and
// early-returned before wiring sign-in. Both scanners (locate.ts and
// adapters/registry.ts) must include the .vscode-insiders root.
//
// homedir() is mocked at a per-test temp root (same pattern as
// locateLog.test.ts). registry.ts computes ROOTS at module load, so both
// modules are imported dynamically after the fake home exists.
const h = vi.hoisted(() => ({ home: "" }));
vi.mock("node:os", async (importOriginal) => {
  const os = await importOriginal<typeof import("node:os")>();
  return { ...os, homedir: () => h.home };
});

function freshHome(): string {
  h.home = mkdtempSync(join(tmpdir(), "vibe-ads-insiders-"));
  return h.home;
}
function installClaudeCode(root: string, ver = "2.1.170"): string {
  const webview = join(h.home, root, "extensions",
    `anthropic.claude-code-${ver}`, "webview");
  mkdirSync(webview, { recursive: true });
  const idx = join(webview, "index.js");
  writeFileSync(idx, "// fixture", "utf8");
  return idx;
}
function installCodex(root: string, ver = "0.5.10"): string {
  const assets = join(h.home, root, "extensions",
    `openai.chatgpt-${ver}`, "webview", "assets");
  mkdirSync(assets, { recursive: true });
  const chunk = join(assets, "thinking-shimmer-abc123.js");
  writeFileSync(chunk, "// fixture", "utf8");
  return chunk;
}

beforeEach(() => {
  vi.resetModules();
  delete process.env.KICKBACKS_CC_TARGET;
  delete process.env.VIBE_ADS_CC_TARGET;
  delete process.env.KICKBACKS_CODEX_TARGET;
  delete process.env.VIBE_ADS_CODEX_TARGET;
  freshHome();
});

describe("VS Code Insiders target discovery", () => {
  it("locateClaudeCode finds an install under ~/.vscode-insiders", async () => {
    const idx = installClaudeCode(".vscode-insiders");
    const { locateClaudeCode } = await import("../src/locate");
    expect(locateClaudeCode()).toBe(idx);
  });

  it("registry discovers claude-code and codex under ~/.vscode-insiders",
      async () => {
    installClaudeCode(".vscode-insiders");
    installCodex(".vscode-insiders");
    const { discover } = await import("../src/adapters/registry");
    const ids = discover().map((e) => e.id);
    expect(ids).toContain("claude-code");
    expect(ids).toContain("codex");
  });

  it("stable ~/.vscode still wins when both hosts have an install", async () => {
    const stable = installClaudeCode(".vscode");
    installClaudeCode(".vscode-insiders");
    const { locateClaudeCode } = await import("../src/locate");
    expect(locateClaudeCode()).toBe(stable);
  });
});