codex/broker-operations-ui #18
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user