feat: add hourly portfolio sync history
This commit is contained in:
@@ -3,16 +3,21 @@ import type { Server } from 'node:http';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { setTimeout as delay } from 'node:timers/promises';
|
||||
import request from 'supertest';
|
||||
|
||||
import { AppModule } from '../src/app.module';
|
||||
import { TbankMembershipService } from '../src/integrations/tbank/tbank-membership.service';
|
||||
import { TbankClient } from '../src/integrations/tbank/tbank.client';
|
||||
import { configureApp } from '../src/main';
|
||||
import { PortfolioService } from '../src/modules/investments/portfolio/application/portfolio.service';
|
||||
import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler';
|
||||
import { PrismaService } from '../src/prisma/prisma.service';
|
||||
|
||||
describe('Portfolio structure HTTP contract', () => {
|
||||
let app: INestApplication<Server>;
|
||||
let prisma: PrismaService;
|
||||
let membership: TbankMembershipService;
|
||||
let portfolios: PortfolioService;
|
||||
const tbank = {
|
||||
validateToken: jest.fn().mockResolvedValue([
|
||||
{ id: 'a', name: 'A', type: 'ACCOUNT_TYPE_TINKOFF' },
|
||||
@@ -22,6 +27,10 @@ describe('Portfolio structure HTTP contract', () => {
|
||||
getPositions: jest.fn(),
|
||||
getInstrumentByFigi: jest.fn().mockResolvedValue(null),
|
||||
getInstrumentByUid: jest.fn().mockResolvedValue(null),
|
||||
getOpenAccounts: jest.fn().mockResolvedValue([
|
||||
{ id: 'a', name: 'A', type: 'ACCOUNT_TYPE_TINKOFF' },
|
||||
{ id: 'b', name: 'B', type: 'ACCOUNT_TYPE_TINKOFF' },
|
||||
]),
|
||||
};
|
||||
const token = new JwtService().sign(
|
||||
{ sub: 'structure-user', type: 'access' },
|
||||
@@ -32,11 +41,16 @@ describe('Portfolio structure HTTP contract', () => {
|
||||
const module = await Test.createTestingModule({ imports: [AppModule] })
|
||||
.overrideProvider(TbankClient)
|
||||
.useValue(tbank)
|
||||
.overrideProvider(TbankHourlyScheduler)
|
||||
.useValue({ connected: jest.fn().mockResolvedValue(undefined) })
|
||||
.compile();
|
||||
app = module.createNestApplication();
|
||||
configureApp(app);
|
||||
await app.init();
|
||||
await app.get(PrismaService).user.create({
|
||||
prisma = app.get(PrismaService);
|
||||
membership = app.get(TbankMembershipService);
|
||||
portfolios = app.get(PortfolioService);
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
id: 'structure-user',
|
||||
email: 'structure@example.invalid',
|
||||
@@ -65,21 +79,25 @@ describe('Portfolio structure HTTP contract', () => {
|
||||
});
|
||||
afterAll(() => app.close());
|
||||
async function load(id: string) {
|
||||
await request(app.getHttpServer())
|
||||
.get(`/api/v1/brokerage-accounts/${id}/portfolio`)
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200);
|
||||
for (let index = 0; index < 200; index += 1) {
|
||||
if (
|
||||
!(await app
|
||||
.get(PrismaService)
|
||||
.tbankSyncWork.count({ where: { state: 'running' } }))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
await delay(5);
|
||||
const connection = await prisma.tbankConnection.findUniqueOrThrow({
|
||||
where: { userId: 'structure-user' },
|
||||
});
|
||||
const member = await membership.request(
|
||||
'structure-user',
|
||||
connection.revision,
|
||||
true,
|
||||
);
|
||||
if (member) await member.done;
|
||||
const accountIds = id === 'all' ? ['a', 'b'] : [id];
|
||||
for (const accountId of accountIds) {
|
||||
const work = await portfolios.request(
|
||||
'structure-user',
|
||||
connection.revision,
|
||||
accountId,
|
||||
true,
|
||||
);
|
||||
if (work) await work.done;
|
||||
}
|
||||
throw new Error('Portfolio did not settle');
|
||||
}
|
||||
|
||||
it.each(['a', 'all'])(
|
||||
|
||||
Reference in New Issue
Block a user