Merge the single and multi strategy panels into one

The single "Strategy" panel and "Strategies (multi)" were redundant: the multi
panel with one row is exactly the single-strategy behaviour. Remove StrategyPanel
and make "Strategies" the one trading panel. Presets move into it (load adds a
row, per-row Save), and the header now reports "N strategies" when several run
instead of only the first. Deletes the obsolete component and its test; adds
preset tests to the multi-strategy suite.
This commit is contained in:
matitos committed 2026-09-22 17:57:10 +00:00
1 parent d4d864dc5c
commit 50b22df948
6 files changed
+119 -176

No files matched your search

+51 -3
View File
@@ -1,7 +1,11 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { afterEach, describe, expect, it, vi } from 'vitest'
import MultiStrategyPanel from './components/MultiStrategyPanel.vue'
afterEach(() => {
vi.restoreAllMocks()
})
const STRATEGIES = [
{
key: 'sma_cross',
@@ -19,9 +23,20 @@ const STRATEGIES = [
const EMPTY_STATUS = { running: false, strategies: [], total_pnl: 0, equity: 0 }
function mountPanel(multiStatus = EMPTY_STATUS) {
const PRESETS = [
{
id: 1,
name: 'BTC fast',
strategy_key: 'ema_cross',
symbol: 'ETH/USDT',
timeframe: '15m',
params: { fast: 3 },
},
]
function mountPanel(multiStatus = EMPTY_STATUS, presets = []) {
return mount(MultiStrategyPanel, {
props: { strategies: STRATEGIES, multiStatus, busy: false, loading: false },
props: { strategies: STRATEGIES, multiStatus, presets, busy: false, loading: false },
})
}
@@ -89,6 +104,39 @@ describe('MultiStrategyPanel', () => {
expect(text).toContain('running')
})
it('loads a preset as an additional row', async () => {
const wrapper = mountPanel(EMPTY_STATUS, PRESETS)
const presetSelect = wrapper.findAll('select').find((s) => s.text().includes('BTC fast'))
expect(presetSelect).toBeTruthy()
await presetSelect.setValue('1')
// A second row now exists, seeded from the preset.
expect(wrapper.findAll('select').length).toBeGreaterThan(1)
const inputs = wrapper.findAll('input')
expect(inputs.some((i) => i.element.value === 'ETH/USDT')).toBe(true)
expect(inputs.some((i) => i.element.value === '15m')).toBe(true)
})
it('emits save-preset with the row config', async () => {
vi.spyOn(window, 'prompt').mockReturnValue('my preset')
const wrapper = mountPanel()
const save = wrapper.findAll('button').find((b) => b.text() === 'Save')
await save.trigger('click')
const payload = wrapper.emitted('save-preset')[0][0]
expect(payload.name).toBe('my preset')
expect(payload.strategy_key).toBe('sma_cross')
expect(payload.params).toEqual({ fast: 10 })
})
it('does not save when the prompt is cancelled', async () => {
vi.spyOn(window, 'prompt').mockReturnValue(null)
const wrapper = mountPanel()
const save = wrapper.findAll('button').find((b) => b.text() === 'Save')
await save.trigger('click')
expect(wrapper.emitted('save-preset')).toBeUndefined()
})
it('marks a halted strategy', () => {
const wrapper = mountPanel({
running: true,