88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
import { ForbiddenException, NotFoundException } from '@nestjs/common';
|
|
import { TeamRolesEnum } from '../team-roles/team-roles.enum';
|
|
import { CashboxExportService } from './cashbox-export.service';
|
|
|
|
describe('CashboxExportService', () => {
|
|
const teamRepository = { findOne: jest.fn() };
|
|
const access = { assertAtLeast: jest.fn() };
|
|
let service: CashboxExportService;
|
|
let callOrder: string[];
|
|
|
|
const team = {
|
|
id: 5,
|
|
name: 'Team A',
|
|
alias: 'team-a',
|
|
transactions: [
|
|
{ date: '2026-08-05T00:00:00.000Z', amount: 10, note: 'Sponsoring', type: { name: 'credit' } },
|
|
],
|
|
players: [],
|
|
};
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
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);
|
|
});
|
|
|
|
it('checks permission before loading data', async () => {
|
|
await service.exportForUser(5, 42, '2026-08-01', '2026-08-31', 'csv');
|
|
|
|
expect(access.assertAtLeast).toHaveBeenCalledWith(
|
|
42,
|
|
5,
|
|
'transaction_create_min_role',
|
|
TeamRolesEnum.scnd_treasurer,
|
|
);
|
|
});
|
|
|
|
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 () => {
|
|
teamRepository.findOne.mockResolvedValueOnce(null);
|
|
|
|
await expect(
|
|
service.exportForUser(999, 42, '2026-08-01', '2026-08-31', 'csv'),
|
|
).rejects.toBeInstanceOf(NotFoundException);
|
|
});
|
|
|
|
it('builds a CSV buffer with the correct content type and filename', async () => {
|
|
const result = await service.exportForUser(5, 42, '2026-08-01', '2026-08-31', 'csv');
|
|
|
|
expect(result.contentType).toBe('text/csv; charset=utf-8');
|
|
expect(result.filename).toBe('kassenbuch_team-a_2026-08-01_2026-08-31.csv');
|
|
expect(result.buffer.toString('utf-8')).toContain('Sponsoring');
|
|
});
|
|
|
|
it('builds a PDF buffer with the correct content type and filename', async () => {
|
|
const result = await service.exportForUser(5, 42, '2026-08-01', '2026-08-31', 'pdf');
|
|
|
|
expect(result.contentType).toBe('application/pdf');
|
|
expect(result.filename).toBe('kassenbuch_team-a_2026-08-01_2026-08-31.pdf');
|
|
expect(result.buffer.subarray(0, 5).toString('utf-8')).toBe('%PDF-');
|
|
});
|
|
});
|