Files
backend/src/modules/investments/investment-resource.mapper.spec.ts
T
ksv741 d698ed9425
Backend verify / commits (pull_request) Successful in 29s
Backend verify / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 9m36s
refactor!: simplify runtime coordination #7
Keep financial ownership, atomic publication and refresh CAS.
Failed refresh leaves cookies untouched; logout still clears them.

Remove full-history candle prefetch and special metadata retries.
Use native Pino request context instead of parallel middleware.

BREAKING CHANGE: remove investment stateVersion, queued sync state,
and tbank-sync status progress/resources. Consumers must observe
resources through sync=observe with the updated frontend contract.
2026-10-03 11:38:08 +03:00

79 lines
2.5 KiB
TypeScript

import { investmentResourceMeta } from './investment-resource.mapper';
describe('investment resource source freshness', () => {
afterEach(() => jest.useRealTimers());
it('uses each required source TTL and oldest successful timestamp', () => {
jest.useFakeTimers().setSystemTime(new Date('2026-09-25T12:00:00Z'));
const membership = investmentResourceMeta({
resourceKey: 'membership',
dataRevision: '1',
availability: 'complete',
fetchedAt: new Date('2026-09-25T11:58:00Z'),
freshForMs: 300_000,
work: null,
});
const input = {
resourceKey: 'portfolio',
dataRevision: '1',
availability: 'complete' as const,
fetchedAt: new Date('2026-09-25T11:59:30Z'),
freshForMs: 60_000,
work: null,
dependencies: [membership],
};
const fresh = investmentResourceMeta(input);
expect(fresh.freshness).toBe('fresh');
expect(fresh.lastSuccessfulAt).toBe('2026-09-25T11:58:00.000Z');
jest.advanceTimersByTime(30_000);
const stale = investmentResourceMeta(input);
expect(stale.freshness).toBe('stale');
expect(stale.lastSuccessfulAt).toBe(fresh.lastSuccessfulAt);
expect(
investmentResourceMeta({
...input,
dependencies: [{ ...membership, freshness: 'unknown' }],
}).freshness,
).toBe('unknown');
});
});
describe('dependent resource lifecycle', () => {
const input = {
resourceKey: 'source',
dataRevision: '1',
availability: 'complete' as const,
fetchedAt: new Date(),
freshForMs: 60_000,
work: null,
};
it('exposes dependency work without losing saved availability or timestamps', () => {
const failed = investmentResourceMeta({
...input,
work: { id: 'failed', state: 'failed', errorCode: 'TBANK_UNAVAILABLE' },
});
const running = investmentResourceMeta({
...input,
work: { id: 'running', state: 'running', errorCode: null },
});
const parent = investmentResourceMeta({
...input,
dependencies: [failed, running],
});
expect(parent.sync).toEqual(running.sync);
expect(parent.availability).toBe('complete');
const terminal = investmentResourceMeta({
...input,
dependencies: [failed],
});
expect(terminal.sync).toEqual(failed.sync);
expect(terminal.lastSuccessfulAt).toBe(parent.lastSuccessfulAt);
expect(
investmentResourceMeta({
...input,
dependencies: [{ ...failed, unavailableReason: 'calendar_boundary' }],
}).sync.state,
).toBe('idle');
});
});