Skip to content

Commit 38f700d

Browse files
op7418claude
andcommitted
fix(tests): use consistent @/lib/db specifier to avoid CI module-identity drift
Two new tests landed with 5d92fc5 (cc-switch credential bridge) passed locally but failed on the v0.50.2 CI run: not ok - DB provider WITHOUT api_key → returns false even when settings.json has creds not ok - resolves ${...} env placeholders against CodePilot DB settings Root cause: the tests imported lib/db via relative specifier `../../lib/db` while the prod callers they exercise (runtime/registry.ts, mcp-loader.ts) import via mixed specifiers. Under tsx + node 20 on Linux, these can resolve as separate module instances with separate db handles — setSetting() in the test writes to one DB, getSetting() inside the prod function reads from another, so the values never line up. macOS tsx 4.x happens to dedupe by absolute path, which is why local didn't reproduce. Fix: - Unified all test imports to `@/lib/db` - Unified runtime/registry.ts to `@/lib/db` / `@/lib/claude-settings` so it matches mcp-loader.ts (the rest of the codebase is already on the alias) - Added ANTHROPIC_* env var scrub + legacy DB token reset in the hasCredentialsForRequest describe's beforeEach so inherited CI env can't short-circuit the function past the branch we're testing No prod behavior change — production imports still resolve to the same compiled module in Next.js. This only normalizes the test-time specifier shape so tsx's module cache sees one instance everywhere. 1030/1030 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dc5a6c5 commit 38f700d

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

src/__tests__/unit/claude-settings-credentials.test.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,31 @@ describe('cc-switch end-to-end (no CodePilot provider, settings.json only)', ()
260260
// be "rescued" by cc-switch — the user picked Kimi/GLM precisely because they
261261
// want THAT provider's auth.
262262
describe('hasCredentialsForRequest — provider-group ownership', () => {
263+
// Explicitly scrub ANTHROPIC_* env vars and the legacy DB token the function
264+
// short-circuits on — otherwise CI runners that inherit these from the
265+
// workflow or a prior test's state will make the function return true before
266+
// it reaches the provider-ownership branch we're testing.
267+
const savedApiKey = process.env.ANTHROPIC_API_KEY;
268+
const savedAuthToken = process.env.ANTHROPIC_AUTH_TOKEN;
269+
let savedDbToken: string | undefined;
270+
271+
beforeEach(async () => {
272+
delete process.env.ANTHROPIC_API_KEY;
273+
delete process.env.ANTHROPIC_AUTH_TOKEN;
274+
const { getSetting, setSetting } = await import('@/lib/db');
275+
savedDbToken = getSetting('anthropic_auth_token');
276+
setSetting('anthropic_auth_token', '');
277+
});
278+
279+
afterEach(async () => {
280+
if (savedApiKey !== undefined) process.env.ANTHROPIC_API_KEY = savedApiKey;
281+
if (savedAuthToken !== undefined) process.env.ANTHROPIC_AUTH_TOKEN = savedAuthToken;
282+
if (savedDbToken !== undefined) {
283+
const { setSetting } = await import('@/lib/db');
284+
setSetting('anthropic_auth_token', savedDbToken);
285+
}
286+
});
287+
263288
it('env group + settings.json creds → has credentials', async () => {
264289
writeSettings('settings.json', { env: { ANTHROPIC_AUTH_TOKEN: 'sk-cc-switch' } });
265290
const { hasCredentialsForRequest } = await import('../../lib/runtime/registry');
@@ -277,7 +302,7 @@ describe('hasCredentialsForRequest — provider-group ownership', () => {
277302
// a "Kimi config error", NOT a "use my Anthropic key" silent fallback.
278303
writeSettings('settings.json', { env: { ANTHROPIC_AUTH_TOKEN: 'sk-cc-switch-leak' } });
279304

280-
const { createProvider } = await import('../../lib/db');
305+
const { createProvider } = await import('@/lib/db');
281306
const dbProvider = createProvider({
282307
name: 'Kimi (no key configured)',
283308
provider_type: 'anthropic',
@@ -296,7 +321,7 @@ describe('hasCredentialsForRequest — provider-group ownership', () => {
296321
it('DB provider WITH api_key → returns true (uses its own creds)', async () => {
297322
writeSettings('settings.json', { env: { ANTHROPIC_AUTH_TOKEN: 'sk-cc-switch-leak' } });
298323

299-
const { createProvider } = await import('../../lib/db');
324+
const { createProvider } = await import('@/lib/db');
300325
const dbProvider = createProvider({
301326
name: 'Kimi (configured)',
302327
provider_type: 'anthropic',

src/__tests__/unit/project-mcp-injection.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ describe('loadProjectMcpServers — explicit project .mcp.json injection', () =>
120120
});
121121

122122
// Seed CodePilot DB with the secret value
123-
const { setSetting } = await import('../../lib/db');
123+
const { setSetting } = await import('@/lib/db');
124124
setSetting('team_api_token', 'sk-team-secret');
125125

126126
const { loadProjectMcpServers } = await import('../../lib/mcp-loader');

src/lib/runtime/registry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
*/
77

88
import type { AgentRuntime } from './types';
9-
import { getSetting, getAllProviders, getProvider } from '../db';
10-
import { hasClaudeSettingsCredentials } from '../claude-settings';
9+
import { getSetting, getAllProviders, getProvider } from '@/lib/db';
10+
import { hasClaudeSettingsCredentials } from '@/lib/claude-settings';
1111

1212
const runtimes = new Map<string, AgentRuntime>();
1313

0 commit comments

Comments
 (0)