mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-05 23:42:03 +00:00
Merge pull request #2080 from zy6p/fix/2049-preserve-selected-auth-type-on-auth-failure
fix(cli): preserve selected auth type on startup auth failure
This commit is contained in:
commit
a1b700192b
2 changed files with 110 additions and 9 deletions
109
packages/cli/src/core/initializer.test.ts
Normal file
109
packages/cli/src/core/initializer.test.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { AuthType } from '@qwen-code/qwen-code-core';
|
||||
import type { LoadedSettings } from '../config/settings.js';
|
||||
import type { Config } from '@qwen-code/qwen-code-core';
|
||||
import { initializeApp } from './initializer.js';
|
||||
import { performInitialAuth } from './auth.js';
|
||||
import { validateTheme } from './theme.js';
|
||||
import { initializeI18n } from '../i18n/index.js';
|
||||
|
||||
vi.mock('./auth.js', () => ({
|
||||
performInitialAuth: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('./theme.js', () => ({
|
||||
validateTheme: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../i18n/index.js', () => ({
|
||||
initializeI18n: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('initializeApp', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
delete process.env['QWEN_CODE_LANG'];
|
||||
|
||||
vi.mocked(initializeI18n).mockResolvedValue(undefined);
|
||||
vi.mocked(validateTheme).mockReturnValue(null);
|
||||
});
|
||||
|
||||
function createMockConfig(
|
||||
options: {
|
||||
authType?: AuthType;
|
||||
wasAuthTypeExplicitlyProvided?: boolean;
|
||||
geminiMdFileCount?: number;
|
||||
ideMode?: boolean;
|
||||
} = {},
|
||||
): Config {
|
||||
const {
|
||||
authType = AuthType.USE_OPENAI,
|
||||
wasAuthTypeExplicitlyProvided = true,
|
||||
geminiMdFileCount = 0,
|
||||
ideMode = false,
|
||||
} = options;
|
||||
|
||||
return {
|
||||
getModelsConfig: vi.fn().mockReturnValue({
|
||||
getCurrentAuthType: vi.fn().mockReturnValue(authType),
|
||||
wasAuthTypeExplicitlyProvided: vi
|
||||
.fn()
|
||||
.mockReturnValue(wasAuthTypeExplicitlyProvided),
|
||||
}),
|
||||
getIdeMode: vi.fn().mockReturnValue(ideMode),
|
||||
getGeminiMdFileCount: vi.fn().mockReturnValue(geminiMdFileCount),
|
||||
} as unknown as Config;
|
||||
}
|
||||
|
||||
function createMockSettings(): LoadedSettings {
|
||||
return {
|
||||
merged: {
|
||||
general: {
|
||||
language: 'en',
|
||||
},
|
||||
},
|
||||
setValue: vi.fn(),
|
||||
} as unknown as LoadedSettings;
|
||||
}
|
||||
|
||||
it('should not clear selected auth type when initial auth fails', async () => {
|
||||
vi.mocked(performInitialAuth).mockResolvedValue(
|
||||
'Failed to login. Message: missing OLLAMA_API_KEY',
|
||||
);
|
||||
|
||||
const config = createMockConfig({
|
||||
authType: AuthType.USE_OPENAI,
|
||||
wasAuthTypeExplicitlyProvided: true,
|
||||
});
|
||||
const settings = createMockSettings();
|
||||
|
||||
const result = await initializeApp(config, settings);
|
||||
|
||||
expect(result.authError).toBe(
|
||||
'Failed to login. Message: missing OLLAMA_API_KEY',
|
||||
);
|
||||
expect(result.shouldOpenAuthDialog).toBe(true);
|
||||
expect(settings.setValue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open auth dialog when auth is explicit and succeeds', async () => {
|
||||
vi.mocked(performInitialAuth).mockResolvedValue(null);
|
||||
|
||||
const config = createMockConfig({
|
||||
authType: AuthType.USE_OPENAI,
|
||||
wasAuthTypeExplicitlyProvided: true,
|
||||
});
|
||||
const settings = createMockSettings();
|
||||
|
||||
const result = await initializeApp(config, settings);
|
||||
|
||||
expect(result.authError).toBeNull();
|
||||
expect(result.shouldOpenAuthDialog).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -11,7 +11,7 @@ import {
|
|||
logIdeConnection,
|
||||
type Config,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { type LoadedSettings, SettingScope } from '../config/settings.js';
|
||||
import { type LoadedSettings } from '../config/settings.js';
|
||||
import { performInitialAuth } from './auth.js';
|
||||
import { validateTheme } from './theme.js';
|
||||
import { initializeI18n, type SupportedLanguage } from '../i18n/index.js';
|
||||
|
|
@ -46,14 +46,6 @@ export async function initializeApp(
|
|||
const authType = config.getModelsConfig().getCurrentAuthType();
|
||||
const authError = await performInitialAuth(config, authType);
|
||||
|
||||
// Fallback to user select when initial authentication fails
|
||||
if (authError) {
|
||||
settings.setValue(
|
||||
SettingScope.User,
|
||||
'security.auth.selectedType',
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
const themeError = validateTheme(settings);
|
||||
|
||||
const shouldOpenAuthDialog =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue