mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-20 00:18:55 +00:00
Merge pull request #7183 from ouchihao/codex/bug-proxy-test-dedup
fix(proxies): reuse in-flight test guards during batch testing
This commit is contained in:
@@ -274,20 +274,7 @@ const handleBatchTest = async () => {
|
||||
batchTesting.value = true
|
||||
|
||||
// Test all proxies in parallel
|
||||
const testPromises = props.proxies.map(async (proxy) => {
|
||||
testingProxyIds.add(proxy.id)
|
||||
try {
|
||||
const result = await adminAPI.proxies.testProxy(proxy.id)
|
||||
testResults[proxy.id] = result
|
||||
} catch (error: any) {
|
||||
testResults[proxy.id] = {
|
||||
success: false,
|
||||
message: error.response?.data?.detail || 'Test failed'
|
||||
}
|
||||
} finally {
|
||||
testingProxyIds.delete(proxy.id)
|
||||
}
|
||||
})
|
||||
const testPromises = props.proxies.map(handleTestProxy)
|
||||
|
||||
await Promise.all(testPromises)
|
||||
batchTesting.value = false
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import ProxySelector from '../ProxySelector.vue'
|
||||
import type { Proxy } from '@/types'
|
||||
|
||||
const testProxy = vi.hoisted(() => vi.fn())
|
||||
vi.mock('@/api/admin', () => ({ adminAPI: { proxies: { testProxy } } }))
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key: string) => key }) }))
|
||||
enableAutoUnmount(afterEach)
|
||||
beforeEach(() => { vi.clearAllMocks() })
|
||||
|
||||
async function openSelector() {
|
||||
const wrapper = mount(ProxySelector, {
|
||||
props: { modelValue: null, proxies: [1, 2].map(id => ({
|
||||
id, name: `Proxy ${id}`, host: 'localhost', port: 8080, protocol: 'http'
|
||||
} as Proxy)) },
|
||||
global: { stubs: { Icon: true } }
|
||||
})
|
||||
await wrapper.get('.select-trigger').trigger('click')
|
||||
return wrapper
|
||||
}
|
||||
|
||||
describe('proxy connection tests', () => {
|
||||
it('does not restart an individual test when a batch is started', async () => {
|
||||
let finish!: (result: object) => void
|
||||
testProxy.mockImplementation((id: number) => id === 1
|
||||
? new Promise(resolve => { finish = resolve })
|
||||
: Promise.resolve({ success: true, country: 'GB' }))
|
||||
const wrapper = await openSelector()
|
||||
await wrapper.findAll('.test-btn')[0].trigger('click')
|
||||
await wrapper.get('.batch-test-btn').trigger('click')
|
||||
await flushPromises()
|
||||
expect(testProxy.mock.calls.map(([id]) => id)).toEqual([1, 2])
|
||||
expect(wrapper.findAll('.test-btn')[0].attributes('disabled')).toBeDefined()
|
||||
finish({ success: true, country: 'US' })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('US')
|
||||
expect(wrapper.findAll('.test-btn')[0].attributes('disabled')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('shows per-proxy outcomes and allows another batch after a failure', async () => {
|
||||
testProxy.mockImplementation((id: number) => id === 1
|
||||
? Promise.reject(new Error('offline'))
|
||||
: Promise.resolve({ success: true, country: 'GB' }))
|
||||
const wrapper = await openSelector()
|
||||
await wrapper.get('.batch-test-btn').trigger('click')
|
||||
await flushPromises()
|
||||
expect(testProxy).toHaveBeenCalledTimes(2)
|
||||
expect(wrapper.text()).toContain('admin.proxies.testFailed')
|
||||
expect(wrapper.text()).toContain('GB')
|
||||
expect(wrapper.get('.batch-test-btn').attributes('disabled')).toBeUndefined()
|
||||
await wrapper.get('.batch-test-btn').trigger('click')
|
||||
await flushPromises()
|
||||
expect(testProxy).toHaveBeenCalledTimes(4)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user