style: 修复图标 样式 #46

Fixes https://github.com/Wxw-Gu/TraceMemo/issues/46
This commit is contained in:
电摇小子
2026-10-01 17:35:47 +07:00
parent 194dd0035b
commit e5a1656644
10 changed files with 241 additions and 19 deletions
@@ -1,7 +1,10 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { describe, expect, it, vi } from 'vitest'
import { AccountSummary } from '../../src/renderer/src/components/account/AccountSummary'
import { AccountOverview } from '../../src/renderer/src/features/settings/account-database/AccountOverview'
import { ConnectionHealthSection } from '../../src/renderer/src/features/settings/account-database/ConnectionHealthSection'
import type { ConnectionDiagnostic } from '../../src/renderer/src/features/settings/account-database/types'
import { TooltipProvider } from '../../src/renderer/src/components/ui'
describe('account database controls', () => {
@@ -61,4 +64,54 @@ describe('account database controls', () => {
expect(screen.getByRole('button', { name: '打开账号目录' })).toBeDisabled()
expect(screen.getByRole('button', { name: '复制账号目录' })).toBeDisabled()
})
it('renders connection states with SVG glyphs and keeps checking accessible', () => {
const diagnostics: ConnectionDiagnostic[] = [
{ id: 'db-key', label: '数据库密钥', status: 'success', result: '已用于当前连接' },
{ id: 'contacts', label: '联系人索引', status: 'warning', result: '索引待更新' },
{ id: 'messages', label: '消息数据库', status: 'error', result: '读取失败' },
{ id: 'identity', label: '账号身份', status: 'idle', result: '尚未检测' },
{ id: 'image-key', label: '图片解密密钥', status: 'unavailable', result: '未配置' }
]
const { container, rerender } = render(<ConnectionHealthSection diagnostics={diagnostics} />)
const icons = container.querySelectorAll('.settings-diagnostic-icon:not(.checking)')
expect(icons).toHaveLength(diagnostics.length)
icons.forEach((icon) => {
expect(icon).toHaveAttribute('aria-hidden', 'true')
expect(icon.querySelector('svg')).toHaveAttribute('viewBox', '0 0 24 24')
})
expect(container.textContent).not.toMatch(/[✓!×—]/)
rerender(
<ConnectionHealthSection
diagnostics={[{ id: 'db-key', label: '数据库密钥', status: 'checking', result: '检测中' }]}
/>
)
expect(screen.getByLabelText('检测中')).toHaveClass('checking')
expect(container.querySelector('.checking svg')).toBeNull()
})
it('keeps the account settings button clickable with a centered-viewBox SVG', async () => {
const user = userEvent.setup()
const onClick = vi.fn()
render(
<AccountSummary
selfInfo={{
wxid: 'wxid_fixture',
nickname: '测试账号',
accountRoot: '/fixture/account'
}}
dbReady
onClick={onClick}
/>
)
const button = screen.getByRole('button', { name: '设置' })
expect(button.querySelector('svg')).toHaveAttribute('viewBox', '0 0 24 24')
expect(button.querySelector('svg circle')).toHaveAttribute('cx', '12')
expect(button.querySelector('svg circle')).toHaveAttribute('cy', '12')
await user.click(button)
expect(onClick).toHaveBeenCalledOnce()
})
})
+69
View File
@@ -0,0 +1,69 @@
import { describe, expect, it, vi } from 'vitest'
import { createTrayImage, type TrayNativeImage } from '../../src/main/tray-icon'
function makeImage(empty = false): TrayNativeImage {
const image = {
addRepresentation: vi.fn(),
isEmpty: vi.fn(() => empty),
resize: vi.fn(),
setTemplateImage: vi.fn()
}
image.resize.mockReturnValue(image)
return image as unknown as TrayNativeImage
}
describe('tray icon creation', () => {
it('uses a monochrome 1x/2x template image on macOS', () => {
const image = makeImage()
const readImageFile = vi.fn((path: string) => Buffer.from(path))
const nativeImage = {
createEmpty: vi.fn(() => image),
createFromPath: vi.fn(() => makeImage())
}
const result = createTrayImage(
'darwin',
'/app/icon.png',
{ oneX: '/resources/trayTemplate.png', twoX: '/resources/trayTemplate@2x.png' },
nativeImage,
readImageFile
)
expect(result).toBe(image)
expect(readImageFile.mock.calls.map(([path]) => path)).toEqual([
'/resources/trayTemplate.png',
'/resources/trayTemplate@2x.png'
])
expect(image.addRepresentation).toHaveBeenNthCalledWith(1, {
scaleFactor: 1,
dataURL: `data:image/png;base64,${Buffer.from('/resources/trayTemplate.png').toString('base64')}`
})
expect(image.addRepresentation).toHaveBeenNthCalledWith(2, {
scaleFactor: 2,
dataURL: `data:image/png;base64,${Buffer.from('/resources/trayTemplate@2x.png').toString('base64')}`
})
expect(image.setTemplateImage).toHaveBeenCalledWith(true)
expect(nativeImage.createFromPath).not.toHaveBeenCalled()
})
it('preserves the app icon resize policy on Windows', () => {
const appImage = makeImage()
const nativeImage = {
createEmpty: vi.fn(() => makeImage()),
createFromPath: vi.fn(() => appImage)
}
const result = createTrayImage(
'win32',
'/app/icon.png',
{ oneX: '/resources/trayTemplate.png', twoX: '/resources/trayTemplate@2x.png' },
nativeImage,
vi.fn(() => Buffer.alloc(0))
)
expect(nativeImage.createFromPath).toHaveBeenCalledWith('/app/icon.png')
expect(appImage.resize).toHaveBeenCalledWith({ width: 24, height: 24, quality: 'best' })
expect(appImage.setTemplateImage).not.toHaveBeenCalled()
expect(result).toBe(appImage)
})
})