test(frontend): update broker tests for positions hook and removal from portfolio

This commit is contained in:
Sergey Krylov 2026-06-17 14:50:35 +03:00
parent e25daa931a
commit 5ccd421259

View File

@ -1,5 +1,5 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { render, screen } from '@testing-library/react'; import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import { type ReactElement } from 'react'; import { type ReactElement } from 'react';
import { MemoryRouter, Route, Routes } from 'react-router-dom'; import { MemoryRouter, Route, Routes } from 'react-router-dom';
@ -7,6 +7,7 @@ import { describe, expect, it, vi } from 'vitest';
import * as accountHook from '../../hooks/useBrokerAccounts'; import * as accountHook from '../../hooks/useBrokerAccounts';
import * as operationsHook from '../../hooks/useBrokerOperations'; import * as operationsHook from '../../hooks/useBrokerOperations';
import * as portfolioHook from '../../hooks/useBrokerPortfolio'; import * as portfolioHook from '../../hooks/useBrokerPortfolio';
import * as positionsHook from '../../hooks/useBrokerPositions';
import { BrokerAccountDetailPage } from './BrokerAccountDetailPage'; import { BrokerAccountDetailPage } from './BrokerAccountDetailPage';
import { BrokerAccountsPage } from './BrokerAccountsPage'; import { BrokerAccountsPage } from './BrokerAccountsPage';
@ -66,24 +67,6 @@ describe('Broker pages', () => {
yields: { expectedPercent: 5, daily: null, dailyPercent: null }, yields: { expectedPercent: 5, daily: null, dailyPercent: null },
cash: [{ currency: 'RUB', units: '100', nano: 0, value: 100 }], cash: [{ currency: 'RUB', units: '100', nano: 0, value: 100 }],
blockedCash: [], blockedCash: [],
positions: [
{
figi: null,
instrumentUid: 'uid-1',
positionUid: null,
ticker: 'SBER',
classCode: 'TQBR',
instrumentType: 'share',
name: 'Sberbank',
quantity: 10,
blockedLots: null,
currentPrice: null,
currentValue: { currency: 'RUB', units: '1000', nano: 0, value: 1000 },
averagePositionPrice: null,
expectedYieldPercent: null,
dailyYield: null,
},
],
asOf: '2026-06-16T00:00:00.000Z', asOf: '2026-06-16T00:00:00.000Z',
}, },
isLoading: false, isLoading: false,
@ -124,6 +107,34 @@ describe('Broker pages', () => {
isLoading: false, isLoading: false,
error: null, error: null,
} as any); } as any);
vi.spyOn(positionsHook, 'useBrokerPositions').mockReturnValue({
data: {
accountId: 'acc-1',
items: [
{
figi: null,
instrumentUid: 'uid-1',
positionUid: null,
ticker: 'SBER',
classCode: 'TQBR',
instrumentType: 'share',
name: 'Sberbank',
quantity: 10,
blockedLots: null,
currentPrice: null,
currentValue: { currency: 'RUB', units: '1000', nano: 0, value: 1000 },
averagePositionPrice: null,
expectedYieldPercent: null,
dailyYield: null,
},
],
nextCursor: null,
hasNext: false,
asOf: '2026-06-16T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
renderWithClient( renderWithClient(
<Routes> <Routes>
@ -151,7 +162,26 @@ describe('Broker pages', () => {
yields: { expectedPercent: 5, daily: null, dailyPercent: null }, yields: { expectedPercent: 5, daily: null, dailyPercent: null },
cash: [], cash: [],
blockedCash: [], blockedCash: [],
positions: [ asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
vi.spyOn(operationsHook, 'useBrokerOperations').mockReturnValue({
data: {
accountId: 'acc-1',
items: [],
nextCursor: null,
hasNext: false,
asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
vi.spyOn(positionsHook, 'useBrokerPositions').mockReturnValue({
data: {
accountId: 'acc-1',
items: [
{ {
figi: null, figi: null,
instrumentUid: 'share-uid', instrumentUid: 'share-uid',
@ -185,15 +215,6 @@ describe('Broker pages', () => {
dailyYield: null, dailyYield: null,
}, },
], ],
asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
vi.spyOn(operationsHook, 'useBrokerOperations').mockReturnValue({
data: {
accountId: 'acc-1',
items: [],
nextCursor: null, nextCursor: null,
hasNext: false, hasNext: false,
asOf: '2026-06-17T00:00:00.000Z', asOf: '2026-06-17T00:00:00.000Z',
@ -237,7 +258,6 @@ describe('Broker pages', () => {
yields: { expectedPercent: null, daily: null, dailyPercent: null }, yields: { expectedPercent: null, daily: null, dailyPercent: null },
cash: [], cash: [],
blockedCash: [], blockedCash: [],
positions: [],
asOf: '2026-06-17T00:00:00.000Z', asOf: '2026-06-17T00:00:00.000Z',
}, },
isLoading: false, isLoading: false,
@ -301,6 +321,17 @@ describe('Broker pages', () => {
isLoading: false, isLoading: false,
error: null, error: null,
} as any); } as any);
vi.spyOn(positionsHook, 'useBrokerPositions').mockReturnValue({
data: {
accountId: 'acc-1',
items: [],
nextCursor: null,
hasNext: false,
asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
renderWithClient( renderWithClient(
<Routes> <Routes>
@ -334,7 +365,6 @@ describe('Broker pages', () => {
yields: { expectedPercent: null, daily: null, dailyPercent: null }, yields: { expectedPercent: null, daily: null, dailyPercent: null },
cash: [], cash: [],
blockedCash: [], blockedCash: [],
positions: [],
asOf: '2026-06-17T00:00:00.000Z', asOf: '2026-06-17T00:00:00.000Z',
}, },
isLoading: false, isLoading: false,
@ -411,6 +441,17 @@ describe('Broker pages', () => {
error: null, error: null,
}) as any, }) as any,
); );
vi.spyOn(positionsHook, 'useBrokerPositions').mockReturnValue({
data: {
accountId: 'acc-1',
items: [],
nextCursor: null,
hasNext: false,
asOf: '2026-06-17T00:00:00.000Z',
},
isLoading: false,
error: null,
} as any);
renderWithClient( renderWithClient(
<Routes> <Routes>
@ -421,9 +462,11 @@ describe('Broker pages', () => {
expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: undefined }); expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: undefined });
// Find pagination buttons by their text content (← and →) // Scope pagination queries to the operations section (positions section also has pagination now)
const nextButton = screen.getByRole('button', { name: '→' }); const operationsSection = screen.getByRole('heading', { name: 'Операции' }).closest('section')!;
const prevButton = screen.getByRole('button', { name: '←' }); const withinOperations = within(operationsSection);
const nextButton = withinOperations.getByRole('button', { name: '→' });
const prevButton = withinOperations.getByRole('button', { name: '←' });
expect(prevButton).toBeDisabled(); expect(prevButton).toBeDisabled();
expect(nextButton).not.toBeDisabled(); expect(nextButton).not.toBeDisabled();
@ -435,11 +478,11 @@ describe('Broker pages', () => {
}); });
// Page number is shown as just a number (without "Страница" label) // Page number is shown as just a number (without "Страница" label)
expect(screen.getByText('2')).toBeInTheDocument(); expect(withinOperations.getByText('2')).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: '←' })); await user.click(prevButton);
expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: undefined }); expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: undefined });
expect(screen.getByText('1')).toBeInTheDocument(); expect(withinOperations.getByText('1')).toBeInTheDocument();
}); });
}); });