187 lines
4.8 KiB
TypeScript
187 lines
4.8 KiB
TypeScript
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<typeof vi.fn>;
|
||
|
||
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<string, unknown> = {
|
||
'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',
|
||
});
|
||
});
|
||
});
|