Files
WechatExplorer/tests/unit/ai-search-time-range.test.ts
T
Wxw-Gu f93dc539e4 fix: 修复 AI 检索 Evidence 覆盖与加载更多问题
修复问一问微信查询遗漏群聊的问题
区分会话覆盖与发送者覆盖策略
新增问一问微信加载更多功能
2026-08-18 14:19:28 +08:00

124 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import {
buildLocalAiSearchPlan,
includesExplicitAiSearchAlias,
inferAiSearchTimeRange
} from '../../src/shared/ai-search'
const NOW = new Date('2026-08-05T12:00:00+08:00')
describe('AI search natural-language time ranges', () => {
it('tightens an all-history selection when the user says 最近', () => {
expect(inferAiSearchTimeRange('我和张三最近聊了什么?', 'all', NOW)).toMatchObject({
label: '近 30 天',
source: 'query',
startTime: Math.floor(NOW.getTime() / 1000) - 30 * 86400
})
})
it('recognizes explicit recent days and the current year', () => {
expect(inferAiSearchTimeRange('我和张三最近三天聊了什么?', 'all', NOW)).toMatchObject({
label: '近 3 天',
source: 'query'
})
expect(inferAiSearchTimeRange('我和张三今年聊了什么?', 'all', NOW)).toMatchObject({
label: '今年',
startTime: Math.floor(new Date(2026, 0, 1).getTime() / 1000)
})
})
it('keeps an explicit user retry override above the word 最近 in the original question', () => {
expect(
inferAiSearchTimeRange('我和张三最近聊了什么?', 'all', NOW, {
label: '全部历史',
reason: '用户主动扩大到全部历史',
source: 'user_retry'
})
).toMatchObject({
label: '全部历史',
source: 'user_retry'
})
})
it('keeps an explicit UI range above the generic word 最近', () => {
expect(
inferAiSearchTimeRange('我和张三最近聊了什么?', '7d', NOW, {
startTime: Math.floor(NOW.getTime() / 1000) - 7 * 86400,
endTime: undefined,
label: '近 7 天',
reason: '用户在界面选择的时间范围',
source: 'user_selected'
})
).toMatchObject({
label: '近 7 天',
source: 'user_selected',
startTime: Math.floor(NOW.getTime() / 1000) - 7 * 86400
})
})
it('classifies a direct person recap as conversation_recall rather than a topic FTS query', () => {
expect(buildLocalAiSearchPlan('我和张三最近聊了什么?')).toMatchObject({
intent: 'conversation_recall',
contactQuery: '张三'
})
})
it('keeps identity and message topic separate for a contact topic search', () => {
expect(buildLocalAiSearchPlan('我和张三最近聊过健身吗?')).toMatchObject({
intent: 'conversation_topic_search',
contactQuery: '张三',
topicQuery: '健身',
keywords: ['健身']
})
})
it('classifies global topics and bare conversation names without turning names into FTS terms', () => {
expect(buildLocalAiSearchPlan('最近谁聊过 MCP')).toMatchObject({
intent: 'global_sender_topic_search',
topicQuery: 'MCP',
keywords: ['MCP']
})
expect(buildLocalAiSearchPlan('技术交流群')).toMatchObject({
intent: 'conversation_name_search',
contactQuery: '技术交流群',
topicQuery: undefined
})
expect(buildLocalAiSearchPlan('技术交流群最近说了什么')).toMatchObject({
intent: 'conversation_name_search',
contactQuery: '技术交流群',
topicQuery: undefined
})
expect(buildLocalAiSearchPlan('技术交流群最近聊了啥')).toMatchObject({
intent: 'conversation_name_search',
contactQuery: '技术交流群',
topicQuery: undefined
})
})
it('classifies group conversation questions separately from sender questions', () => {
for (const question of [
'哪个群聊过 WechatExplorer',
'哪些群聊过 WechatExplorer',
'哪些群讨论过 WechatExplorer',
'哪个群说过 WechatExplorer'
]) {
expect(buildLocalAiSearchPlan(question)).toMatchObject({
intent: 'global_group_topic_search',
topicQuery: 'WechatExplorer',
keywords: ['WechatExplorer']
})
}
expect(buildLocalAiSearchPlan('谁聊过 WechatExplorer')).toMatchObject({
intent: 'global_sender_topic_search',
topicQuery: 'WechatExplorer',
keywords: ['WechatExplorer']
})
})
it('matches an explicitly mentioned nickname when the user omits punctuation', () => {
expect(includesExplicitAiSearchAlias('我和中田健身弘毅最近聊了什么?', '中田健身-弘毅')).toBe(
true
)
})
})