Files
WechatExplorer/tests/unit/ai-search-time-range.test.ts

104 lines
3.6 KiB
TypeScript
Raw Permalink 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_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('matches an explicitly mentioned nickname when the user omits punctuation', () => {
expect(includesExplicitAiSearchAlias('我和中田健身弘毅最近聊了什么?', '中田健身-弘毅')).toBe(
true
)
})
})