fix: improve broker account shell accessibility

This commit is contained in:
Sergey Krylov 2026-06-19 06:32:20 +03:00
parent 633def5ebb
commit 1c26d2a3eb
3 changed files with 69 additions and 6 deletions

View File

@ -40,9 +40,9 @@ export function BrokerAccountLayout() {
</NavLink>
</nav>
<main className="broker-account__content">
<div className="broker-account__content">
<Outlet context={context} />
</main>
</div>
</div>
</div>
);

View File

@ -9,7 +9,7 @@ import * as operationsHook from '../../hooks/useBrokerOperations';
import * as portfolioHook from '../../hooks/useBrokerPortfolio';
import * as positionsHook from '../../hooks/useBrokerPositions';
import type { BrokerPosition } from '../../api/responses';
import { BrokerAccountLayout } from './BrokerAccountLayout';
import { BrokerAccountLayout, useBrokerAccountContext } from './BrokerAccountLayout';
import { BrokerAccountDetailPage } from './BrokerAccountDetailPage';
import { BrokerAccountsPage } from './BrokerAccountsPage';
@ -63,6 +63,19 @@ function mockUseBrokerPositions(...positions: BrokerPosition[]) {
});
}
function BrokerAccountContextProbe({ expectedPortfolio }: { expectedPortfolio: unknown }) {
const { accountId, portfolio } = useBrokerAccountContext();
return (
<div>
<p>Account context: {accountId}</p>
<p>
{portfolio === expectedPortfolio ? 'Same portfolio query' : 'Different portfolio query'}
</p>
</div>
);
}
describe('Broker pages', () => {
it('renders account section navigation with the current nested route', () => {
vi.spyOn(portfolioHook, 'useBrokerPortfolio').mockReturnValue({
@ -117,6 +130,59 @@ describe('Broker pages', () => {
expect(activeLink).toHaveAttribute('aria-current', 'page');
expect(activeLink).toHaveClass('is-active');
expect(screen.getByText('Содержимое облигаций')).toBeInTheDocument();
expect(screen.queryByRole('main')).not.toBeInTheDocument();
});
it('passes the decoded account and exact portfolio query through outlet context', () => {
const portfolioResult = {
data: {
account: {
id: 'account one',
type: 'brokerage',
name: 'Encoded account',
status: 'ACCOUNT_STATUS_OPEN',
openedAt: null,
accessLevel: null,
},
totals: { portfolio: { currency: 'RUB', units: '1000', nano: 0, value: 1000 } },
yields: { expectedPercent: 5, daily: null, dailyPercent: null },
cash: [],
blockedCash: [],
asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
isFetching: false,
error: null,
} as any;
const portfolioSpy = vi
.spyOn(portfolioHook, 'useBrokerPortfolio')
.mockReturnValue(portfolioResult);
renderWithClient(
<Routes>
<Route path="/broker/:accountId" element={<BrokerAccountLayout />}>
<Route
path="bonds"
element={<BrokerAccountContextProbe expectedPortfolio={portfolioResult} />}
/>
</Route>
</Routes>,
['/broker/account%20one/bonds'],
);
expect(screen.getByText('Account context: account one')).toBeInTheDocument();
expect(screen.getByText('Same portfolio query')).toBeInTheDocument();
expect(portfolioSpy).toHaveBeenCalledWith('account one');
const navigation = screen.getByRole('navigation', { name: 'Разделы брокерского счёта' });
expect(within(navigation).getByRole('link', { name: 'Обзор' })).toHaveAttribute(
'href',
'/broker/account%20one',
);
expect(within(navigation).getByRole('link', { name: 'Облигации' })).toHaveAttribute(
'href',
'/broker/account%20one/bonds',
);
});
it('keeps account navigation and nested content visible when the portfolio is unavailable', () => {

View File

@ -118,9 +118,6 @@ a {
@media (max-width: 720px) {
.broker-account__workspace {
gap: 16px;
}
.broker-account__workspace {
grid-template-columns: minmax(0, 1fr);
}