reader = new InMemoryTeacherStatisticsReader(); $this->handler = new GetStudentProgressionHandler( $this->reader, new TeacherStatisticsCalculator(), ); } #[Test] public function itReturnsEmptyProgressionWhenNoGrades(): void { $result = ($this->handler)($this->query()); self::assertSame([], $result->grades); self::assertNull($result->trendLine); } #[Test] public function itReturnsSingleGradeWithNoTrendLine(): void { $this->reader->feedGradeHistory([ ['date' => '2026-01-15', 'value' => 12.0, 'evaluationTitle' => 'Contrôle 1'], ]); $result = ($this->handler)($this->query()); self::assertCount(1, $result->grades); self::assertSame('2026-01-15', $result->grades[0]->date); self::assertSame(12.0, $result->grades[0]->value); self::assertNull($result->trendLine); } #[Test] public function itComputesTrendLineFromMultipleGrades(): void { $this->reader->feedGradeHistory([ ['date' => '2026-01-15', 'value' => 10.0, 'evaluationTitle' => 'Contrôle 1'], ['date' => '2026-02-10', 'value' => 12.0, 'evaluationTitle' => 'Contrôle 2'], ['date' => '2026-03-05', 'value' => 14.0, 'evaluationTitle' => 'Contrôle 3'], ]); $result = ($this->handler)($this->query()); self::assertCount(3, $result->grades); self::assertNotNull($result->trendLine); self::assertGreaterThan(0, $result->trendLine->slope); // Positive trend } private function query(): GetStudentProgressionQuery { return new GetStudentProgressionQuery( studentId: '550e8400-e29b-41d4-a716-446655440050', subjectId: '550e8400-e29b-41d4-a716-446655440030', classId: '550e8400-e29b-41d4-a716-446655440020', teacherId: '550e8400-e29b-41d4-a716-446655440010', tenantId: '550e8400-e29b-41d4-a716-446655440001', ); } }