import { NotFoundException } from '@nestjs/common'; import { CacheService } from '../../cache/cache.service'; import { BrokerAccountsService } from './broker-accounts.service'; import { BrokerOperationsService } from './broker-operations.service'; import { TBankClientService } from './tbank-client.service'; describe('BrokerOperationsService', () => { const accounts = { findById: vi.fn() } as unknown as BrokerAccountsService; const client = { getServiceClient: vi.fn(), callUnary: vi.fn() } as unknown as TBankClientService; const cache = { getOrFetch: vi.fn() } as unknown as CacheService; beforeEach(() => { vi.clearAllMocks(); }); it('throws 404 for excluded or missing account', async () => { vi.mocked(accounts.findById).mockResolvedValue(null); const service = new BrokerOperationsService(accounts, client, cache); await expect(service.getOperations('missing', {})).rejects.toThrow(NotFoundException); }); it('builds cursor request and maps operation page', async () => { vi.mocked(accounts.findById).mockResolvedValue({ id: 'acc-1', type: 'brokerage', name: 'Broker', status: 'ACCOUNT_STATUS_OPEN', openedAt: null, accessLevel: null, }); vi.mocked(cache.getOrFetch).mockImplementation( async (_prefix: string, _parts: string[], fetchFn: () => Promise) => ({ data: await fetchFn(), fromCache: false, cachedAt: null, }), ); vi.mocked(client.getServiceClient).mockReturnValue({ getOperationsByCursor: vi.fn() } as any); vi.mocked(client.callUnary).mockResolvedValue({ hasNext: false, items: [{ cursor: 'c1', brokerAccountId: 'acc-1', type: 'OPERATION_TYPE_BUY' }], }); const service = new BrokerOperationsService(accounts, client, cache); const result = await service.getOperations('acc-1', { from: '2026-01-01T00:00:00.000Z', to: '2026-06-16T00:00:00.000Z', limit: 1000, state: 'OPERATION_STATE_EXECUTED', }); expect(result.data.items[0].category).toBe('trade'); expect(client.callUnary).toHaveBeenCalledWith( 'OperationsService/GetOperationsByCursor', expect.any(Function), expect.objectContaining({ accountId: 'acc-1', limit: 1000, state: 'OPERATION_STATE_EXECUTED', }), ); }); });