Files
WechatExplorer/tests/unit/skill-resource-service.test.ts
T
Wxw-Gu cf3f115124 feat: 完成 TraceMemo v2.2.0 品牌身份与数据迁移升级
- 将 WechatExplorer 产品身份升级为 TraceMemo
- 更新 appId、Runtime Identity、Reader Skill 和 API 环境变量
- 增加旧用户数据、Knowledge、Token 与 AI Provider 安全迁移
- 保留 Windows WeFlow 和旧版配置兼容
- 完善首次启动迁移测试及 v2.2.0 发布文档
- 移除 macOS Intel x64 构建与发布支持
2026-08-11 17:52:57 +08:00

108 lines
3.5 KiB
TypeScript

import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { dirname, join, resolve } from 'path'
import { afterEach, describe, expect, it } from 'vitest'
import {
getSkillCandidates,
resolveSkillResourceStatus
} from '../../src/main/services/skill-resource-service'
const roots: string[] = []
function fixtureRoot(): string {
const root = mkdtempSync(join(tmpdir(), 'wxe-reader-skill-'))
roots.push(root)
return root
}
function environment(root: string, packaged: boolean) {
return {
appPath: join(root, 'application'),
cwd: join(root, 'workspace'),
resourcesPath: join(root, 'runtime', 'resources'),
execPath: join(root, 'runtime', 'WechatExplorer.exe'),
packaged
}
}
function writeSkill(filePath: string): void {
mkdirSync(dirname(filePath), { recursive: true })
writeFileSync(filePath, '# TraceMemo Reader\n', 'utf8')
}
describe('Reader Skill resource resolution', () => {
afterEach(() => {
while (roots.length) rmSync(roots.pop()!, { recursive: true, force: true })
})
it('finds the repository Skill from the current working directory in development', () => {
const root = fixtureRoot()
const runtime = environment(root, false)
const skillPath = join(runtime.cwd, 'docs', 'skill', 'tracememo-reader', 'SKILL.md')
writeSkill(skillPath)
expect(resolveSkillResourceStatus(runtime)).toMatchObject({
available: true,
source: 'development',
version: 'v1.2',
filePath: skillPath,
directoryPath: dirname(skillPath)
})
})
it('resolves the Reader Skill from this checkout', () => {
const workspace = resolve(__dirname, '../..')
const status = resolveSkillResourceStatus({
appPath: workspace,
cwd: workspace,
resourcesPath: join(workspace, 'node_modules', 'electron', 'resources'),
execPath: join(workspace, 'node_modules', 'electron', 'electron.exe'),
packaged: false
})
expect(status).toMatchObject({
available: true,
source: 'development',
version: 'v1.2',
filePath: join(workspace, 'docs', 'skill', 'tracememo-reader', 'SKILL.md')
})
})
it('uses the extraResources Skill directory in a packaged runtime', () => {
const root = fixtureRoot()
const runtime = environment(root, true)
const skillPath = join(runtime.resourcesPath, 'skill', 'tracememo-reader', 'SKILL.md')
writeSkill(skillPath)
expect(resolveSkillResourceStatus(runtime)).toMatchObject({
available: true,
source: 'bundled',
filePath: skillPath
})
})
it('falls back to the legacy Skill directory for one compatibility release', () => {
const root = fixtureRoot()
const runtime = environment(root, true)
const skillPath = join(runtime.resourcesPath, 'skill', 'wechatexplorer-reader', 'SKILL.md')
writeSkill(skillPath)
expect(resolveSkillResourceStatus(runtime)).toMatchObject({
available: true,
source: 'bundled',
filePath: skillPath
})
})
it('reports every checked path without duplicating candidates', () => {
const root = fixtureRoot()
const runtime = environment(root, false)
const candidates = getSkillCandidates(runtime)
const status = resolveSkillResourceStatus(runtime)
expect(new Set(candidates.map((candidate) => candidate.path)).size).toBe(candidates.length)
expect(status).toMatchObject({ available: false, source: 'development' })
for (const candidate of candidates) expect(status.error).toContain(candidate.path)
})
})