test: enforce permission check ordering in CashboxExportService

This commit is contained in:
Bastian Wagner
2026-08-03 21:33:36 +02:00
parent 396dc29cf5
commit 18df224386

View File

@@ -1,4 +1,4 @@
import { NotFoundException } from '@nestjs/common'; import { ForbiddenException, NotFoundException } from '@nestjs/common';
import { TeamRolesEnum } from '../team-roles/team-roles.enum'; import { TeamRolesEnum } from '../team-roles/team-roles.enum';
import { CashboxExportService } from './cashbox-export.service'; import { CashboxExportService } from './cashbox-export.service';
@@ -6,6 +6,7 @@ describe('CashboxExportService', () => {
const teamRepository = { findOne: jest.fn() }; const teamRepository = { findOne: jest.fn() };
const access = { assertAtLeast: jest.fn() }; const access = { assertAtLeast: jest.fn() };
let service: CashboxExportService; let service: CashboxExportService;
let callOrder: string[];
const team = { const team = {
id: 5, id: 5,
@@ -19,7 +20,17 @@ describe('CashboxExportService', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
teamRepository.findOne.mockResolvedValue(team); callOrder = [];
access.assertAtLeast.mockImplementation(async () => {
callOrder.push('assertAtLeast');
});
teamRepository.findOne.mockImplementation(async () => {
callOrder.push('findOne');
return team;
});
service = new CashboxExportService(teamRepository as any, access as any); service = new CashboxExportService(teamRepository as any, access as any);
}); });
@@ -34,8 +45,24 @@ describe('CashboxExportService', () => {
); );
}); });
it('calls assertAtLeast before findOne to enforce permission check ordering', async () => {
await service.exportForUser(5, 42, '2026-08-01', '2026-08-31', 'csv');
expect(callOrder).toEqual(['assertAtLeast', 'findOne']);
});
it('skips team lookup when permission check rejects', async () => {
access.assertAtLeast.mockRejectedValueOnce(new ForbiddenException('Insufficient permissions'));
await expect(
service.exportForUser(5, 42, '2026-08-01', '2026-08-31', 'csv'),
).rejects.toBeInstanceOf(ForbiddenException);
expect(teamRepository.findOne).not.toHaveBeenCalled();
});
it('throws NotFoundException for an unknown team', async () => { it('throws NotFoundException for an unknown team', async () => {
teamRepository.findOne.mockResolvedValue(null); teamRepository.findOne.mockResolvedValueOnce(null);
await expect( await expect(
service.exportForUser(999, 42, '2026-08-01', '2026-08-31', 'csv'), service.exportForUser(999, 42, '2026-08-01', '2026-08-31', 'csv'),