mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-17 11:37:06 +08:00
fix: 完善交互、知识库目录与 Windows 运行库提示
This commit is contained in:
@@ -376,6 +376,56 @@ describe('AISearchWorkspace cache privacy boundary', () => {
|
||||
expect(api.runAiSearch).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('submits with Enter and keeps Shift+Enter available for a new line', async () => {
|
||||
api.getAiSearchProviderStatus.mockResolvedValue({ configured: true, requiresConsent: false })
|
||||
api.runAiSearch.mockResolvedValue({
|
||||
requestId: 'enter-submit',
|
||||
status: 'completed',
|
||||
answer: 'answer',
|
||||
plan: { intent: 'global_topic_search' },
|
||||
knowledge: { indexedMessageCount: 1, indexedChunkCount: 1, totalMessages: 1 },
|
||||
candidateEvidenceCount: 0,
|
||||
contextEvidenceCount: 0,
|
||||
evidence: [],
|
||||
aggregation: {
|
||||
messageCount: 0,
|
||||
peopleCount: 0,
|
||||
conversationCount: 0,
|
||||
people: [],
|
||||
conversations: []
|
||||
},
|
||||
agent: { mode: 'agent', toolCalls: 1, trace: [] },
|
||||
timings: {},
|
||||
elapsedMs: 1
|
||||
} as never)
|
||||
render(
|
||||
<AISearchWorkspace
|
||||
contacts={[]}
|
||||
selectedContact={null}
|
||||
dbReady
|
||||
aiModelConfig={{
|
||||
configured: true,
|
||||
providerName: 'Local Provider',
|
||||
model: 'model',
|
||||
modelName: 'Model',
|
||||
status: 'connected'
|
||||
}}
|
||||
onSelectContact={vi.fn()}
|
||||
onOpenEvidence={vi.fn()}
|
||||
onOpenAISettings={vi.fn()}
|
||||
onNotice={vi.fn()}
|
||||
/>
|
||||
)
|
||||
|
||||
const input = screen.getByRole('textbox')
|
||||
await userEvent.type(input, 'Enter submit question')
|
||||
fireEvent.keyDown(input, { key: 'Enter', shiftKey: true })
|
||||
expect(api.runAiSearch).not.toHaveBeenCalled()
|
||||
|
||||
fireEvent.keyDown(input, { key: 'Enter' })
|
||||
await waitFor(() => expect(api.runAiSearch).toHaveBeenCalledOnce())
|
||||
})
|
||||
|
||||
it('cancels an active analysis and ignores its late result', async () => {
|
||||
api.getAiSearchProviderStatus.mockResolvedValue({ configured: true, requiresConsent: false })
|
||||
let resolveSearch: ((value: unknown) => void) | undefined
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { CacheCleanupPage } from '../../src/renderer/src/features/settings/pages/CacheCleanupPage'
|
||||
|
||||
const api = {
|
||||
getCacheSummary: vi.fn(),
|
||||
clearCache: vi.fn(),
|
||||
openKnowledgeDirectory: vi.fn()
|
||||
}
|
||||
|
||||
describe('CacheCleanupPage', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
Object.defineProperty(window, 'api', { configurable: true, value: api })
|
||||
api.getCacheSummary.mockResolvedValue({
|
||||
items: [
|
||||
{
|
||||
id: 'knowledge',
|
||||
label: '本地知识库索引',
|
||||
description: '问一问微信使用的本地检索索引',
|
||||
sizeBytes: 1024,
|
||||
fileCount: 1
|
||||
}
|
||||
],
|
||||
totalBytes: 1024,
|
||||
updatedAt: Date.now()
|
||||
})
|
||||
api.openKnowledgeDirectory.mockResolvedValue({ success: true })
|
||||
})
|
||||
|
||||
it('opens the real knowledge directory without clearing it', async () => {
|
||||
const onNotice = vi.fn()
|
||||
render(<CacheCleanupPage onNotice={onNotice} />)
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: '打开文件夹' }))
|
||||
|
||||
await waitFor(() => expect(api.openKnowledgeDirectory).toHaveBeenCalledOnce())
|
||||
expect(api.clearCache).not.toHaveBeenCalled()
|
||||
expect(onNotice).toHaveBeenCalledWith('已打开知识库文件夹')
|
||||
})
|
||||
})
|
||||
@@ -180,4 +180,16 @@ describe('DatabaseConnectionPage', () => {
|
||||
expect(screen.getByRole('button', { name: '返回上一步' })).toBeEnabled()
|
||||
expect(screen.getByRole('button', { name: '取消并重新检查' })).toBeEnabled()
|
||||
})
|
||||
it('provides the official Visual C++ runtime download on Windows', () => {
|
||||
renderPage({
|
||||
status: '当前 Windows 缺少 Microsoft Visual C++ 运行库',
|
||||
statusKind: 'error'
|
||||
})
|
||||
|
||||
expect(screen.getByRole('link', { name: '下载运行库' })).toHaveAttribute(
|
||||
'href',
|
||||
'https://aka.ms/vc14/vc_redist.x64.exe'
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -62,6 +62,8 @@ describe('preload IPC contract', () => {
|
||||
expect(invoke).toHaveBeenLastCalledWith('knowledge:startIndex')
|
||||
await api.clearCache('knowledge')
|
||||
expect(invoke).toHaveBeenLastCalledWith('cache:clear', 'knowledge')
|
||||
await api.openKnowledgeDirectory()
|
||||
expect(invoke).toHaveBeenLastCalledWith('cache:openKnowledgeDirectory')
|
||||
|
||||
await api.getImage('fixture-md5', 'fixture.dat', 'fixture-session', {
|
||||
force: true,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
isWindowsVcRuntimeMissingError,
|
||||
WINDOWS_VC_RUNTIME_DOWNLOAD_URL,
|
||||
WINDOWS_VC_RUNTIME_ERROR_MESSAGE
|
||||
} from '../../src/shared/windows-runtime'
|
||||
|
||||
describe('Windows Visual C++ runtime diagnostics', () => {
|
||||
it.each([
|
||||
'VCRUNTIME140_1.dll was not found',
|
||||
'MSVCP140.dll is missing',
|
||||
'The specified module could not be found',
|
||||
'Win32 error 126',
|
||||
'找不到指定的模块'
|
||||
])('recognizes a Windows native dependency load failure: %s', (detail) => {
|
||||
expect(isWindowsVcRuntimeMissingError(detail, 'win32')).toBe(true)
|
||||
})
|
||||
|
||||
it('does not relabel unrelated or non-Windows failures', () => {
|
||||
expect(isWindowsVcRuntimeMissingError('invalid database key', 'win32')).toBe(false)
|
||||
expect(isWindowsVcRuntimeMissingError('VCRUNTIME140.dll was not found', 'darwin')).toBe(false)
|
||||
})
|
||||
|
||||
it('keeps the official download URL in the actionable error message', () => {
|
||||
expect(WINDOWS_VC_RUNTIME_ERROR_MESSAGE).toContain(WINDOWS_VC_RUNTIME_DOWNLOAD_URL)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user