mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-15 08:31:14 -07:00
fix(cli): Enable typechecking for more test files (#11455)
This commit is contained in:
@@ -4,20 +4,39 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import {
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
vi,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
type MockInstance,
|
||||
type Mock,
|
||||
} from 'vitest';
|
||||
import { validateNonInteractiveAuth } from './validateNonInterActiveAuth.js';
|
||||
import { AuthType, OutputFormat } from '@google/gemini-cli-core';
|
||||
import {
|
||||
AuthType,
|
||||
OutputFormat,
|
||||
makeFakeConfig,
|
||||
} from '@google/gemini-cli-core';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import * as auth from './config/auth.js';
|
||||
import { type LoadedSettings } from './config/settings.js';
|
||||
|
||||
function createLocalMockConfig(overrides: Partial<Config> = {}): Config {
|
||||
const config = makeFakeConfig();
|
||||
Object.assign(config, overrides);
|
||||
return config;
|
||||
}
|
||||
|
||||
describe('validateNonInterActiveAuth', () => {
|
||||
let originalEnvGeminiApiKey: string | undefined;
|
||||
let originalEnvVertexAi: string | undefined;
|
||||
let originalEnvGcp: string | undefined;
|
||||
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
|
||||
let processExitSpy: ReturnType<typeof vi.spyOn>;
|
||||
let refreshAuthMock: vi.Mock;
|
||||
let processExitSpy: MockInstance;
|
||||
let refreshAuthMock: Mock;
|
||||
let mockSettings: LoadedSettings;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -28,11 +47,16 @@ describe('validateNonInterActiveAuth', () => {
|
||||
delete process.env['GOOGLE_GENAI_USE_VERTEXAI'];
|
||||
delete process.env['GOOGLE_GENAI_USE_GCA'];
|
||||
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
processExitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => {
|
||||
throw new Error(`process.exit(${code}) called`);
|
||||
});
|
||||
processExitSpy = vi
|
||||
.spyOn(process, 'exit')
|
||||
.mockImplementation((code?: string | number | null | undefined) => {
|
||||
throw new Error(`process.exit(${code}) called`);
|
||||
});
|
||||
vi.spyOn(auth, 'validateAuthMethod').mockReturnValue(null);
|
||||
refreshAuthMock = vi.fn().mockResolvedValue('refreshed');
|
||||
refreshAuthMock = vi.fn().mockImplementation(async () => {
|
||||
console.log('DEBUG: refreshAuthMock called');
|
||||
return 'refreshed';
|
||||
});
|
||||
mockSettings = {
|
||||
system: { path: '', settings: {} },
|
||||
systemDefaults: { path: '', settings: {} },
|
||||
@@ -74,13 +98,13 @@ describe('validateNonInterActiveAuth', () => {
|
||||
});
|
||||
|
||||
it('exits if no auth type is configured or env vars set', async () => {
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.TEXT),
|
||||
getContentGeneratorConfig: vi
|
||||
.fn()
|
||||
.mockReturnValue({ authType: undefined }),
|
||||
};
|
||||
});
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
@@ -100,9 +124,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
|
||||
it('uses LOGIN_WITH_GOOGLE if GOOGLE_GENAI_USE_GCA is set', async () => {
|
||||
process.env['GOOGLE_GENAI_USE_GCA'] = 'true';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -114,9 +138,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
|
||||
it('uses USE_GEMINI if GEMINI_API_KEY is set', async () => {
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -130,9 +154,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
process.env['GOOGLE_GENAI_USE_VERTEXAI'] = 'true';
|
||||
process.env['GOOGLE_CLOUD_PROJECT'] = 'test-project';
|
||||
process.env['GOOGLE_CLOUD_LOCATION'] = 'us-central1';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -145,9 +169,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
it('uses USE_VERTEX_AI if GOOGLE_GENAI_USE_VERTEXAI is true and GOOGLE_API_KEY is set', async () => {
|
||||
process.env['GOOGLE_GENAI_USE_VERTEXAI'] = 'true';
|
||||
process.env['GOOGLE_API_KEY'] = 'vertex-api-key';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -163,9 +187,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
process.env['GOOGLE_GENAI_USE_VERTEXAI'] = 'true';
|
||||
process.env['GOOGLE_CLOUD_PROJECT'] = 'test-project';
|
||||
process.env['GOOGLE_CLOUD_LOCATION'] = 'us-central1';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -180,9 +204,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
process.env['GOOGLE_GENAI_USE_VERTEXAI'] = 'true';
|
||||
process.env['GOOGLE_CLOUD_PROJECT'] = 'test-project';
|
||||
process.env['GOOGLE_CLOUD_LOCATION'] = 'us-central1';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -197,9 +221,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
process.env['GOOGLE_CLOUD_PROJECT'] = 'test-project';
|
||||
process.env['GOOGLE_CLOUD_LOCATION'] = 'us-central1';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -211,9 +235,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
|
||||
it('uses configuredAuthType over environment variables', async () => {
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
AuthType.LOGIN_WITH_GOOGLE,
|
||||
undefined,
|
||||
@@ -226,13 +250,13 @@ describe('validateNonInterActiveAuth', () => {
|
||||
it('exits if validateAuthMethod returns error', async () => {
|
||||
// Mock validateAuthMethod to return error
|
||||
vi.spyOn(auth, 'validateAuthMethod').mockReturnValue('Auth error!');
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.TEXT),
|
||||
getContentGeneratorConfig: vi
|
||||
.fn()
|
||||
.mockReturnValue({ authType: undefined }),
|
||||
};
|
||||
});
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
AuthType.USE_GEMINI,
|
||||
@@ -253,10 +277,9 @@ describe('validateNonInterActiveAuth', () => {
|
||||
const validateAuthMethodSpy = vi
|
||||
.spyOn(auth, 'validateAuthMethod')
|
||||
.mockReturnValue('Auth error!');
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
|
||||
});
|
||||
// Even with an invalid auth type, it should not exit
|
||||
// because validation is skipped.
|
||||
await validateNonInteractiveAuth(
|
||||
@@ -274,11 +297,11 @@ describe('validateNonInterActiveAuth', () => {
|
||||
});
|
||||
|
||||
it('succeeds if effectiveAuthType matches enforcedAuthType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
mockSettings.merged.security!.auth!.enforcedType = AuthType.USE_GEMINI;
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
};
|
||||
});
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -289,11 +312,12 @@ describe('validateNonInterActiveAuth', () => {
|
||||
});
|
||||
|
||||
it('exits if configuredAuthType does not match enforcedAuthType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.LOGIN_WITH_GOOGLE;
|
||||
const nonInteractiveConfig = {
|
||||
mockSettings.merged.security!.auth!.enforcedType =
|
||||
AuthType.LOGIN_WITH_GOOGLE;
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.TEXT),
|
||||
};
|
||||
});
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
AuthType.USE_GEMINI,
|
||||
@@ -312,12 +336,13 @@ describe('validateNonInterActiveAuth', () => {
|
||||
});
|
||||
|
||||
it('exits if auth from env var does not match enforcedAuthType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.LOGIN_WITH_GOOGLE;
|
||||
mockSettings.merged.security!.auth!.enforcedType =
|
||||
AuthType.LOGIN_WITH_GOOGLE;
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.TEXT),
|
||||
};
|
||||
});
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
@@ -337,20 +362,20 @@ describe('validateNonInterActiveAuth', () => {
|
||||
|
||||
describe('JSON output mode', () => {
|
||||
it('prints JSON error when no auth is configured and exits with code 1', async () => {
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.JSON),
|
||||
getContentGeneratorConfig: vi
|
||||
.fn()
|
||||
.mockReturnValue({ authType: undefined }),
|
||||
};
|
||||
});
|
||||
|
||||
let thrown: Error | undefined;
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
undefined,
|
||||
undefined,
|
||||
nonInteractiveConfig as unknown as Config,
|
||||
nonInteractiveConfig,
|
||||
mockSettings,
|
||||
);
|
||||
} catch (e) {
|
||||
@@ -368,21 +393,21 @@ describe('validateNonInterActiveAuth', () => {
|
||||
});
|
||||
|
||||
it('prints JSON error when enforced auth mismatches current auth and exits with code 1', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
const nonInteractiveConfig = {
|
||||
mockSettings.merged.security!.auth!.enforcedType = AuthType.USE_GEMINI;
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.JSON),
|
||||
getContentGeneratorConfig: vi
|
||||
.fn()
|
||||
.mockReturnValue({ authType: undefined }),
|
||||
};
|
||||
});
|
||||
|
||||
let thrown: Error | undefined;
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
AuthType.LOGIN_WITH_GOOGLE,
|
||||
undefined,
|
||||
nonInteractiveConfig as unknown as Config,
|
||||
nonInteractiveConfig,
|
||||
mockSettings,
|
||||
);
|
||||
} catch (e) {
|
||||
@@ -405,20 +430,20 @@ describe('validateNonInterActiveAuth', () => {
|
||||
vi.spyOn(auth, 'validateAuthMethod').mockReturnValue('Auth error!');
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
|
||||
const nonInteractiveConfig = {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.JSON),
|
||||
getContentGeneratorConfig: vi
|
||||
.fn()
|
||||
.mockReturnValue({ authType: undefined }),
|
||||
};
|
||||
});
|
||||
|
||||
let thrown: Error | undefined;
|
||||
try {
|
||||
await validateNonInteractiveAuth(
|
||||
AuthType.USE_GEMINI,
|
||||
undefined,
|
||||
nonInteractiveConfig as unknown as Config,
|
||||
nonInteractiveConfig,
|
||||
mockSettings,
|
||||
);
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user