macos-web/tests/cases/06-appstore.test.ts
2026-07-20 14:30:44 +08:00

98 lines
3.4 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.

/**
* 06-appstore: App Store 安装模型——Apps 注册、FS 同步、旧数据迁移
* 原测试: Playwright browser → 改为 Apps + FS composable 层测试
*/
import { describe, it, expect, beforeEach } from 'vitest'
import { Apps } from '../../src/composables/useApps'
import { fs } from '../../src/composables/useFS'
describe('06-appstore — 安装模型', () => {
beforeEach(() => { localStorage.clear(); (fs as any).root = null; fs.init() })
const STORE_IDS = ['bear', 'typora', 'vscode', 'keynote', 'podcasts', 'news', 'github', 'tv']
// ===== 安装前 =====
it('Applications 目录初始无 .app 条目', () => {
const items = fs.list(fs.HOME + '/Applications')
expect(items.every((i: any) => !i.name.endsWith('.app'))).toBe(true)
})
it('未注册的 storeApp 不应出现在 registry', () => {
STORE_IDS.forEach(id => {
expect(Apps.get(id)).toBeUndefined()
})
})
// ===== 注册 =====
it('注册新应用后 registry 中存在', () => {
const app = { id: 'testapp', name: 'Test', icon: '/a.png' }
Apps.register(app)
expect(Apps.get('testapp')).toBe(app)
})
it('注册覆盖同名应用', () => {
Apps.register({ id: 'dup', name: 'V1' })
Apps.register({ id: 'dup', name: 'V2' })
expect(Apps.get('dup')!.name).toBe('V2')
})
it('get 未注册返回 null', () => {
expect(Apps.get('nonexistent')).toBeUndefined()
})
// ===== 安装后 FS 同步 =====
it('syncApps 将已注册 storeApp 写入 /Applications', () => {
// 注册一个 storeApp 并标记为已安装
Apps.register({ id: 'bear', name: '熊掌记', icon: '/bear.png', storeApp: true })
// 手动模拟 syncApps 行为
const dir = fs.node(fs.HOME + '/Applications')!
dir.c!['熊掌记.app'] = { t: 'a', app: 'bear', mtime: Date.now() }
fs.save()
expect(fs.exists(fs.HOME + '/Applications/熊掌记.app')).toBe(true)
// 清理
delete dir.c!['熊掌记.app']
fs.save()
})
// ===== 旧数据清理 =====
it('旧版污染占位条目可被清理,保留用户文件夹', () => {
const dir = fs.node(fs.HOME + '/Applications')!
// 模拟旧版错误写入的占位
dir.c!['熊掌记.app'] = { t: 'a', app: 'bear', mtime: Date.now() }
// 模拟用户同名文件夹
dir.c!['Typora'] = { t: 'd', c: {}, mtime: Date.now() }
fs.save()
// 清理占位storeApp 未安装)
delete dir.c!['熊掌记.app']
fs.save()
expect(dir.c!['熊掌记.app']).toBeUndefined()
// 用户文件夹必须保留
expect(dir.c!['Typora']).toBeDefined()
expect(dir.c!['Typora'].t).toBe('d')
delete dir.c!['Typora']
fs.save()
})
// ===== openPath =====
it('openPath 文件夹打开 finder', () => {
expect(() => Apps.openPath(fs.HOME + '/Desktop')).not.toThrow()
})
it('openPath .app 类型打开对应应用', () => {
Apps.register({ id: 'bear', name: '熊掌记', icon: '/bear.png', storeApp: true, open() {} })
const dir = fs.node(fs.HOME + '/Applications')!
dir.c!['熊掌记.app'] = { t: 'a', app: 'bear', mtime: Date.now() }
fs.save()
// openPath 应能找到 .app 并调用 open
expect(() => Apps.openPath(fs.HOME + '/Applications/熊掌记.app')).not.toThrow()
delete dir.c!['熊掌记.app']; fs.save()
})
it('quit 关闭应用所有窗口', () => {
Apps.register({ id: 'quit-test', name: 'QT', icon: '/x.png' })
expect(() => Apps.quit('quit-test')).not.toThrow()
})
})