auditLogger = $this->createMock(AuditLogger::class); $this->handler = new AuditGradeEventsHandler($this->auditLogger); } public function testHandleNoteSaisieLogsAuditEntryWithCreationPayload(): void { $gradeId = GradeId::generate(); $evaluationId = Uuid::uuid4()->toString(); $studentId = Uuid::uuid4()->toString(); $createdBy = Uuid::uuid4()->toString(); $event = new NoteSaisie( gradeId: $gradeId, evaluationId: $evaluationId, studentId: $studentId, value: 15.5, status: 'draft', createdBy: $createdBy, occurredOn: new DateTimeImmutable(), ); $this->auditLogger->expects($this->once()) ->method('logDataChange') ->with( $this->equalTo('Grade'), $this->callback(static fn ($uuid) => $uuid->toString() === $gradeId->value->toString()), $this->equalTo('NoteSaisie'), $this->equalTo([]), $this->callback(static fn ($new) => $new['evaluation_id'] === $evaluationId && $new['student_id'] === $studentId && $new['value'] === 15.5 && $new['status'] === 'draft' && $new['created_by'] === $createdBy ), ); $this->handler->handleNoteSaisie($event); } public function testHandleNoteSaisieSupportsNullValue(): void { $event = new NoteSaisie( gradeId: GradeId::generate(), evaluationId: Uuid::uuid4()->toString(), studentId: Uuid::uuid4()->toString(), value: null, status: 'absent', createdBy: Uuid::uuid4()->toString(), occurredOn: new DateTimeImmutable(), ); $this->auditLogger->expects($this->once()) ->method('logDataChange') ->with( $this->equalTo('Grade'), $this->anything(), $this->equalTo('NoteSaisie'), $this->equalTo([]), $this->callback(static fn ($new) => $new['value'] === null && $new['status'] === 'absent' ), ); $this->handler->handleNoteSaisie($event); } public function testHandleNoteModifieeLogsAuditEntryWithDiff(): void { $gradeId = GradeId::generate(); $evaluationId = Uuid::uuid4()->toString(); $studentId = Uuid::uuid4()->toString(); $modifiedBy = Uuid::uuid4()->toString(); $event = new NoteModifiee( gradeId: $gradeId, evaluationId: $evaluationId, studentId: $studentId, oldValue: 12.0, newValue: 14.5, oldStatus: 'draft', newStatus: 'published', modifiedBy: $modifiedBy, occurredOn: new DateTimeImmutable(), ); $this->auditLogger->expects($this->once()) ->method('logDataChange') ->with( $this->equalTo('Grade'), $this->callback(static fn ($uuid) => $uuid->toString() === $gradeId->value->toString()), $this->equalTo('NoteModifiee'), $this->callback(static fn ($old) => $old['value'] === 12.0 && $old['status'] === 'draft' ), $this->callback(static fn ($new) => $new['value'] === 14.5 && $new['status'] === 'published' && $new['modified_by'] === $modifiedBy && $new['evaluation_id'] === $evaluationId && $new['student_id'] === $studentId ), ); $this->handler->handleNoteModifiee($event); } public function testHandleNoteModifieeSupportsNullValues(): void { $event = new NoteModifiee( gradeId: GradeId::generate(), evaluationId: Uuid::uuid4()->toString(), studentId: Uuid::uuid4()->toString(), oldValue: 10.0, newValue: null, oldStatus: 'published', newStatus: 'absent', modifiedBy: Uuid::uuid4()->toString(), occurredOn: new DateTimeImmutable(), ); $this->auditLogger->expects($this->once()) ->method('logDataChange') ->with( $this->equalTo('Grade'), $this->anything(), $this->equalTo('NoteModifiee'), $this->callback(static fn ($old) => $old['value'] === 10.0), $this->callback(static fn ($new) => $new['value'] === null && $new['status'] === 'absent' ), ); $this->handler->handleNoteModifiee($event); } public function testHandleNoteSaisieSupportsZeroValue(): void { $event = new NoteSaisie( gradeId: GradeId::generate(), evaluationId: Uuid::uuid4()->toString(), studentId: Uuid::uuid4()->toString(), value: 0.0, status: 'published', createdBy: Uuid::uuid4()->toString(), occurredOn: new DateTimeImmutable(), ); $this->auditLogger->expects($this->once()) ->method('logDataChange') ->with( $this->equalTo('Grade'), $this->anything(), $this->equalTo('NoteSaisie'), $this->equalTo([]), $this->callback(static fn ($new) => array_key_exists('value', $new) && $new['value'] === 0.0 && $new['status'] === 'published' ), ); $this->handler->handleNoteSaisie($event); } }