diff --git a/src/cli/mcp-oauth/login.test.ts b/src/cli/mcp-oauth/login.test.ts index 8f6c23076..df1588892 100644 --- a/src/cli/mcp-oauth/login.test.ts +++ b/src/cli/mcp-oauth/login.test.ts @@ -1,30 +1,24 @@ -import { afterAll, afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test" +import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test" +import { login } from "./login" +import type { LoginDependencies } from "./login" const mockLogin = mock(() => Promise.resolve({ accessToken: "test-token", expiresAt: 1710000000 })) -mock.module("../../features/mcp-oauth/provider", () => ({ - McpOAuthProvider: class MockMcpOAuthProvider { - constructor(public options: { serverUrl: string; clientId?: string; scopes?: string[] }) {} - async login() { - return mockLogin() - } - }, -})) - -afterAll(() => { - mock.restore() -}) - -const { login } = await import("./login") - describe("login command", () => { let consoleErrorSpy: ReturnType let consoleLogSpy: ReturnType + let deps: LoginDependencies beforeEach(() => { + mock.restore() mockLogin.mockClear() consoleErrorSpy = spyOn(console, "error").mockImplementation(() => {}) consoleLogSpy = spyOn(console, "log").mockImplementation(() => {}) + deps = { + createProvider: () => ({ + login: () => mockLogin(), + }), + } }) afterEach(() => { @@ -38,7 +32,7 @@ describe("login command", () => { const options = {} // when - const exitCode = await login(serverName, options) + const exitCode = await login(serverName, options, deps) // then expect(exitCode).toBe(1) @@ -52,7 +46,7 @@ describe("login command", () => { } // when - const exitCode = await login(serverName, options) + const exitCode = await login(serverName, options, deps) // then expect(exitCode).toBe(0) @@ -68,7 +62,7 @@ describe("login command", () => { mockLogin.mockRejectedValueOnce(new Error("Network error")) // when - const exitCode = await login(serverName, options) + const exitCode = await login(serverName, options, deps) // then expect(exitCode).toBe(1) @@ -82,7 +76,7 @@ describe("login command", () => { } // when - const exitCode = await login(serverName, options) + const exitCode = await login(serverName, options, deps) // then expect(exitCode).toBe(1) diff --git a/src/cli/mcp-oauth/login.ts b/src/cli/mcp-oauth/login.ts index 1397900c9..0f17f6bbb 100644 --- a/src/cli/mcp-oauth/login.ts +++ b/src/cli/mcp-oauth/login.ts @@ -6,7 +6,21 @@ export interface LoginOptions { scopes?: string[] } -export async function login(serverName: string, options: LoginOptions): Promise { +export type McpOAuthProviderLike = Pick + +export interface LoginDependencies { + createProvider: (options: Required> & Omit) => McpOAuthProviderLike +} + +const defaultLoginDependencies: LoginDependencies = { + createProvider: (options) => new McpOAuthProvider(options), +} + +export async function login( + serverName: string, + options: LoginOptions, + deps: LoginDependencies = defaultLoginDependencies, +): Promise { try { const serverUrl = options.serverUrl if (!serverUrl) { @@ -14,7 +28,7 @@ export async function login(serverName: string, options: LoginOptions): Promise< return 1 } - const provider = new McpOAuthProvider({ + const provider = deps.createProvider({ serverUrl, clientId: options.clientId, scopes: options.scopes,