import { Test, TestingModule } from '@nestjs/testing'; import { CandlesService } from './candles.service'; import { MoexCandlesClient } from '../moex-client/moex-candles.client'; import { CacheService } from '../cache/cache.service'; import { CandleInterval } from './dto/candles-query.dto'; describe('CandlesService', () => { let service: CandlesService; let moexCandles: Pick; let cache: Pick; beforeEach(async () => { moexCandles = { getCandles: vi.fn(), }; cache = { getOrFetch: vi.fn(async (_keyPrefix, _keyParts, fetchFn) => ({ data: await fetchFn(), fromCache: false, cachedAt: '2026-06-15T00:00:00.000Z', })), }; const module: TestingModule = await Test.createTestingModule({ providers: [ CandlesService, { provide: MoexCandlesClient, useValue: moexCandles }, { provide: CacheService, useValue: cache }, ], }).compile(); service = module.get(CandlesService); }); it('uses MOEX interval 24 for daily share candles and maps output envelope', async () => { vi.mocked(moexCandles.getCandles).mockResolvedValue([ { open: 320, high: 325, low: 318, close: 323, volume: 1500000, value: 480000000, begin: '2026-05-01 00:00:00', end: '2026-05-01 23:59:59', }, ]); const result = await service.getCandles( 'shares', 'SBER', CandleInterval.DAY, '2026-05-01', '2026-06-01', ); expect(cache.getOrFetch).toHaveBeenCalledWith( 'candles', ['shares', 'SBER', '24', '2026-05-01', '2026-06-01'], expect.any(Function), 'candlesTtl', ); expect(moexCandles.getCandles).toHaveBeenCalledWith( 'stock', 'shares', 'SBER', 24, '2026-05-01', '2026-06-01', ); expect(result).toEqual({ data: [ { open: 320, high: 325, low: 318, close: 323, volume: 1500000, value: 480000000, begin: '2026-05-01 00:00:00', end: '2026-05-01 23:59:59', }, ], fromCache: false, cachedAt: '2026-06-15T00:00:00.000Z', }); }); it('uses MOEX interval 60 for hourly bond candles without live MOEX dependency', async () => { vi.mocked(moexCandles.getCandles).mockResolvedValue([]); await service.getCandles( 'bonds', 'SU26238RMFS5', CandleInterval.HOUR, '2026-05-01', '2026-06-01', ); expect(cache.getOrFetch).toHaveBeenCalledWith( 'candles', ['bonds', 'SU26238RMFS5', '60', '2026-05-01', '2026-06-01'], expect.any(Function), 'candlesTtl', ); expect(moexCandles.getCandles).toHaveBeenCalledWith( 'stock', 'bonds', 'SU26238RMFS5', 60, '2026-05-01', '2026-06-01', ); }); });