import { ForbiddenException, NotFoundException } from '@nestjs/common'; import { SuppressionService } from './suppression.service'; import { RoleType } from 'src/entities/users.entity'; describe('SuppressionService (#159)', () => { const dataSource = { transaction: jest.fn(async (cb: (m: unknown) => Promise) => cb({ delete: jest.fn(), query: jest.fn(), }), ), }; const usersRepository = { findOne: jest.fn(), delete: jest.fn(), count: jest.fn(), }; const parentsRepository = { findOne: jest.fn(), find: jest.fn(), query: jest.fn(), }; const amRepository = { findOne: jest.fn(), }; const childrenRepository = { findOne: jest.fn(), delete: jest.fn(), save: jest.fn(), }; const parentsChildrenRepository = { find: jest.fn(), }; const amChildrenRepository = { find: jest.fn(), save: jest.fn(), count: jest.fn(), }; let service: SuppressionService; const staff = { id: 'staff-1', role: RoleType.GESTIONNAIRE, } as never; const admin = { id: 'admin-1', role: RoleType.ADMINISTRATEUR, } as never; const superAdmin = { id: 'sa-1', role: RoleType.SUPER_ADMIN, } as never; beforeEach(() => { jest.clearAllMocks(); service = new SuppressionService( dataSource as never, usersRepository as never, parentsRepository as never, amRepository as never, childrenRepository as never, parentsChildrenRepository as never, amChildrenRepository as never, ); }); it('refuse self-delete', async () => { usersRepository.findOne.mockResolvedValue({ id: 'admin-1', role: RoleType.ADMINISTRATEUR, }); await expect(service.deleteUser('admin-1', admin)).rejects.toBeInstanceOf( ForbiddenException, ); }); it('refuse gestionnaire deleting another gestionnaire', async () => { usersRepository.findOne.mockResolvedValue({ id: 'g2', role: RoleType.GESTIONNAIRE, }); await expect(service.deleteUser('g2', staff)).rejects.toBeInstanceOf( ForbiddenException, ); }); it('dernier admin : refus si pas super_admin', async () => { usersRepository.findOne.mockResolvedValue({ id: 'admin-2', role: RoleType.ADMINISTRATEUR, }); usersRepository.count.mockResolvedValue(1); await expect(service.deleteUser('admin-2', admin)).rejects.toBeInstanceOf( ForbiddenException, ); }); it('dernier admin : OK pour super_admin', async () => { usersRepository.findOne.mockResolvedValue({ id: 'admin-2', role: RoleType.ADMINISTRATEUR, }); usersRepository.count.mockResolvedValue(1); usersRepository.delete.mockResolvedValue({ affected: 1 }); const res = await service.deleteUser('admin-2', superAdmin); expect(res.deleted_user_ids).toEqual(['admin-2']); }); it('delete AM : clos placements, pas d’enfants deleted', async () => { usersRepository.findOne.mockResolvedValue({ id: 'am-1', role: RoleType.ASSISTANTE_MATERNELLE, }); amRepository.findOne.mockResolvedValue({ user_id: 'am-1', numero_dossier: '2026-000015', }); amChildrenRepository.find.mockResolvedValue([ { amId: 'am-1', enfantId: 'e1', child: { id: 'e1', status: 'garde' }, }, ]); amChildrenRepository.count.mockResolvedValue(0); amChildrenRepository.save.mockImplementation(async (x) => x); childrenRepository.save.mockResolvedValue({}); usersRepository.delete.mockResolvedValue({ affected: 1 }); const res = await service.deleteUser('am-1', staff); expect(res.deleted_enfant_ids).toEqual([]); expect(res.deleted_user_ids).toEqual(['am-1']); expect(res.type).toBe('assistante_maternelle'); }); it('delete dossier famille introuvable', async () => { parentsRepository.findOne.mockResolvedValue(null); amRepository.findOne.mockResolvedValue(null); await expect( service.deleteDossier('2026-999999', staff), ).rejects.toBeInstanceOf(NotFoundException); }); it('co-parent : delete user seul', async () => { usersRepository.findOne.mockResolvedValue({ id: 'p2', role: RoleType.PARENT, }); parentsRepository.findOne.mockResolvedValue({ user_id: 'p2', numero_dossier: '2026-000010', co_parent: { id: 'p1' }, }); parentsRepository.query.mockResolvedValue([ { id: 'p1' }, { id: 'p2' }, ]); dataSource.transaction.mockImplementation(async (cb) => cb({ delete: jest.fn(), query: jest.fn(), }), ); const res = await service.deleteUser('p2', staff); expect(res.deleted_enfant_ids).toEqual([]); expect(res.deleted_user_ids).toEqual(['p2']); expect(res.message).toMatch(/co-parent/i); }); });