fix: prompt reload for stale Web UI bundle (#641)
This commit is contained in:
@@ -152,6 +152,38 @@ describe('App Store', () => {
|
||||
expect(mockSystemApi.updateDefaultModel).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('marks the client stale when the served Web UI version changes', async () => {
|
||||
mockSystemApi.checkHealth.mockResolvedValue({
|
||||
status: 'ok',
|
||||
webui_version: '0.5.17',
|
||||
webui_latest: '0.5.17',
|
||||
webui_update_available: false,
|
||||
})
|
||||
const store = useAppStore()
|
||||
|
||||
await store.checkConnection()
|
||||
|
||||
expect(store.connected).toBe(true)
|
||||
expect(store.serverVersion).toBe('0.5.17')
|
||||
expect(store.clientOutdated).toBe(true)
|
||||
expect(store.updateAvailable).toBe(false)
|
||||
})
|
||||
|
||||
it('does not mark the client stale when the served Web UI version matches this bundle', async () => {
|
||||
mockSystemApi.checkHealth.mockResolvedValue({
|
||||
status: 'ok',
|
||||
webui_version: 'test',
|
||||
webui_latest: 'test',
|
||||
webui_update_available: false,
|
||||
})
|
||||
const store = useAppStore()
|
||||
|
||||
await store.checkConnection()
|
||||
|
||||
expect(store.serverVersion).toBe('test')
|
||||
expect(store.clientOutdated).toBe(false)
|
||||
})
|
||||
|
||||
it('clears the updating state and reports failure when self-update request fails', async () => {
|
||||
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
mockSystemApi.triggerUpdate.mockRejectedValue(new Error('install failed'))
|
||||
|
||||
@@ -3,6 +3,21 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
const openSessionSearchMock = vi.hoisted(() => vi.fn())
|
||||
const mockAppStore = vi.hoisted(() => ({
|
||||
sidebarOpen: true,
|
||||
sidebarCollapsed: false,
|
||||
connected: true,
|
||||
serverVersion: 'test',
|
||||
latestVersion: '',
|
||||
updateAvailable: false,
|
||||
clientOutdated: false,
|
||||
updating: false,
|
||||
toggleSidebar: vi.fn(),
|
||||
toggleSidebarCollapsed: vi.fn(),
|
||||
closeSidebar: vi.fn(),
|
||||
doUpdate: vi.fn(),
|
||||
reloadClient: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/useSessionSearch', () => ({
|
||||
useSessionSearch: () => ({
|
||||
@@ -11,16 +26,7 @@ vi.mock('@/composables/useSessionSearch', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/hermes/app', () => ({
|
||||
useAppStore: () => ({
|
||||
sidebarOpen: true,
|
||||
connected: true,
|
||||
serverVersion: 'test',
|
||||
updateAvailable: false,
|
||||
updating: false,
|
||||
toggleSidebar: vi.fn(),
|
||||
closeSidebar: vi.fn(),
|
||||
doUpdate: vi.fn(),
|
||||
}),
|
||||
useAppStore: () => mockAppStore,
|
||||
}))
|
||||
|
||||
vi.mock('vue-router', async (importOriginal) => {
|
||||
@@ -55,7 +61,7 @@ vi.mock('naive-ui', async () => {
|
||||
error: vi.fn(),
|
||||
}),
|
||||
NButton: {
|
||||
template: '<button><slot /></button>',
|
||||
template: '<button v-bind="$attrs"><slot /></button>',
|
||||
},
|
||||
NSelect: {
|
||||
template: '<div />',
|
||||
@@ -68,6 +74,12 @@ import AppSidebar from '@/components/layout/AppSidebar.vue'
|
||||
describe('AppSidebar search entry', () => {
|
||||
beforeEach(() => {
|
||||
openSessionSearchMock.mockClear()
|
||||
mockAppStore.serverVersion = 'test'
|
||||
mockAppStore.latestVersion = ''
|
||||
mockAppStore.updateAvailable = false
|
||||
mockAppStore.clientOutdated = false
|
||||
mockAppStore.updating = false
|
||||
mockAppStore.reloadClient.mockClear()
|
||||
})
|
||||
|
||||
it('opens the session search modal from the sidebar button', async () => {
|
||||
@@ -90,4 +102,26 @@ describe('AppSidebar search entry', () => {
|
||||
await searchButton!.trigger('click')
|
||||
expect(openSessionSearchMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('offers a client reload when the server version differs from the loaded bundle', async () => {
|
||||
mockAppStore.clientOutdated = true
|
||||
mockAppStore.serverVersion = '0.5.17'
|
||||
const wrapper = mount(AppSidebar, {
|
||||
global: {
|
||||
stubs: {
|
||||
ProfileSelector: true,
|
||||
ModelSelector: true,
|
||||
LanguageSwitch: true,
|
||||
ThemeSwitch: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const reloadButton = wrapper.findAll('button')
|
||||
.find(node => node.text().includes('sidebar.reloadClientVersion'))
|
||||
expect(reloadButton).toBeTruthy()
|
||||
|
||||
await reloadButton!.trigger('click')
|
||||
expect(mockAppStore.reloadClient).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user