feat(ui): move user identity display to header (#18216)

This commit is contained in:
Sehoon Shon
2026-02-03 16:51:21 -05:00
committed by GitHub
parent 7a6dfa3704
commit d63c34b6e1
7 changed files with 219 additions and 224 deletions
-168
View File
@@ -21,7 +21,6 @@ import { act, useContext, type ReactElement } from 'react';
import { AppContainer } from './AppContainer.js';
import { SettingsContext } from './contexts/SettingsContext.js';
import { type TrackedToolCall } from './hooks/useReactToolScheduler.js';
import { MessageType } from './types.js';
import {
type Config,
makeFakeConfig,
@@ -29,8 +28,6 @@ import {
type UserFeedbackPayload,
type ResumedSessionData,
AuthType,
UserAccountManager,
type ContentGeneratorConfig,
type AgentDefinition,
} from '@google/gemini-cli-core';
@@ -47,11 +44,6 @@ const mockIdeClient = vi.hoisted(() => ({
getInstance: vi.fn().mockReturnValue(new Promise(() => {})),
}));
// Mock UserAccountManager
const mockUserAccountManager = vi.hoisted(() => ({
getCachedGoogleAccount: vi.fn().mockReturnValue(null),
}));
// Mock stdout
const mocks = vi.hoisted(() => ({
mockStdout: { write: vi.fn() },
@@ -81,9 +73,6 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
})),
enableMouseEvents: vi.fn(),
disableMouseEvents: vi.fn(),
UserAccountManager: vi
.fn()
.mockImplementation(() => mockUserAccountManager),
FileDiscoveryService: vi.fn().mockImplementation(() => ({
initialize: vi.fn(),
})),
@@ -428,7 +417,6 @@ describe('AppContainer State Management', () => {
...defaultMergedSettings.ui,
showStatusInTitle: false,
hideWindowTitle: false,
showUserIdentity: true,
},
useAlternateBuffer: false,
},
@@ -500,162 +488,6 @@ describe('AppContainer State Management', () => {
});
});
describe('Authentication Check', () => {
it('displays correct message for LOGIN_WITH_GOOGLE auth type', async () => {
// Explicitly mock implementation to ensure we control the instance
(UserAccountManager as unknown as Mock).mockImplementation(
() => mockUserAccountManager,
);
mockUserAccountManager.getCachedGoogleAccount.mockReturnValue(
'test@example.com',
);
const mockAddItem = vi.fn();
mockedUseHistory.mockReturnValue({
history: [],
addItem: mockAddItem,
updateItem: vi.fn(),
clearItems: vi.fn(),
loadHistory: vi.fn(),
});
// Explicitly enable showUserIdentity
mockSettings.merged.ui = {
...mockSettings.merged.ui,
showUserIdentity: true,
};
// Need to ensure config.getContentGeneratorConfig() returns appropriate authType
const authConfig = makeFakeConfig();
// Mock getTargetDir as well since makeFakeConfig might not set it up fully for the component
vi.spyOn(authConfig, 'getTargetDir').mockReturnValue('/test/workspace');
vi.spyOn(authConfig, 'initialize').mockResolvedValue(undefined);
vi.spyOn(authConfig, 'getExtensionLoader').mockReturnValue(
mockExtensionManager,
);
vi.spyOn(authConfig, 'getContentGeneratorConfig').mockReturnValue({
authType: AuthType.LOGIN_WITH_GOOGLE,
} as unknown as ContentGeneratorConfig);
vi.spyOn(authConfig, 'getUserTierName').mockReturnValue('Standard Tier');
let unmount: () => void;
await act(async () => {
const result = renderAppContainer({ config: authConfig });
unmount = result.unmount;
});
await waitFor(() => {
expect(UserAccountManager).toHaveBeenCalled();
expect(
mockUserAccountManager.getCachedGoogleAccount,
).toHaveBeenCalled();
expect(mockAddItem).toHaveBeenCalledWith(
expect.objectContaining({
text: 'Logged in with Google: test@example.com (Plan: Standard Tier)',
}),
);
});
await act(async () => {
unmount!();
});
});
it('displays correct message for USE_GEMINI auth type', async () => {
// Explicitly mock implementation to ensure we control the instance
(UserAccountManager as unknown as Mock).mockImplementation(
() => mockUserAccountManager,
);
mockUserAccountManager.getCachedGoogleAccount.mockReturnValue(null);
const mockAddItem = vi.fn();
mockedUseHistory.mockReturnValue({
history: [],
addItem: mockAddItem,
updateItem: vi.fn(),
clearItems: vi.fn(),
loadHistory: vi.fn(),
});
const authConfig = makeFakeConfig();
vi.spyOn(authConfig, 'getTargetDir').mockReturnValue('/test/workspace');
vi.spyOn(authConfig, 'initialize').mockResolvedValue(undefined);
vi.spyOn(authConfig, 'getExtensionLoader').mockReturnValue(
mockExtensionManager,
);
vi.spyOn(authConfig, 'getContentGeneratorConfig').mockReturnValue({
authType: AuthType.USE_GEMINI,
} as unknown as ContentGeneratorConfig);
vi.spyOn(authConfig, 'getUserTierName').mockReturnValue('Standard Tier');
let unmount: () => void;
await act(async () => {
const result = renderAppContainer({ config: authConfig });
unmount = result.unmount;
});
await waitFor(() => {
expect(mockAddItem).toHaveBeenCalledWith(
expect.objectContaining({
text: expect.stringContaining('Authenticated with gemini-api-key'),
}),
);
});
await act(async () => {
unmount!();
});
});
it('does not display authentication message if showUserIdentity is false', async () => {
mockUserAccountManager.getCachedGoogleAccount.mockReturnValue(
'test@example.com',
);
const mockAddItem = vi.fn();
mockedUseHistory.mockReturnValue({
history: [],
addItem: mockAddItem,
updateItem: vi.fn(),
clearItems: vi.fn(),
loadHistory: vi.fn(),
});
mockSettings.merged.ui = {
...mockSettings.merged.ui,
showUserIdentity: false,
};
const authConfig = makeFakeConfig();
vi.spyOn(authConfig, 'getTargetDir').mockReturnValue('/test/workspace');
vi.spyOn(authConfig, 'initialize').mockResolvedValue(undefined);
vi.spyOn(authConfig, 'getExtensionLoader').mockReturnValue(
mockExtensionManager,
);
vi.spyOn(authConfig, 'getContentGeneratorConfig').mockReturnValue({
authType: AuthType.LOGIN_WITH_GOOGLE,
} as unknown as ContentGeneratorConfig);
let unmount: () => void;
await act(async () => {
const result = renderAppContainer({ config: authConfig });
unmount = result.unmount;
});
// Give it some time to potentially call addItem
await new Promise((resolve) => setTimeout(resolve, 100));
expect(mockAddItem).not.toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
}),
);
await act(async () => {
unmount!();
});
});
});
describe('Context Providers', () => {
it('provides AppContext with correct values', async () => {
let unmount: () => void;