| |
| |
| |
| |
| |
|
|
| import { describe, it, expect, beforeEach, vi } from 'vitest'; |
| import { modelCommand } from './modelCommand.js'; |
| import { type CommandContext } from './types.js'; |
| import { createMockCommandContext } from '../../test-utils/mockCommandContext.js'; |
| import type { Config } from '@google/gemini-cli-core'; |
| import { MessageType } from '../types.js'; |
|
|
| describe('modelCommand', () => { |
| let mockContext: CommandContext; |
|
|
| beforeEach(() => { |
| mockContext = createMockCommandContext(); |
| }); |
|
|
| it('should return a dialog action to open the model dialog when no args', async () => { |
| if (!modelCommand.action) { |
| throw new Error('The model command must have an action.'); |
| } |
|
|
| const result = await modelCommand.action(mockContext, ''); |
|
|
| expect(result).toEqual({ |
| type: 'dialog', |
| dialog: 'model', |
| }); |
| }); |
|
|
| it('should call refreshUserQuota if config is available when opening dialog', async () => { |
| if (!modelCommand.action) { |
| throw new Error('The model command must have an action.'); |
| } |
|
|
| const mockRefreshUserQuota = vi.fn(); |
| mockContext.services.agentContext = { |
| refreshUserQuota: mockRefreshUserQuota, |
| get config() { |
| return this; |
| }, |
| } as unknown as Config; |
|
|
| await modelCommand.action(mockContext, ''); |
|
|
| expect(mockRefreshUserQuota).toHaveBeenCalled(); |
| }); |
|
|
| describe('manage subcommand', () => { |
| it('should return a dialog action to open the model dialog', async () => { |
| const manageCommand = modelCommand.subCommands?.find( |
| (c) => c.name === 'manage', |
| ); |
| expect(manageCommand).toBeDefined(); |
|
|
| const result = await manageCommand!.action!(mockContext, ''); |
|
|
| expect(result).toEqual({ |
| type: 'dialog', |
| dialog: 'model', |
| }); |
| }); |
|
|
| it('should call refreshUserQuota if config is available', async () => { |
| const manageCommand = modelCommand.subCommands?.find( |
| (c) => c.name === 'manage', |
| ); |
| const mockRefreshUserQuota = vi.fn(); |
| mockContext.services.agentContext = { |
| refreshUserQuota: mockRefreshUserQuota, |
| get config() { |
| return this; |
| }, |
| } as unknown as Config; |
|
|
| await manageCommand!.action!(mockContext, ''); |
|
|
| expect(mockRefreshUserQuota).toHaveBeenCalled(); |
| }); |
| }); |
|
|
| describe('set subcommand', () => { |
| it('should set the model and log the command', async () => { |
| const setCommand = modelCommand.subCommands?.find( |
| (c) => c.name === 'set', |
| ); |
| expect(setCommand).toBeDefined(); |
|
|
| const mockSetModel = vi.fn(); |
| mockContext.services.agentContext = { |
| setModel: mockSetModel, |
| getHasAccessToPreviewModel: vi.fn().mockReturnValue(true), |
| getUserId: vi.fn().mockReturnValue('test-user'), |
| getUsageStatisticsEnabled: vi.fn().mockReturnValue(true), |
| getSessionId: vi.fn().mockReturnValue('test-session'), |
| getContentGeneratorConfig: vi |
| .fn() |
| .mockReturnValue({ authType: 'test-auth' }), |
| isInteractive: vi.fn().mockReturnValue(true), |
| getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }), |
| getPolicyEngine: vi.fn().mockReturnValue({ |
| getApprovalMode: vi.fn().mockReturnValue('auto'), |
| }), |
| get config() { |
| return this; |
| }, |
| } as unknown as Config; |
|
|
| await setCommand!.action!(mockContext, 'gemini-pro'); |
|
|
| expect(mockSetModel).toHaveBeenCalledWith('gemini-pro', true); |
| expect(mockContext.ui.addItem).toHaveBeenCalledWith( |
| expect.objectContaining({ |
| type: MessageType.INFO, |
| text: expect.stringContaining('Model set to gemini-pro'), |
| }), |
| ); |
| }); |
|
|
| it('should set the model with persistence when --persist is used', async () => { |
| const setCommand = modelCommand.subCommands?.find( |
| (c) => c.name === 'set', |
| ); |
| const mockSetModel = vi.fn(); |
| mockContext.services.agentContext = { |
| setModel: mockSetModel, |
| getHasAccessToPreviewModel: vi.fn().mockReturnValue(true), |
| getUserId: vi.fn().mockReturnValue('test-user'), |
| getUsageStatisticsEnabled: vi.fn().mockReturnValue(true), |
| getSessionId: vi.fn().mockReturnValue('test-session'), |
| getContentGeneratorConfig: vi |
| .fn() |
| .mockReturnValue({ authType: 'test-auth' }), |
| isInteractive: vi.fn().mockReturnValue(true), |
| getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }), |
| getPolicyEngine: vi.fn().mockReturnValue({ |
| getApprovalMode: vi.fn().mockReturnValue('auto'), |
| }), |
| get config() { |
| return this; |
| }, |
| } as unknown as Config; |
|
|
| await setCommand!.action!(mockContext, 'gemini-pro --persist'); |
|
|
| expect(mockSetModel).toHaveBeenCalledWith('gemini-pro', false); |
| expect(mockContext.ui.addItem).toHaveBeenCalledWith( |
| expect.objectContaining({ |
| type: MessageType.INFO, |
| text: expect.stringContaining('Model set to gemini-pro (persisted)'), |
| }), |
| ); |
| }); |
|
|
| it('should show error if no model name is provided', async () => { |
| const setCommand = modelCommand.subCommands?.find( |
| (c) => c.name === 'set', |
| ); |
| await setCommand!.action!(mockContext, ''); |
|
|
| expect(mockContext.ui.addItem).toHaveBeenCalledWith( |
| expect.objectContaining({ |
| type: MessageType.ERROR, |
| text: expect.stringContaining('Usage: /model set <model-name>'), |
| }), |
| ); |
| }); |
| }); |
|
|
| it('should have the correct name and description', () => { |
| expect(modelCommand.name).toBe('model'); |
| expect(modelCommand.description).toBe('Manage model configuration'); |
| }); |
| }); |
|
|