skillhub/cli/test/unit/services/update-service.test.ts
dongmucat e249db35a3 test(cli): add comprehensive integration tests and fix update command bugs
- Add integration tests for doctor, install, list, publish, remove, whoami commands
- Expand fake-registry with resolve/delete state capture for real assertions
- Fix update command: use correct package name @astron-team/skillhub from constants
- Refactor runUpdateCommand to accept string[] instead of fragile string splitting
- Add dependency injection to updateCommand for testable unit tests without global mocks
- Replace package.json import with codegen (scripts/generate-pkg-info.ts) to avoid
  leaking devDependencies into the build artifact
- Fix startNetworkFailureServer TOCTOU race by keeping listener alive
- Add TODO markers for known help command bugs (--json not forwarded, unknown topic crash)
- Extend update integration test timeout for real npm registry checks
2026-05-07 14:46:40 +08:00

90 lines
2.9 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { UpdateService } from '../../../src/services/update-service'
describe('UpdateService', () => {
test('npx install mode only suggests next command', async () => {
const service = new UpdateService({
currentVersion: '0.1.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'npx',
run: async () => { throw new Error('should not run') }
})
const result = await service.update({ checkOnly: false })
expect(result.updated).toBe(false)
expect(result.next).toContain('npx @astron-team/skillhub@latest')
})
test('npm-global install mode runs npm update', async () => {
let executed: readonly string[] = []
const service = new UpdateService({
currentVersion: '0.1.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'npm-global',
run: async (cmd) => { executed = cmd; return { success: true, output: '' } }
})
const result = await service.update({ checkOnly: false })
expect(result.updated).toBe(true)
expect(executed).toEqual(['npm', 'install', '-g', '@astron-team/skillhub@latest'])
})
test('bun-global install mode runs bun update', async () => {
let executed: readonly string[] = []
const service = new UpdateService({
currentVersion: '0.1.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'bun-global',
run: async (cmd) => { executed = cmd; return { success: true, output: '' } }
})
const result = await service.update({ checkOnly: false })
expect(result.updated).toBe(true)
expect(executed).toEqual(['bun', 'add', '-g', '@astron-team/skillhub@latest'])
})
test('unknown install mode only suggests next command', async () => {
const service = new UpdateService({
currentVersion: '0.1.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'unknown',
run: async () => { throw new Error('should not run') }
})
const result = await service.update({ checkOnly: false })
expect(result.updated).toBe(false)
expect(result.next).toBeTruthy()
})
test('checkOnly mode does not execute update', async () => {
const service = new UpdateService({
currentVersion: '0.1.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'npm-global',
run: async () => { throw new Error('should not run') }
})
const result = await service.update({ checkOnly: true })
expect(result.updated).toBe(false)
expect(result.available).toBe(true)
})
test('no update available', async () => {
const service = new UpdateService({
currentVersion: '0.2.0',
latestVersion: async () => '0.2.0',
detectInstallMode: () => 'npm-global',
run: async () => { throw new Error('should not run') }
})
const result = await service.update({ checkOnly: false })
expect(result.updated).toBe(false)
expect(result.available).toBe(false)
})
})