fix: harden auth and cache concurrency
This commit is contained in:
@@ -31,6 +31,8 @@ describe('BrokerageOperationsService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
tbank.getOpenAccounts.mockReset();
|
||||
tbank.getOperationsByCursor.mockReset();
|
||||
prisma.tbankConnection.findUnique.mockResolvedValue({
|
||||
encryptedToken: crypto.encrypt('token'),
|
||||
});
|
||||
@@ -46,6 +48,11 @@ describe('BrokerageOperationsService', () => {
|
||||
(service as unknown as { pages: Map<string, unknown> }).pages.clear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('uses the current UTC year by default and asks only for executed operations', async () => {
|
||||
await service.get('user', 'account', {});
|
||||
|
||||
@@ -134,4 +141,41 @@ describe('BrokerageOperationsService', () => {
|
||||
expect.any(ServiceUnavailableException),
|
||||
);
|
||||
});
|
||||
|
||||
it('reuses one fresh page for equivalent categories within the default end-time bucket', async () => {
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date('2026-08-23T12:00:00.100Z'));
|
||||
|
||||
await service.get('user', 'account', {
|
||||
categories: ['tax', 'income', 'income'],
|
||||
});
|
||||
jest.advanceTimersByTime(500);
|
||||
await service.get('user', 'account', { categories: ['income', 'tax'] });
|
||||
|
||||
expect(tbank.getOperationsByCursor).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not let a cached page bypass account ownership checks', async () => {
|
||||
const query = { from: '2025-01-01', to: '2025-01-31' };
|
||||
await service.get('user', 'account', query);
|
||||
tbank.getOpenAccounts.mockResolvedValueOnce([]);
|
||||
|
||||
await expect(service.get('user', 'account', query)).rejects.toEqual(
|
||||
expect.any(NotFoundException),
|
||||
);
|
||||
expect(tbank.getOperationsByCursor).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('evicts the least recently used ledger page after one hundred entries', async () => {
|
||||
for (let index = 0; index < 100; index += 1)
|
||||
await service.get('user', 'account', { cursor: String(index) });
|
||||
|
||||
await service.get('user', 'account', { cursor: '0' });
|
||||
await service.get('user', 'account', { cursor: '100' });
|
||||
await service.get('user', 'account', { cursor: '1' });
|
||||
|
||||
const pages = (service as unknown as { pages: { size: number } }).pages;
|
||||
expect(pages.size).toBe(100);
|
||||
expect(tbank.getOperationsByCursor).toHaveBeenCalledTimes(102);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user