mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-17 03:27:00 +08:00
test: 暂存代码
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
const { fork } = require('node:child_process')
|
||||
const { existsSync, mkdtempSync } = require('node:fs')
|
||||
const { rm } = require('node:fs/promises')
|
||||
const { tmpdir } = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { randomUUID, createHash } = require('node:crypto')
|
||||
|
||||
const workerPath = join(__dirname, '..', 'out', 'main', 'knowledgeWorker.js')
|
||||
if (!existsSync(workerPath)) throw new Error(`Knowledge worker build is missing: ${workerPath}`)
|
||||
|
||||
const root = mkdtempSync(join(tmpdir(), 'wxe-knowledge-worker-'))
|
||||
const child = fork(workerPath, [], {
|
||||
stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
||||
serialization: 'advanced',
|
||||
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' }
|
||||
})
|
||||
const pending = new Map()
|
||||
|
||||
function request(type, payload) {
|
||||
const requestId = randomUUID()
|
||||
return new Promise((resolve, reject) => {
|
||||
pending.set(requestId, { resolve, reject })
|
||||
child.send({ version: 1, type, requestId, payload }, (error) => {
|
||||
if (error) reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
child.on('message', (message) => {
|
||||
if (!message || message.type === 'progress') return
|
||||
const current = pending.get(message.requestId)
|
||||
if (!current) return
|
||||
pending.delete(message.requestId)
|
||||
if (message.type === 'error') current.reject(new Error(message.error))
|
||||
else current.resolve(message.payload)
|
||||
})
|
||||
|
||||
function fts(profileId) {
|
||||
return {
|
||||
profileId,
|
||||
tokenizer: 'trigram',
|
||||
contentMode: 'external',
|
||||
detail: 'full',
|
||||
columnsize: 1
|
||||
}
|
||||
}
|
||||
|
||||
function conversation(accountId, id) {
|
||||
return {
|
||||
conversationId: `conversation-${id}`,
|
||||
completeSnapshot: true,
|
||||
messages: [
|
||||
{
|
||||
accountId,
|
||||
conversationId: `conversation-${id}`,
|
||||
messageId: `message-${id}`,
|
||||
createTime: 1,
|
||||
senderId: 'fixture-member',
|
||||
senderName: '脱敏成员',
|
||||
kind: 'text',
|
||||
text: `脱敏索引内容 ${id}`
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
function accountPath(accountId) {
|
||||
const key = createHash('sha256')
|
||||
.update(`knowledge-account-v1:${accountId}`)
|
||||
.digest('hex')
|
||||
.slice(0, 32)
|
||||
return join(root, key, 'knowledge.sqlite')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const chunker = {
|
||||
version: 'conversation-v1',
|
||||
maxGapMs: 600000,
|
||||
maxMessages: 12,
|
||||
maxCharacters: 1200,
|
||||
overlapMessages: 3
|
||||
}
|
||||
const accountA = 'worker-fixture-a'
|
||||
const accountB = 'worker-fixture-b'
|
||||
const first = await request('index', {
|
||||
accountId: accountA,
|
||||
databaseRoot: root,
|
||||
conversations: [conversation(accountA, 'a')],
|
||||
chunker,
|
||||
fts: fts('worker-a')
|
||||
})
|
||||
await request('index', {
|
||||
accountId: accountB,
|
||||
databaseRoot: root,
|
||||
conversations: [conversation(accountB, 'b')],
|
||||
chunker,
|
||||
fts: fts('worker-b')
|
||||
})
|
||||
if (
|
||||
!first ||
|
||||
first.cancelled ||
|
||||
!existsSync(accountPath(accountA)) ||
|
||||
!existsSync(accountPath(accountB))
|
||||
) {
|
||||
throw new Error('Knowledge worker did not create isolated derived databases')
|
||||
}
|
||||
const search = await request('search', {
|
||||
accountId: accountA,
|
||||
databaseRoot: root,
|
||||
fts: fts('worker-a'),
|
||||
text: '查询脱敏索引内容 a',
|
||||
terms: ['脱敏索引内容', 'a'],
|
||||
limit: 10
|
||||
})
|
||||
const evidence = search?.evidence?.[0]
|
||||
if (
|
||||
search?.state !== 'ready' ||
|
||||
!evidence ||
|
||||
evidence.messageId !== 'message-a' ||
|
||||
evidence.conversationId !== 'conversation-a' ||
|
||||
evidence.sender !== '脱敏成员' ||
|
||||
typeof evidence.timestamp !== 'number'
|
||||
) {
|
||||
throw new Error('Knowledge worker search did not return message-level evidence')
|
||||
}
|
||||
await request('remove', { accountId: accountA, databaseRoot: root })
|
||||
if (existsSync(accountPath(accountA)) || !existsSync(accountPath(accountB))) {
|
||||
throw new Error('Knowledge worker removal crossed an account boundary')
|
||||
}
|
||||
const unavailable = await request('search', {
|
||||
accountId: accountA,
|
||||
databaseRoot: root,
|
||||
fts: fts('worker-a'),
|
||||
text: '查询脱敏索引内容 a',
|
||||
terms: ['脱敏索引内容'],
|
||||
limit: 10
|
||||
})
|
||||
if (unavailable?.state !== 'unavailable' || unavailable.evidence?.length) {
|
||||
throw new Error('Knowledge worker did not report unavailable index after removal')
|
||||
}
|
||||
await request('close', {})
|
||||
console.log('Knowledge worker integration check passed')
|
||||
} finally {
|
||||
child.kill()
|
||||
await rm(root, { recursive: true, force: true })
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
Reference in New Issue
Block a user