test(plans): harden route navigation coverage

This commit is contained in:
root 2026-05-06 20:30:16 +00:00
parent 11e2837bc9
commit 26dfb575be
2 changed files with 94 additions and 0 deletions

View File

@ -53,6 +53,16 @@ vi.mock('../../views/SettingsView', () => ({
}));
describe('AppShell routing fallback', () => {
it('renders the plans view directly on the canonical /plans route', async () => {
render(
<MemoryRouter initialEntries={['/plans']}>
<AppShell />
</MemoryRouter>,
);
expect(await screen.findByText('Simple view')).toBeInTheDocument();
});
it('keeps /simple as a redirect alias to the plans view', async () => {
render(
<MemoryRouter initialEntries={['/simple?setupId=setup-1']}>

View File

@ -0,0 +1,84 @@
// @vitest-environment jsdom
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { describe, expect, it, vi } from 'vitest';
import { PortfolioView } from './PortfolioView';
const navigateMock = vi.fn();
vi.mock('react-router-dom', async () => {
const actual = await vi.importActual<typeof import('react-router-dom')>('react-router-dom');
return {
...actual,
useNavigate: () => navigateMock,
};
});
vi.mock('../context/AppContext', () => ({
useAppContext: () => ({
botState: {
symbols: {},
alerts: [],
positions: [],
orders: [],
history: [],
settings: {
executionMode: 'Paper',
riskPerTrade: 0.01,
totalCapital: 1000,
maxOpenTrades: 3,
isAlgoEnabled: true,
enabledRules: [],
},
uptime: 1000,
},
}),
}));
vi.mock('../tabs/PositionsTab', () => ({
PositionsTab: ({ onManageHolding }: any) => (
<div>
<button
type="button"
onClick={() => onManageHolding?.({
symbol: 'AAPL',
tradeId: 'TRD-AAPL',
planEntryId: 'setup-aapl',
}, 'open-plan')}
>
open linked plan
</button>
<button
type="button"
onClick={() => onManageHolding?.({
symbol: 'MSFT',
tradeId: 'TRD-MSFT',
}, 'create-exit-plan')}
>
create exit plan
</button>
</div>
),
}));
vi.mock('../tabs/HistoryTab', () => ({
HistoryTab: () => <div>History tab</div>,
}));
describe('PortfolioView navigation', () => {
it('navigates to the canonical plans route for exact plan drill-in and new exit plans', async () => {
const user = userEvent.setup();
render(
<MemoryRouter>
<PortfolioView />
</MemoryRouter>,
);
await user.click(screen.getByRole('button', { name: 'open linked plan' }));
expect(navigateMock).toHaveBeenCalledWith('/plans?setupId=setup-aapl');
await user.click(screen.getByRole('button', { name: 'create exit plan' }));
expect(navigateMock).toHaveBeenCalledWith('/plans?mode=sell&symbol=MSFT&tradeId=TRD-MSFT');
});
});