fix(cards): FK card_responses via relation JoinColumn + save(create)
Double mapping @Column/@JoinColumn sur id_card ; persist response via card/user relations. Garde update() sur l’instance (évite save parent qui nullifiait les FK enfants). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -24,6 +24,7 @@ describe('CardsService (#194)', () => {
|
||||
const cardsRepo = {
|
||||
create: jest.fn((x) => x),
|
||||
save: jest.fn(async (x) => ({ ...x, id: x.id ?? 'card-1', cree_le: new Date(), modifie_le: new Date() })),
|
||||
update: jest.fn(async () => ({ affected: 1 })),
|
||||
findOne: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
createQueryBuilder: jest.fn(),
|
||||
@@ -37,7 +38,8 @@ describe('CardsService (#194)', () => {
|
||||
};
|
||||
const responsesRepo = {
|
||||
create: jest.fn((x) => x),
|
||||
save: jest.fn(),
|
||||
save: jest.fn(async (x) => x),
|
||||
insert: jest.fn(),
|
||||
};
|
||||
const amChildrenRepo = { findOne: jest.fn() };
|
||||
const parentsChildrenRepo = { find: jest.fn(), findOne: jest.fn() };
|
||||
@@ -226,4 +228,57 @@ describe('CardsService (#194)', () => {
|
||||
expect(ids).toEqual(['am-1', 'p-1', 'p-2']);
|
||||
expect(saved.find((m) => m.id_utilisateur === 'p-2')?.is_creator).toBe(false);
|
||||
});
|
||||
|
||||
it('parent accepte conge_am → response via relation + carte traitee', async () => {
|
||||
cardsRepo.findOne.mockResolvedValue({
|
||||
id: 'card-1',
|
||||
type_code: 'conge_am',
|
||||
id_placement: 'pl-1',
|
||||
id_evenement: 'ev-1',
|
||||
cree_par: 'am-1',
|
||||
operation: CardOperationType.CREATE,
|
||||
statut: CardInstanceStatutType.OUVERTE,
|
||||
payload: { date_debut: '2026-10-27', date_fin: '2026-10-31' },
|
||||
purge_at: new Date(),
|
||||
cree_le: new Date(),
|
||||
modifie_le: new Date(),
|
||||
type: {
|
||||
titre: 'Congé AM',
|
||||
response_mode: CardResponseModeType.ACCEPT_REFUSE,
|
||||
retention_days: 14,
|
||||
},
|
||||
responses: [],
|
||||
audience: [
|
||||
{ id_utilisateur: 'am-1' },
|
||||
{ id_utilisateur: 'p-1' },
|
||||
{ id_utilisateur: 'p-2' },
|
||||
],
|
||||
});
|
||||
audienceRepo.findOne.mockResolvedValue({ id_card: 'card-1', id_utilisateur: 'p-1' });
|
||||
evenementsService.maj.mockResolvedValue({});
|
||||
|
||||
const res = await service.repondre('p-1', RoleType.PARENT, 'card-1', {
|
||||
action: 'accept' as never,
|
||||
});
|
||||
|
||||
expect(responsesRepo.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
card: { id: 'card-1' },
|
||||
user: { id: 'p-1' },
|
||||
action: 'accept',
|
||||
}),
|
||||
);
|
||||
expect(responsesRepo.save).toHaveBeenCalled();
|
||||
expect(evenementsService.maj).toHaveBeenCalledWith(
|
||||
'p-1',
|
||||
RoleType.PARENT,
|
||||
'ev-1',
|
||||
expect.objectContaining({ statut: StatutEvenementAgendaType.ACCEPTE }),
|
||||
);
|
||||
expect(cardsRepo.update).toHaveBeenCalledWith(
|
||||
{ id: 'card-1' },
|
||||
expect.objectContaining({ statut: CardInstanceStatutType.TRAITEE }),
|
||||
);
|
||||
expect(res.statut).toBe(CardInstanceStatutType.TRAITEE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,12 +227,14 @@ export class CardsService {
|
||||
throw new BadRequestException('Motivation obligatoire en cas de refus');
|
||||
}
|
||||
|
||||
await this.responsesRepo.insert({
|
||||
id_card: card.id,
|
||||
id_utilisateur: userId,
|
||||
action: dto.action,
|
||||
comment: dto.comment?.trim() || undefined,
|
||||
});
|
||||
await this.responsesRepo.save(
|
||||
this.responsesRepo.create({
|
||||
card: { id: card.id },
|
||||
user: { id: userId },
|
||||
action: dto.action,
|
||||
comment: dto.comment?.trim() || undefined,
|
||||
}),
|
||||
);
|
||||
|
||||
if (card.id_evenement) {
|
||||
if (dto.action === CardResponseActionType.ACCEPT || dto.action === CardResponseActionType.ACK) {
|
||||
@@ -252,8 +254,8 @@ export class CardsService {
|
||||
}
|
||||
|
||||
card.purge_at = this.purgeAt(card.type.retention_days, card.statut);
|
||||
// update() et non save() : save() avec relations responses/audience
|
||||
// resynchronise les FK et tente UPDATE card_responses SET id_card=null.
|
||||
// Ne pas cardsRepo.save(card) avec relations chargées : TypeORM peut
|
||||
// resynchroniser les FK enfants (UPDATE … SET id_card=null).
|
||||
await this.cardsRepo.update(
|
||||
{ id: card.id },
|
||||
{ statut: card.statut, purge_at: card.purge_at },
|
||||
|
||||
Reference in New Issue
Block a user