98 lines
3.4 KiB
TypeScript
98 lines
3.4 KiB
TypeScript
/**
|
||
* 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()
|
||
})
|
||
})
|