import 'reflect-metadata'; import axios from 'axios'; import { ConfigService } from '@nestjs/config'; import { MoexClientService } from './moex-client.service'; vi.mock('axios', () => ({ default: { create: vi.fn(), }, })); describe('MoexClientService', () => { let service: MoexClientService; let getMock: ReturnType; beforeEach(() => { getMock = vi.fn(); vi.mocked(axios.create).mockReturnValue({ get: getMock } as never); service = new MoexClientService({ get: vi.fn((key: string, fallback?: unknown) => { const values: Record = { 'app.moex.baseUrl': 'https://iss.moex.test/iss', 'app.moex.circuitBreakerThreshold': 5, 'app.moex.circuitBreakerResetSeconds': 30, 'app.moex.rateLimit': 10, }; return values[key] ?? fallback; }), } as unknown as ConfigService); }); it('создаётся с настроенным MOEX client', () => { expect(service).toBeDefined(); expect(axios.create).toHaveBeenCalledWith({ baseURL: 'https://iss.moex.test/iss', timeout: 10000, paramsSerializer: { indexes: null }, }); }); it('нормализует результаты поиска из ISS table format', async () => { getMock.mockResolvedValueOnce({ data: { securities: { columns: [ 'secid', 'isin', 'name', 'shortName', 'latName', 'listLevel', 'issuesize', 'facevalue', 'faceunit', 'issuedate', 'typename', 'group', 'type', 'isqualifiedinvestors', 'morningsession', 'eveningsession', ], data: [ [ 'SBER', 'RU0009029540', 'Сбербанк России ПАО ао', 'Сбербанк', 'Sberbank', '1', '21586948000', '3', 'SUR', '2007-07-20', 'Акция обыкновенная', 'stock_shares', 'common_share', '0', '1', '1', ], ], }, }, }); const results = await service.searchSecurities('SBER'); expect(getMock).toHaveBeenCalledWith('/securities.json', { params: { q: 'SBER', 'iss.meta': 'off' }, }); expect(results).toEqual([ { secid: 'SBER', isin: 'RU0009029540', name: 'Сбербанк России ПАО ао', shortName: 'Сбербанк', latName: 'Sberbank', listLevel: 1, issueSize: 21586948000, faceValue: 3, faceUnit: 'SUR', issueDate: '2007-07-20', typeName: 'Акция обыкновенная', group: 'stock_shares', type: 'common_share', isQualifiedInvestors: false, morningSession: true, eveningSession: true, }, ]); }); it('нормализует market data акции без live MOEX запроса', async () => { getMock.mockResolvedValueOnce({ data: { securities: { columns: ['SECID', 'BOARDID', 'SHORTNAME', 'PREVPRICE'], data: [['SBER', 'TQBR', 'Сбербанк', '320.10']], }, marketdata: { columns: [ 'SECID', 'BOARDID', 'BID', 'OFFER', 'OPEN', 'LOW', 'HIGH', 'LAST', 'LASTCHANGE', 'LASTCHANGEPRCNT', 'VOLTODAY', 'VALTODAY', 'WAPRICE', 'NUMTRADES', 'ISSUECAPITALIZATION', 'TRADINGSTATUS', 'UPDATETIME', ], data: [ [ 'SBER', 'TQBR', '321', '322', '320', '319', '323', '322.35', '1.15', '0.36', '1925163', '620184479', '321.9', '12345', '6958336818320', 'T', '10:30:00', ], ], }, }, }); const data = await service.getShareMarketData('SBER'); expect(getMock).toHaveBeenCalledWith('/engines/stock/markets/shares/securities/SBER.json', { params: { boards: 'TQBR', 'iss.meta': 'off' }, }); expect(data).toMatchObject({ secid: 'SBER', boardid: 'TQBR', shortName: 'Сбербанк', last: 322.35, lastChange: 1.15, lastChangePrcnt: 0.36, volume: 1925163, value: 620184479, issueCapitalization: 6958336818320, tradingStatus: 'T', updateTime: '10:30:00', }); }); });