import { mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { KimiOAuthToolkit, OAuthConnectionError, OAuthError, OAuthUnauthorizedError, RetryableRefreshError, } from '@moonshot-ai/kimi-code-oauth'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { ErrorCodes, KimiError, KimiForCodingProvider } from '#/index'; import { TEST_IDENTITY } from './test-identity'; describe('KimiForCodingProvider OAuth error mapping', () => { let homeDir: string; beforeEach(async () => { homeDir = await mkdtemp(join(tmpdir(), 'kimi-for-coding-provider-')); }); afterEach(async () => { vi.restoreAllMocks(); await rm(homeDir, { recursive: true, force: true }); }); function resolveAuth() { const provider = new KimiForCodingProvider({ homeDir, ...TEST_IDENTITY }); return provider.resolveAuth('kimi-for-coding'); } it('maps unauthorized token failures to auth.login_required', async () => { vi.spyOn(KimiOAuthToolkit.prototype, 'ensureFresh').mockRejectedValue( new OAuthUnauthorizedError('No token for "kimi-code". Run /login to authenticate.'), ); const auth = resolveAuth(); await expect(auth(async () => 'ok')).rejects.toMatchObject({ code: ErrorCodes.AUTH_LOGIN_REQUIRED, }); }); it('maps transient token failures to provider.connection_error', async () => { const tokenErrors = [ new OAuthConnectionError('OAuth request to https://example.test failed: fetch failed'), new RetryableRefreshError('Token refresh failed (HTTP 503).'), ]; for (const tokenError of tokenErrors) { vi.spyOn(KimiOAuthToolkit.prototype, 'ensureFresh').mockRejectedValue(tokenError); const auth = resolveAuth(); const caught = await auth(async () => 'ok').catch((error: unknown) => error); expect(caught).toBeInstanceOf(KimiError); expect(caught).toMatchObject({ code: ErrorCodes.PROVIDER_CONNECTION_ERROR, message: expect.stringContaining(tokenError.message), cause: tokenError, }); vi.restoreAllMocks(); } }); it('rethrows unrecognized OAuth errors raw instead of guessing a category', async () => { const oauthError = new OAuthError('Token refresh failed (HTTP 400).'); vi.spyOn(KimiOAuthToolkit.prototype, 'ensureFresh').mockRejectedValue(oauthError); const auth = resolveAuth(); await expect(auth(async () => 'ok')).rejects.toBe(oauthError); }); });