import { Test, TestingModule } from '@nestjs/testing'; import { ScreenerService } from './screener.service'; import { MoexClientService } from '../moex-client/moex-client.service'; import { CacheService } from '../cache/cache.service'; import { ScreenerType } from './dto/screener-query.dto'; describe('ScreenerService', () => { let service: ScreenerService; let cache: CacheService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ ScreenerService, { provide: MoexClientService, useValue: { getShareMarketDataBatch: vi.fn(), getBondPositionDataBatch: vi.fn(), }, }, { provide: CacheService, useValue: { getOrFetch: vi.fn(), }, }, ], }).compile(); service = module.get(ScreenerService); cache = module.get(CacheService); }); it('should be defined', () => { expect(service).toBeDefined(); }); describe('screen', () => { it('should filter and sort shares', async () => { const mockShares = [ { secid: 'SBER', shortName: 'Sberbank', price: 250, volume: 1000000, changePercent: 1, type: 'share', }, { secid: 'GAZP', shortName: 'Gazprom', price: 150, volume: 500000, changePercent: -1, type: 'share', }, { secid: 'LKOH', shortName: 'Lukoil', price: 5000, volume: 100000, changePercent: 0.5, type: 'share', }, ]; vi.mocked(cache.getOrFetch).mockImplementation(async () => ({ data: mockShares, fromCache: false, cachedAt: null, })); const result = await service.screen({ type: ScreenerType.SHARE, priceMax: 300, sortOrder: 'desc', sortBy: 'price', }); expect(result.items).toHaveLength(2); expect(result.items[0].secid).toBe('SBER'); // 250 expect(result.items[1].secid).toBe('GAZP'); // 150 expect(result.total).toBe(2); }); it('should paginate results', async () => { const mockShares = Array.from({ length: 50 }, (_, i) => ({ secid: `TICKER${i}`, last: i, })); vi.mocked(cache.getOrFetch).mockImplementation(async () => ({ data: mockShares, fromCache: false, cachedAt: null, })); const result = await service.screen({ type: ScreenerType.SHARE, page: 2, pageSize: 10, }); expect(result.items).toHaveLength(10); expect(result.page).toBe(2); expect(result.totalPages).toBe(5); }); }); });