hermes-agent/apps/desktop/src/components/language-switcher.test.tsx
2026-06-06 07:51:44 -07:00

53 lines
1.7 KiB
TypeScript

import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import type { HermesConfigRecord } from '@/hermes'
import { type I18nConfigClient, I18nProvider } from '@/i18n'
import { LanguageSwitcher } from './language-switcher'
// cmdk (the searchable list) wires a ResizeObserver and scrolls the active
// item into view — neither exists in jsdom. Stub them, matching the polyfill
// idiom in tool-approval-group.test.tsx.
class TestResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
}
vi.stubGlobal('ResizeObserver', TestResizeObserver)
Element.prototype.scrollIntoView = function scrollIntoView() {}
describe('LanguageSwitcher', () => {
afterEach(() => {
cleanup()
vi.restoreAllMocks()
})
it('persists language changes through display.language config', async () => {
const saveConfig = vi.fn().mockResolvedValue({ ok: true })
const latestConfig: HermesConfigRecord = { display: { language: 'en', skin: 'slate' } }
const configClient: I18nConfigClient = {
getConfig: vi.fn().mockResolvedValue(latestConfig),
saveConfig
}
render(
<I18nProvider configClient={configClient}>
<LanguageSwitcher />
</I18nProvider>
)
await waitFor(() => {
expect(screen.getByRole('button', { name: 'Switch language' }).hasAttribute('disabled')).toBe(false)
})
fireEvent.click(screen.getByRole('button', { name: 'Switch language' }))
fireEvent.click(screen.getByRole('option', { name: /日本語/i }))
await waitFor(() => expect(saveConfig).toHaveBeenCalledTimes(1))
expect(saveConfig).toHaveBeenCalledWith({ display: { language: 'ja', skin: 'slate' } })
})
})