90 lines
3.4 KiB
TypeScript
90 lines
3.4 KiB
TypeScript
import { ROLES_KEY } from '../auth/decorators/roles.decorator';
|
|
import { ApiResponse } from '../../common/dto/api-response.dto';
|
|
import { TBankController } from './tbank.controller';
|
|
import { BrokerAccountsService } from './services/broker-accounts.service';
|
|
import { BrokerEventsService } from './services/broker-events.service';
|
|
import { BrokerOperationSyncService } from './services/broker-operation-sync.service';
|
|
import { BrokerOperationsService } from './services/broker-operations.service';
|
|
import { BrokerPortfolioService } from './services/broker-portfolio.service';
|
|
|
|
describe('TBankController', () => {
|
|
const accounts = { findAll: vi.fn() } as unknown as BrokerAccountsService;
|
|
const portfolio = { getPortfolio: vi.fn() } as unknown as BrokerPortfolioService;
|
|
const events = { getEvents: vi.fn() } as unknown as BrokerEventsService;
|
|
const operations = { getOperations: vi.fn() } as unknown as BrokerOperationsService;
|
|
const sync = { syncAccount: vi.fn() } as unknown as BrokerOperationSyncService;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('allows authenticated users to access broker endpoints', () => {
|
|
expect(Reflect.getMetadata(ROLES_KEY, TBankController)).toEqual(['user']);
|
|
});
|
|
|
|
it('returns accounts in a single API envelope', async () => {
|
|
vi.mocked(accounts.findAll).mockResolvedValueOnce({
|
|
data: [
|
|
{
|
|
id: 'acc-1',
|
|
type: 'brokerage',
|
|
name: 'Broker',
|
|
status: 'ACCOUNT_STATUS_OPEN',
|
|
openedAt: null,
|
|
accessLevel: null,
|
|
},
|
|
],
|
|
meta: { fromCache: true, cachedAt: '2026-06-17T00:00:00.000Z' },
|
|
});
|
|
|
|
const controller = new TBankController(accounts, portfolio, events, operations, sync);
|
|
const response = await controller.getAccounts();
|
|
|
|
expect(response).toBeInstanceOf(ApiResponse);
|
|
expect(response.data).toHaveLength(1);
|
|
expect(response.meta).toEqual({ fromCache: true, cachedAt: '2026-06-17T00:00:00.000Z' });
|
|
});
|
|
|
|
it('exposes a sync trigger for durable operation history', async () => {
|
|
vi.mocked(sync.syncAccount).mockResolvedValueOnce({ upserted: 2 });
|
|
|
|
const controller = new TBankController(accounts, portfolio, events, operations, sync);
|
|
const response = await controller.syncOperations('acc-1', {
|
|
from: '2026-06-01T00:00:00.000Z',
|
|
to: '2026-06-17T00:00:00.000Z',
|
|
});
|
|
|
|
expect(sync.syncAccount).toHaveBeenCalledWith('acc-1', {
|
|
from: '2026-06-01T00:00:00.000Z',
|
|
to: '2026-06-17T00:00:00.000Z',
|
|
});
|
|
expect(response.data).toEqual({ upserted: 2 });
|
|
});
|
|
|
|
it('forwards events query and wraps response', async () => {
|
|
const eventsData = {
|
|
items: [],
|
|
summary: {
|
|
eventCount: 0,
|
|
nearestEventDate: null,
|
|
totalEstimatedCashflow: 0,
|
|
dividendsTotal: 0,
|
|
couponsTotal: 0,
|
|
principalRepaymentTotal: 0,
|
|
},
|
|
asOf: '2026-06-22T00:00:00.000Z',
|
|
};
|
|
vi.mocked(events.getEvents).mockResolvedValueOnce({
|
|
data: eventsData,
|
|
meta: { fromCache: false, cachedAt: '2026-06-22T00:00:00.000Z' },
|
|
});
|
|
|
|
const controller = new TBankController(accounts, portfolio, events, operations, sync);
|
|
const response = await controller.getEvents('acc-1', { from: '2026-06-22', to: '2026-07-29' });
|
|
|
|
expect(events.getEvents).toHaveBeenCalledWith('acc-1', '2026-06-22', '2026-07-29');
|
|
expect(response).toBeInstanceOf(ApiResponse);
|
|
expect(response.data).toEqual(eventsData);
|
|
});
|
|
});
|