mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 03:52:26 +08:00
Merge pull request #7973 from ouchihao/codex/bug-monitor-auto-detail-refresh
fix(monitor): refresh cached availability on automatic reload
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
:loading="loading"
|
||||
:auto-refresh="autoRefresh"
|
||||
@update:window="handleWindowChange"
|
||||
@refresh="manualReload"
|
||||
@refresh="refresh()"
|
||||
/>
|
||||
|
||||
<MonitorCardGrid
|
||||
@@ -67,7 +67,7 @@ const autoRefresh = useAutoRefresh({
|
||||
intervals: [30, 60, 120] as const,
|
||||
defaultInterval: DEFAULT_INTERVAL_SECONDS,
|
||||
defaultEnabled: true,
|
||||
onRefresh: () => reload(true),
|
||||
onRefresh: () => refresh(true),
|
||||
shouldPause: () => document.hidden || loading.value,
|
||||
})
|
||||
const countdown = autoRefresh.countdown
|
||||
@@ -109,8 +109,8 @@ async function reload(silent = false) {
|
||||
}
|
||||
}
|
||||
|
||||
async function manualReload() {
|
||||
await reload(false)
|
||||
async function refresh(silent = false) {
|
||||
await reload(silent)
|
||||
// After base reload, refresh any cached detail records so non-7d availability
|
||||
// values stay in sync without forcing the user to switch tabs again.
|
||||
if (currentWindow.value !== '7d') {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { enableAutoUnmount, flushPromises, shallowMount } from '@vue/test-utils'
|
||||
import ChannelStatusV1View from '../ChannelStatusV1View.vue'
|
||||
|
||||
const mocks = vi.hoisted(() => ({ list: vi.fn(), status: vi.fn() }))
|
||||
vi.mock('@/api/channelMonitor', () => mocks)
|
||||
vi.mock('@/stores/app', () => ({ useAppStore: () => ({ cachedPublicSettings: { channel_monitor_enabled: true }, showError: vi.fn() }) }))
|
||||
vi.mock('vue-i18n', async () => ({
|
||||
...await vi.importActual<typeof import('vue-i18n')>('vue-i18n'),
|
||||
useI18n: () => ({ t: (key: string) => key })
|
||||
}))
|
||||
enableAutoUnmount(afterEach)
|
||||
afterEach(() => { vi.useRealTimers(); localStorage.clear() })
|
||||
|
||||
function detail(availability: number) {
|
||||
return { id: 1, models: [{ model: 'model', availability_15d: availability, availability_30d: availability }] }
|
||||
}
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
vi.resetAllMocks()
|
||||
localStorage.clear()
|
||||
localStorage.setItem('channel-status-auto-refresh', JSON.stringify({ enabled: true, interval_seconds: 30 }))
|
||||
mocks.list.mockImplementation(async () => ({ items: [{ id: 1, name: 'Monitor', primary_model: 'model', primary_status: 'operational', availability_7d: 99 }] }))
|
||||
mocks.status.mockResolvedValue(detail(90))
|
||||
})
|
||||
|
||||
function mountView() {
|
||||
return shallowMount(ChannelStatusV1View, {
|
||||
global: { stubs: {
|
||||
AppLayout: { template: '<div><slot /></div>' },
|
||||
MonitorHero: { props: ['loading'], emits: ['update:window', 'refresh'], template: `<div :data-loading="loading">
|
||||
<button class="fifteen" @click="$emit('update:window', '15d')">15d</button>
|
||||
<button class="thirty" @click="$emit('update:window', '30d')">30d</button>
|
||||
<button class="refresh" @click="$emit('refresh')">Refresh</button>
|
||||
</div>` },
|
||||
MonitorCardGrid: false,
|
||||
MonitorCard: { props: ['availabilityValue'], template: '<output>{{ availabilityValue }}</output>' }
|
||||
} }
|
||||
})
|
||||
}
|
||||
|
||||
describe('channel monitor automatic detail refresh', () => {
|
||||
it.each(['fifteen', 'thirty'])('refreshes the cached %s-day availability on timer ticks', async (tab) => {
|
||||
const wrapper = mountView()
|
||||
await flushPromises()
|
||||
await wrapper.get('.' + tab).trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.get('output').text()).toBe('90')
|
||||
mocks.status.mockResolvedValue(detail(98))
|
||||
await vi.advanceTimersByTimeAsync(30000)
|
||||
await flushPromises()
|
||||
expect(wrapper.get('output').text()).toBe('98')
|
||||
expect(mocks.status).toHaveBeenCalledTimes(2)
|
||||
expect(wrapper.get('[data-loading]').attributes('data-loading')).toBe('false')
|
||||
})
|
||||
|
||||
it('keeps the seven-day view on the list endpoint without extra detail requests', async () => {
|
||||
const wrapper = mountView()
|
||||
await flushPromises()
|
||||
await vi.advanceTimersByTimeAsync(30000)
|
||||
await flushPromises()
|
||||
expect(mocks.list).toHaveBeenCalledTimes(2)
|
||||
expect(mocks.status).not.toHaveBeenCalled()
|
||||
expect(wrapper.get('output').text()).toBe('99')
|
||||
})
|
||||
|
||||
it('still refreshes cached availability on manual reload', async () => {
|
||||
const wrapper = mountView()
|
||||
await flushPromises()
|
||||
await wrapper.get('.fifteen').trigger('click')
|
||||
await flushPromises()
|
||||
mocks.status.mockResolvedValue(detail(98))
|
||||
await wrapper.get('.refresh').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.get('output').text()).toBe('98')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user