feat(#112): reprise après refus — dossier complet GET/PATCH

- GET reprise-dossier : parents[], enfants[], texte_motivation (famille) ou fiche AM (#119)
- PATCH reprise-resoumettre : co-parent, enfants (update par id), motivation, fiche AM
- Resoumission famille : tous les parents en en_attente + invalidation token groupée
- DTOs étendus + est_multiple sur enfants dossier famille
- Tests unitaires getRepriseDossier parent/AM

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-16 16:39:53 +02:00
co-authored by Cursor
parent 671da71752
commit d70577b1c3
9 changed files with 655 additions and 17 deletions
+85 -2
View File
@@ -5,11 +5,13 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { ConfigService } from '@nestjs/config';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { ParentsService } from '../parents/parents.service';
import { DossiersService } from '../dossiers/dossiers.service';
import { AppConfigService } from 'src/modules/config/config.service';
import { MailService } from 'src/modules/mail/mail.service';
import { NumeroDossierService } from 'src/modules/numero-dossier/numero-dossier.service';
import { Parents } from 'src/entities/parents.entity';
import { Users } from 'src/entities/users.entity';
import { Users, RoleType, StatutUtilisateurType } from 'src/entities/users.entity';
import { Children } from 'src/entities/children.entity';
import { AssistanteMaternelle } from 'src/entities/assistantes_maternelles.entity';
@@ -19,6 +21,20 @@ describe('AuthService (#118 create-password API)', () => {
findOne: jest.fn(),
createQueryBuilder: jest.fn(),
update: jest.fn(),
manager: { transaction: jest.fn() },
};
const userServiceMock = {
findByTokenReprise: jest.fn(),
};
const parentsServiceMock = {
getDossierFamilleByNumero: jest.fn(),
getFamilyUserIds: jest.fn(),
};
const dossiersServiceMock = {
getDossierByNumero: jest.fn(),
};
const mailServiceMock = {
@@ -45,7 +61,9 @@ describe('AuthService (#118 create-password API)', () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AuthService,
{ provide: UserService, useValue: {} },
{ provide: UserService, useValue: userServiceMock },
{ provide: ParentsService, useValue: parentsServiceMock },
{ provide: DossiersService, useValue: dossiersServiceMock },
{ provide: JwtService, useValue: {} },
{ provide: ConfigService, useValue: { get: jest.fn() } },
{ provide: AppConfigService, useValue: appConfigMock },
@@ -136,4 +154,69 @@ describe('AuthService (#118 create-password API)', () => {
expect(exec).toHaveBeenCalled();
});
});
describe('Reprise après refus (#112)', () => {
const token = '11111111-1111-1111-1111-111111111111';
it('getRepriseDossier throws when token invalid', async () => {
userServiceMock.findByTokenReprise.mockResolvedValue(null);
await expect(service.getRepriseDossier(token)).rejects.toThrow(NotFoundException);
});
it('getRepriseDossier returns famille complète pour parent', async () => {
userServiceMock.findByTokenReprise.mockResolvedValue({
id: 'p1',
email: 'claire@test.fr',
prenom: 'Claire',
nom: 'MARTIN',
role: RoleType.PARENT,
numero_dossier: '2026-000021',
statut: StatutUtilisateurType.REFUSE,
});
parentsServiceMock.getDossierFamilleByNumero.mockResolvedValue({
numero_dossier: '2026-000021',
parents: [{ user_id: 'p1', email: 'claire@test.fr', statut: StatutUtilisateurType.REFUSE }],
enfants: [{ id: 'e1', first_name: 'Emma', status: 'actif' }],
texte_motivation: 'Motivation test',
});
const result = await service.getRepriseDossier(token);
expect(result.parents).toHaveLength(1);
expect(result.enfants).toHaveLength(1);
expect(result.texte_motivation).toBe('Motivation test');
expect(result.numero_dossier).toBe('2026-000021');
});
it('getRepriseDossier returns fiche AM complète', async () => {
userServiceMock.findByTokenReprise.mockResolvedValue({
id: 'am1',
email: 'am@test.fr',
role: RoleType.ASSISTANTE_MATERNELLE,
numero_dossier: '2026-000003',
});
dossiersServiceMock.getDossierByNumero.mockResolvedValue({
type: 'am',
dossier: {
numero_dossier: '2026-000003',
user: {
id: 'am1',
email: 'am@test.fr',
prenom: 'Marie',
nom: 'DUPONT',
statut: StatutUtilisateurType.REFUSE,
},
numero_agrement: 'AGR-1',
nir: '123456789012345',
biographie: 'Bio',
nb_max_enfants: 4,
place_disponible: 2,
},
});
const result = await service.getRepriseDossier(token);
expect(result.numero_agrement).toBe('AGR-1');
expect(result.biographie).toBe('Bio');
expect(result.nb_max_enfants).toBe(4);
});
});
});