Files
teamwallet/myteamwallet_backend/src/cashbox-export/cashbox-export.service.spec.ts

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-');
});
});