mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: add version update flow
This commit is contained in:
45
frontend/src/utils/__tests__/updateStatus.spec.ts
Normal file
45
frontend/src/utils/__tests__/updateStatus.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { CheckUpdateResponse } from '@/api/admin'
|
||||
import {
|
||||
buildUpdateErrorStatus,
|
||||
describeUpdateStatus,
|
||||
} from '../updateStatus'
|
||||
|
||||
function updateStatus(overrides: Partial<CheckUpdateResponse> = {}): CheckUpdateResponse {
|
||||
return {
|
||||
current_version: '0.7.0-rc27',
|
||||
latest_version: null,
|
||||
has_update: false,
|
||||
release_url: null,
|
||||
release_notes: null,
|
||||
published_at: null,
|
||||
error: null,
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
describe('updateStatus', () => {
|
||||
it('describes loading and latest states', () => {
|
||||
expect(describeUpdateStatus(null)).toBe('检查中')
|
||||
expect(describeUpdateStatus(updateStatus())).toBe('已是最新')
|
||||
})
|
||||
|
||||
it('prioritizes update availability over latest-version text', () => {
|
||||
expect(describeUpdateStatus(updateStatus({
|
||||
latest_version: 'v0.7.0-rc28',
|
||||
has_update: true,
|
||||
release_url: 'https://github.com/fawney19/Aether/releases/tag/v0.7.0-rc28',
|
||||
}))).toBe('有新版本')
|
||||
})
|
||||
|
||||
it('preserves the current version when building an error state', () => {
|
||||
const status = buildUpdateErrorStatus(
|
||||
updateStatus({ current_version: '0.7.0-rc28' }),
|
||||
new Error('network down')
|
||||
)
|
||||
|
||||
expect(status.current_version).toBe('0.7.0-rc28')
|
||||
expect(status.has_update).toBe(false)
|
||||
expect(status.error).toBe('network down')
|
||||
})
|
||||
})
|
||||
18
frontend/src/utils/__tests__/version.spec.ts
Normal file
18
frontend/src/utils/__tests__/version.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { formatDisplayVersion } from '../version'
|
||||
|
||||
describe('formatDisplayVersion', () => {
|
||||
it('adds one v prefix to unprefixed versions', () => {
|
||||
expect(formatDisplayVersion('0.7.0-rc28')).toBe('v0.7.0-rc28')
|
||||
})
|
||||
|
||||
it('keeps existing v prefixes intact', () => {
|
||||
expect(formatDisplayVersion('v0.7.0-rc28')).toBe('v0.7.0-rc28')
|
||||
})
|
||||
|
||||
it('preserves git describe development suffixes', () => {
|
||||
expect(formatDisplayVersion('0.7.0-rc28-11-g63149fe2-dirty')).toBe(
|
||||
'v0.7.0-rc28-11-g63149fe2-dirty'
|
||||
)
|
||||
})
|
||||
})
|
||||
23
frontend/src/utils/updateStatus.ts
Normal file
23
frontend/src/utils/updateStatus.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { CheckUpdateResponse } from '@/api/admin'
|
||||
|
||||
export function describeUpdateStatus(status: CheckUpdateResponse | null): string {
|
||||
if (!status) return '检查中'
|
||||
if (status.has_update) return '有新版本'
|
||||
if (status.error) return '检查失败'
|
||||
return '已是最新'
|
||||
}
|
||||
|
||||
export function buildUpdateErrorStatus(
|
||||
previousStatus: CheckUpdateResponse | null,
|
||||
error: unknown
|
||||
): CheckUpdateResponse {
|
||||
return {
|
||||
current_version: previousStatus?.current_version || '',
|
||||
latest_version: null,
|
||||
has_update: false,
|
||||
release_url: null,
|
||||
release_notes: null,
|
||||
published_at: null,
|
||||
error: error instanceof Error ? error.message : '检查更新失败'
|
||||
}
|
||||
}
|
||||
5
frontend/src/utils/version.ts
Normal file
5
frontend/src/utils/version.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export function formatDisplayVersion(version: string): string {
|
||||
const normalized = version.trim()
|
||||
if (!normalized) return ''
|
||||
return normalized.startsWith('v') || normalized.startsWith('V') ? normalized : `v${normalized}`
|
||||
}
|
||||
Reference in New Issue
Block a user