Download packages/cli/src/ui/auth/BannedAccountDialog.test.tsx from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 7.5 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/auth/BannedAccountDialog.test.tsx
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/ui/auth/BannedAccountDialog.test.tsx
-
curl -L -o BannedAccountDialog.test.tsx https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/auth/BannedAccountDialog.test.tsx
7.5 kB
| /** | |
| * @license | |
| * Copyright 2026 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest'; | |
| import { renderWithProviders } from '../../test-utils/render.js'; | |
| import { waitFor } from '../../test-utils/async.js'; | |
| import { BannedAccountDialog } from './BannedAccountDialog.js'; | |
| import { RadioButtonSelect } from '../components/shared/RadioButtonSelect.js'; | |
| import { useKeypress } from '../hooks/useKeypress.js'; | |
| import { | |
| openBrowserSecurely, | |
| shouldLaunchBrowser, | |
| } from '@google/gemini-cli-core'; | |
| import { Text } from 'ink'; | |
| import { runExitCleanup } from '../../utils/cleanup.js'; | |
| import type { AccountSuspensionInfo } from '../contexts/UIStateContext.js'; | |
| vi.mock('@google/gemini-cli-core', async (importOriginal) => { | |
| const actual = | |
| await importOriginal<typeof import('@google/gemini-cli-core')>(); | |
| return { | |
| ...actual, | |
| openBrowserSecurely: vi.fn(), | |
| shouldLaunchBrowser: vi.fn().mockReturnValue(true), | |
| }; | |
| }); | |
| vi.mock('../../utils/cleanup.js', () => ({ | |
| runExitCleanup: vi.fn().mockResolvedValue(undefined), | |
| })); | |
| vi.mock('../hooks/useKeypress.js', () => ({ | |
| useKeypress: vi.fn(), | |
| })); | |
| vi.mock('../components/shared/RadioButtonSelect.js', () => ({ | |
| RadioButtonSelect: vi.fn(({ items }) => ( | |
| <> | |
| {items.map((item: { value: string; label: string }) => ( | |
| <Text key={item.value}>{item.label}</Text> | |
| ))} | |
| </> | |
| )), | |
| })); | |
| const mockedRadioButtonSelect = RadioButtonSelect as Mock; | |
| const mockedUseKeypress = useKeypress as Mock; | |
| const mockedOpenBrowser = openBrowserSecurely as Mock; | |
| const mockedShouldLaunchBrowser = shouldLaunchBrowser as Mock; | |
| const mockedRunExitCleanup = runExitCleanup as Mock; | |
| const DEFAULT_SUSPENSION_INFO: AccountSuspensionInfo = { | |
| message: | |
| 'This service has been disabled in this account for violation of Terms of Service. Please submit an appeal to continue using this product.', | |
| appealUrl: 'https://example.com/appeal', | |
| appealLinkText: 'Appeal Here', | |
| }; | |
| describe('BannedAccountDialog', () => { | |
| let onExit: Mock; | |
| let onChangeAuth: Mock; | |
| beforeEach(() => { | |
| vi.resetAllMocks(); | |
| mockedShouldLaunchBrowser.mockReturnValue(true); | |
| mockedOpenBrowser.mockResolvedValue(undefined); | |
| mockedRunExitCleanup.mockResolvedValue(undefined); | |
| onExit = vi.fn(); | |
| onChangeAuth = vi.fn(); | |
| }); | |
| it('renders the suspension message from accountSuspensionInfo', async () => { | |
| const { lastFrame, unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const frame = lastFrame(); | |
| expect(frame).toContain('Account Suspended'); | |
| expect(frame).toContain('violation of Terms of Service'); | |
| expect(frame).toContain('Escape to exit'); | |
| unmount(); | |
| }); | |
| it('renders menu options with appeal link text from response', async () => { | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const items = mockedRadioButtonSelect.mock.calls[0][0].items; | |
| expect(items).toHaveLength(3); | |
| expect(items[0].label).toBe('Appeal Here'); | |
| expect(items[1].label).toBe('Change authentication'); | |
| expect(items[2].label).toBe('Exit'); | |
| unmount(); | |
| }); | |
| it('hides form option when no appealUrl is provided', async () => { | |
| const infoWithoutUrl: AccountSuspensionInfo = { | |
| message: 'Account suspended.', | |
| }; | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={infoWithoutUrl} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const items = mockedRadioButtonSelect.mock.calls[0][0].items; | |
| expect(items).toHaveLength(2); | |
| expect(items[0].label).toBe('Change authentication'); | |
| expect(items[1].label).toBe('Exit'); | |
| unmount(); | |
| }); | |
| it('uses default label when appealLinkText is not provided', async () => { | |
| const infoWithoutLinkText: AccountSuspensionInfo = { | |
| message: 'Account suspended.', | |
| appealUrl: 'https://example.com/appeal', | |
| }; | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={infoWithoutLinkText} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const items = mockedRadioButtonSelect.mock.calls[0][0].items; | |
| expect(items[0].label).toBe('Open the Google Form'); | |
| unmount(); | |
| }); | |
| it('opens browser when appeal option is selected', async () => { | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const { onSelect } = mockedRadioButtonSelect.mock.calls[0][0]; | |
| await onSelect('open_form'); | |
| expect(mockedOpenBrowser).toHaveBeenCalledWith( | |
| 'https://example.com/appeal', | |
| ); | |
| expect(onExit).not.toHaveBeenCalled(); | |
| unmount(); | |
| }); | |
| it('shows URL when browser cannot be launched', async () => { | |
| mockedShouldLaunchBrowser.mockReturnValue(false); | |
| const { lastFrame, unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const { onSelect } = mockedRadioButtonSelect.mock.calls[0][0]; | |
| onSelect('open_form'); | |
| await waitFor(() => { | |
| expect(lastFrame()).toContain('Please open this URL in a browser'); | |
| }); | |
| expect(mockedOpenBrowser).not.toHaveBeenCalled(); | |
| unmount(); | |
| }); | |
| it('calls onExit when "Exit" is selected', async () => { | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const { onSelect } = mockedRadioButtonSelect.mock.calls[0][0]; | |
| await onSelect('exit'); | |
| expect(mockedRunExitCleanup).toHaveBeenCalled(); | |
| expect(onExit).toHaveBeenCalled(); | |
| unmount(); | |
| }); | |
| it('calls onChangeAuth when "Change authentication" is selected', async () => { | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const { onSelect } = mockedRadioButtonSelect.mock.calls[0][0]; | |
| onSelect('change_auth'); | |
| expect(onChangeAuth).toHaveBeenCalled(); | |
| expect(onExit).not.toHaveBeenCalled(); | |
| unmount(); | |
| }); | |
| it('exits on escape key', async () => { | |
| const { unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| const keypressHandler = mockedUseKeypress.mock.calls[0][0]; | |
| const result = keypressHandler({ name: 'escape' }); | |
| expect(result).toBe(true); | |
| unmount(); | |
| }); | |
| it('renders snapshot correctly', async () => { | |
| const { lastFrame, unmount } = await renderWithProviders( | |
| <BannedAccountDialog | |
| accountSuspensionInfo={DEFAULT_SUSPENSION_INFO} | |
| onExit={onExit} | |
| onChangeAuth={onChangeAuth} | |
| />, | |
| ); | |
| expect(lastFrame()).toMatchSnapshot(); | |
| unmount(); | |
| }); | |
| }); | |