diff --git a/test/all-accounts.e2e-spec.ts b/test/all-accounts.e2e-spec.ts index a238662..c94be41 100644 --- a/test/all-accounts.e2e-spec.ts +++ b/test/all-accounts.e2e-spec.ts @@ -9,6 +9,7 @@ import { AppModule } from '../src/app.module'; import { TbankTokenService } from '../src/integrations/tbank/tbank-token.service'; import { TbankClient } from '../src/integrations/tbank/tbank.client'; import { configureApp } from '../src/main'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; describe('All accounts HTTP boundary', () => { @@ -31,6 +32,8 @@ describe('All accounts HTTP boundary', () => { const module = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(TbankClient) .useValue(upstream) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 0193285..9083f05 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -10,6 +10,7 @@ import { AppModule } from '../src/app.module'; import { loggingOptions } from '../src/common/logging/logging.module'; import { configureApp } from '../src/main'; import { AuthService } from '../src/modules/auth/application/auth.service'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; type Authentication = { accessToken: string; user: { email: string } }; @@ -33,7 +34,10 @@ describe('Authentication (e2e)', () => { }, assignResponse: true, }), - }).compile(); + }) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) + .compile(); app = moduleFixture.createNestApplication(); configureApp(app); diff --git a/test/bank-cards.e2e-spec.ts b/test/bank-cards.e2e-spec.ts index 97effb8..11d74e6 100644 --- a/test/bank-cards.e2e-spec.ts +++ b/test/bank-cards.e2e-spec.ts @@ -16,6 +16,7 @@ import { BankSummaryDto, ExpenseCategoryDto, } from '../src/modules/banking/bank-cards/presentation/bank-card.dto'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; jest.setTimeout(60000); @@ -77,7 +78,10 @@ describe('Manual bank cards configured HTTP and real SQLite', () => { const start = async () => { const module = await Test.createTestingModule({ imports: [AppModule], - }).compile(); + }) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) + .compile(); app = module.createNestApplication(); configureApp(app); await app.listen(0, '127.0.0.1'); @@ -369,6 +373,8 @@ describe('Manual bank cards configured HTTP and real SQLite', () => { expect((await getCard(own.id)).balance.value).toBe('1000'); }); it('renames default category without role loss; duplicates and stale rename conflict', async () => { + // Defaults are seeded by the first write of the user; this case must not depend on earlier cases. + await createCard(); const category = (await categories()).find((c) => c.isDefault); assert.ok(category); await auth('patch', '/categories/' + category.id) @@ -725,11 +731,19 @@ describe('Manual bank cards configured HTTP and real SQLite', () => { expect(await getCard(card.id)).toEqual(before); expect((await getOp(refund.id)).originalExpenseId).toBe(purchase.id); await auth('post', '/operations').send(deletedBody).expect(410); + // The rename is this case's own prerequisite, not an effect of an earlier case. + const defaultCategory = (await categories()).find((c) => c.isDefault); + assert.ok(defaultCategory); + await auth('patch', '/categories/' + defaultCategory.id) + .send({ version: defaultCategory.version, name: 'Остальное' }) + .expect(200); expect((await categories()).find((c) => c.isDefault)?.name).toBe( 'Остальное', ); }); it('enforces actual FK and unique constraints', async () => { + // Seeds the owner's default categories so the unique-name check has a real row to collide with. + await createCard(); await expect( db.expenseCategory.create({ data: { diff --git a/test/bonds.e2e-spec.ts b/test/bonds.e2e-spec.ts index 8e53c35..0b464d8 100644 --- a/test/bonds.e2e-spec.ts +++ b/test/bonds.e2e-spec.ts @@ -15,6 +15,7 @@ import { configureApp } from '../src/main'; import { BondCatalogService } from '../src/modules/investments/instruments/bonds/application/bond-catalog.service'; import { BondIncomeService } from '../src/modules/investments/instruments/bonds/application/bond-income.service'; import { BondMarketService } from '../src/modules/investments/instruments/bonds/application/bond-market.service'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; const uid = 'e6123145-9665-43e0-8413-cd61b8aa9b13'; describe('Bond HTTP contract', () => { @@ -38,6 +39,8 @@ describe('Bond HTTP contract', () => { .useValue(bonds) .overrideProvider(BondIncomeService) .useValue(bonds) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/stocks.e2e-spec.ts b/test/stocks.e2e-spec.ts index 4e05cf5..abf3fe7 100644 --- a/test/stocks.e2e-spec.ts +++ b/test/stocks.e2e-spec.ts @@ -16,6 +16,7 @@ import { StockCatalogService } from '../src/modules/investments/instruments/stoc import { StockIncomeService } from '../src/modules/investments/instruments/stocks/application/stock-income.service'; import { StockMarketService } from '../src/modules/investments/instruments/stocks/application/stock-market.service'; import { StockScreenerService } from '../src/modules/investments/instruments/stocks/application/stock-screener.service'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; const uid = 'e6123145-9665-43e0-8413-cd61b8aa9b13'; describe('Stock HTTP contract', () => { @@ -41,6 +42,8 @@ describe('Stock HTTP contract', () => { .useValue(stocks) .overrideProvider(StockScreenerService) .useValue(screener) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/tbank-connection.e2e-spec.ts b/test/tbank-connection.e2e-spec.ts index f85298d..b06d5bc 100644 --- a/test/tbank-connection.e2e-spec.ts +++ b/test/tbank-connection.e2e-spec.ts @@ -10,6 +10,7 @@ import { TbankAccessService } from '../src/integrations/tbank/tbank-access.servi import { TbankTokenService } from '../src/integrations/tbank/tbank-token.service'; import { TbankClient } from '../src/integrations/tbank/tbank.client'; import { configureApp } from '../src/main'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; describe('Persistent T-Bank connection boundary (SQLite/HTTP)', () => { @@ -31,6 +32,8 @@ describe('Persistent T-Bank connection boundary (SQLite/HTTP)', () => { const module = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(TbankClient) .useValue(upstream) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/tbank-income-local.e2e-spec.ts b/test/tbank-income-local.e2e-spec.ts index 2e16feb..7abdab1 100644 --- a/test/tbank-income-local.e2e-spec.ts +++ b/test/tbank-income-local.e2e-spec.ts @@ -15,6 +15,7 @@ import { } from '../src/modules/investments/income/income-analytics.dto'; import { moscowDate } from '../src/modules/investments/investment-calendar'; import { BrokerageOperationsRepository } from '../src/modules/investments/operations/infrastructure/brokerage-operations.repository'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; // Financial proof uses real persisted rows/coverage and the configured HTTP boundary. @@ -59,6 +60,8 @@ describe('local income completeness and exact money (SQLite)', () => { const module = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(TbankClient) .useValue(upstream) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/tbank-ledger-local.e2e-spec.ts b/test/tbank-ledger-local.e2e-spec.ts index 58725dc..04813bd 100644 --- a/test/tbank-ledger-local.e2e-spec.ts +++ b/test/tbank-ledger-local.e2e-spec.ts @@ -15,6 +15,7 @@ import { TbankClient } from '../src/integrations/tbank/tbank.client'; import { configureApp } from '../src/main'; import { BrokerageOperationsRepository } from '../src/modules/investments/operations/infrastructure/brokerage-operations.repository'; import { BrokerageOperationsResourceDto } from '../src/modules/investments/operations/presentation/brokerage-operation.dto'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; const uid = '11111111-1111-4111-8111-111111111111'; @@ -45,6 +46,8 @@ describe('persistent ledger HTTP and cursor (SQLite)', () => { const module = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(TbankClient) .useValue(upstream) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/tbank-local-reads.e2e-spec.ts b/test/tbank-local-reads.e2e-spec.ts index a90401a..81f3b94 100644 --- a/test/tbank-local-reads.e2e-spec.ts +++ b/test/tbank-local-reads.e2e-spec.ts @@ -17,6 +17,7 @@ import { configureApp } from '../src/main'; import { BrokerageAccountsResourceDto } from '../src/modules/investments/brokerage-accounts/brokerage-account.dto'; import { PortfolioService } from '../src/modules/investments/portfolio/application/portfolio.service'; import { PortfolioResourceDto } from '../src/modules/investments/portfolio/presentation/portfolio.dto'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; function deferred() { @@ -101,6 +102,8 @@ describe('local accounts and portfolio HTTP (SQLite)', () => { const module = await Test.createTestingModule({ imports: [AppModule] }) .overrideProvider(TbankClient) .useValue(upstream) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); configureApp(app); diff --git a/test/tbank-read-baseline.e2e-spec.ts b/test/tbank-read-baseline.e2e-spec.ts index 24f76ed..66df523 100644 --- a/test/tbank-read-baseline.e2e-spec.ts +++ b/test/tbank-read-baseline.e2e-spec.ts @@ -21,6 +21,7 @@ import { TbankOperationsByCursorRequest, } from '../src/integrations/tbank/tbank.client'; import { configureApp } from '../src/main'; +import { TbankHourlyScheduler } from '../src/modules/investments/tbank-sync/tbank-hourly.scheduler'; import { PrismaService } from '../src/prisma/prisma.service'; const evidenceDirectory = mkdtempSync(join(tmpdir(), 'wealthledger-read-evidence-')); @@ -215,6 +216,8 @@ describe('T-Bank persisted read budget', () => { }) .overrideProvider(NcrRatingsClient) .useValue({ rating: () => counted('ncrRating', null) }) + .overrideProvider(TbankHourlyScheduler) + .useValue({ tick: jest.fn() }) .compile(); app = module.createNestApplication(); app.use((_req: Request, res: Response, next: NextFunction) => {