mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-06 13:54:10 +08:00
fix: 修复联系人 API 因昵称备注未补全导致搜索结果为空 #51
Fixes https://github.com/Wxw-Gu/TraceMemo/issues/51
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { WechatDb } from '../../src/main/wechat-db'
|
||||
import { listContacts, listContactsAsync, setChatDb } from '../../src/main/services/chat-service'
|
||||
|
||||
/**
|
||||
* Issue #51 root-cause evidence.
|
||||
*
|
||||
* `listContactsAsync` hydrates display names / identities before filtering,
|
||||
* while the synchronous `listContacts` reads whatever the session cache holds.
|
||||
* On macOS the session cache frequently only carries raw ids (mirrors the
|
||||
* production comment in `listContactsAsync`), so the sync path cannot match a
|
||||
* Chinese nickname even though hydration makes both the contact and the group
|
||||
* searchable.
|
||||
*/
|
||||
|
||||
const HYDRATED_USER_NAME = '张三'
|
||||
const HYDRATED_GROUP_NAME = '张三的测试群'
|
||||
|
||||
function createMacOsStyleFixtureDb(): WechatDb {
|
||||
// Before hydration the macOS session rows only expose raw identifiers.
|
||||
const userSession = { username: 'wxid_fixture_user', nickname: 'wxid_fixture_user' }
|
||||
const groupSession = { username: 'fixture_group@chatroom', nickname: 'fixture_group@chatroom' }
|
||||
|
||||
const getSessionsAsync = vi.fn(async (options: { hydrateDisplayNames?: boolean }) => {
|
||||
if (options.hydrateDisplayNames) {
|
||||
userSession.nickname = HYDRATED_USER_NAME
|
||||
groupSession.nickname = HYDRATED_GROUP_NAME
|
||||
}
|
||||
return [userSession, groupSession]
|
||||
})
|
||||
|
||||
const fakeDb = {
|
||||
close: vi.fn(),
|
||||
md5: (value: string) => `md5-${value}`,
|
||||
hydrateContactIdentitiesAsync: vi.fn(async () => undefined),
|
||||
getAllGroupContacts: () => ({ [`md5-${groupSession.username}`]: groupSession.nickname }),
|
||||
getUserList: () => [
|
||||
{
|
||||
m_nsUsrName: userSession.username,
|
||||
nickname: userSession.nickname,
|
||||
wxid: userSession.username
|
||||
},
|
||||
{
|
||||
m_nsUsrName: groupSession.username,
|
||||
nickname: groupSession.nickname
|
||||
}
|
||||
],
|
||||
getWcdb4Client: () => ({ getSessionsAsync })
|
||||
} as unknown as WechatDb
|
||||
|
||||
return fakeDb
|
||||
}
|
||||
|
||||
describe('chat service contact search on un-hydrated macOS sessions', () => {
|
||||
afterEach(() => setChatDb(null))
|
||||
|
||||
it('sync listContacts cannot see display names that only hydration provides', () => {
|
||||
setChatDb(createMacOsStyleFixtureDb())
|
||||
|
||||
expect(listContacts('张三')).toEqual([])
|
||||
})
|
||||
|
||||
it('async listContactsAsync hydrates first and returns both the contact and the group', async () => {
|
||||
setChatDb(createMacOsStyleFixtureDb())
|
||||
|
||||
const matches = await listContactsAsync('张三')
|
||||
|
||||
expect(matches.map((contact) => contact.type).sort()).toEqual(['group', 'user'])
|
||||
expect(matches.every((contact) => contact.m_nsNickName.includes('张三'))).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { Contact } from '../../src/shared/types'
|
||||
import { buildContactSearchIndex, filterContactSearchIndex } from '../../src/shared/contact-search'
|
||||
|
||||
/**
|
||||
* Issue #51 regression guard for the *shared* search primitives.
|
||||
*
|
||||
* The bug report claims that when one keyword matches a private contact AND a
|
||||
* group chat, the API returns nothing. These tests pin down that multi-match is
|
||||
* itself NOT the problem: the shared index/filter pair already returns every
|
||||
* match. The real defect lived in the data the HTTP layer fed into it.
|
||||
*/
|
||||
|
||||
const user: Contact = {
|
||||
m_nsUsrName: 'wxid_fixture_user',
|
||||
m_nsNickName: '张三',
|
||||
md5: 'fixture-user-md5',
|
||||
type: 'user',
|
||||
remark: '张三'
|
||||
}
|
||||
|
||||
const group: Contact = {
|
||||
m_nsUsrName: 'fixture_group@chatroom',
|
||||
m_nsNickName: '张三的测试群',
|
||||
md5: 'fixture-group-md5',
|
||||
type: 'group'
|
||||
}
|
||||
|
||||
describe('filterContactSearchIndex with a keyword hitting a contact and a group', () => {
|
||||
it('returns both matches instead of collapsing to an empty list', () => {
|
||||
const index = buildContactSearchIndex([user, group])
|
||||
expect(filterContactSearchIndex(index, '张三')).toEqual([user, group])
|
||||
})
|
||||
|
||||
it('still isolates the results with type=user', () => {
|
||||
const index = buildContactSearchIndex([user, group])
|
||||
expect(filterContactSearchIndex(index, '张三', 'user')).toEqual([user])
|
||||
})
|
||||
|
||||
it('still isolates the results with type=group', () => {
|
||||
const index = buildContactSearchIndex([user, group])
|
||||
expect(filterContactSearchIndex(index, '张三', 'group')).toEqual([group])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user