get(Connection::class); $this->sharedConnection = $connection; /** @var SubjectGradeStatsReader $reader */ $reader = static::getContainer()->get(SubjectGradeStatsReader::class); $this->reader = $reader; } protected function tearDown(): void { $this->cleanupSubjectStatsData([self::TENANT_A, self::TENANT_B]); parent::tearDown(); } protected function connection(): Connection { return $this->sharedConnection; } #[Test] public function returnsZeroStatsWhenSubjectHasNoEvaluation(): void { $subjectId = $this->insertSubject(self::TENANT_A, self::SCHOOL_ID, 'Sans évaluation', 'EMPTY'); $stats = $this->reader->countForSubject( TenantId::fromString(self::TENANT_A), SubjectId::fromString($subjectId), ); self::assertSame(0, $stats->evaluationCount); self::assertSame(0, $stats->gradeCount); self::assertFalse($stats->hasGrades()); } #[Test] public function countsEvaluationsAndGradesLinkedToSubject(): void { $subjectId = $this->insertSubject(self::TENANT_A, self::SCHOOL_ID, 'Maths', 'MATH'); $classId = $this->insertClass(self::TENANT_A, self::SCHOOL_ID); $teacherId = $this->insertUser(self::TENANT_A, 'teacher-math@test.local'); $studentAId = $this->insertUser(self::TENANT_A, 'student-a@test.local'); $studentBId = $this->insertUser(self::TENANT_A, 'student-b@test.local'); $eval1 = $this->insertEvaluation(self::TENANT_A, $classId, $subjectId, $teacherId, 'Contrôle 1'); $eval2 = $this->insertEvaluation(self::TENANT_A, $classId, $subjectId, $teacherId, 'Contrôle 2'); $this->insertGrade(self::TENANT_A, $eval1, $studentAId, 15.0); $this->insertGrade(self::TENANT_A, $eval1, $studentBId, 12.5); $this->insertGrade(self::TENANT_A, $eval2, $studentAId, 18.0); $stats = $this->reader->countForSubject( TenantId::fromString(self::TENANT_A), SubjectId::fromString($subjectId), ); self::assertSame(2, $stats->evaluationCount); self::assertSame(3, $stats->gradeCount); self::assertTrue($stats->hasGrades()); } #[Test] public function doesNotCountDataFromOtherTenants(): void { $subjectA = $this->insertSubject(self::TENANT_A, self::SCHOOL_ID, 'Histoire', 'HIST'); $subjectB = $this->insertSubject(self::TENANT_B, self::SCHOOL_ID, 'Histoire', 'HIST'); // Tenant B seed : 3 évaluations + 2 notes sur son subject $classB = $this->insertClass(self::TENANT_B, self::SCHOOL_ID); $teacherB = $this->insertUser(self::TENANT_B, 'teacher-b@test.local'); $studentB = $this->insertUser(self::TENANT_B, 'student-b-isolation@test.local'); $evalB1 = $this->insertEvaluation(self::TENANT_B, $classB, $subjectB, $teacherB, 'Eval B1'); $evalB2 = $this->insertEvaluation(self::TENANT_B, $classB, $subjectB, $teacherB, 'Eval B2'); $this->insertEvaluation(self::TENANT_B, $classB, $subjectB, $teacherB, 'Eval B3'); $this->insertGrade(self::TENANT_B, $evalB1, $studentB, 10.0); $this->insertGrade(self::TENANT_B, $evalB2, $studentB, 14.0); $statsA = $this->reader->countForSubject( TenantId::fromString(self::TENANT_A), SubjectId::fromString($subjectA), ); self::assertSame(0, $statsA->evaluationCount, 'Pas de fuite des évaluations du tenant B'); self::assertSame(0, $statsA->gradeCount, 'Pas de fuite des notes du tenant B'); } }