inner = new InMemoryStudentAverageRepository(); $this->cached = new CachingStudentAverageRepository( inner: $this->inner, cache: new ArrayAdapter(), ); } #[Test] public function itCachesSubjectAveragesOnRead(): void { $tenantId = TenantId::fromString(self::TENANT_ID); $studentId = UserId::fromString(self::STUDENT_ID); $this->inner->saveSubjectAverage( $tenantId, $studentId, SubjectId::fromString(self::SUBJECT_ID), self::PERIOD_ID, 15.0, 3, ); $result1 = $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); $result2 = $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); self::assertSame([15.0], $result1); self::assertSame([15.0], $result2); } #[Test] public function itInvalidatesCacheOnSaveSubjectAverage(): void { $tenantId = TenantId::fromString(self::TENANT_ID); $studentId = UserId::fromString(self::STUDENT_ID); $subjectId = SubjectId::fromString(self::SUBJECT_ID); $this->cached->saveSubjectAverage($tenantId, $studentId, $subjectId, self::PERIOD_ID, 14.0, 2); // Remplir le cache $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); // Mettre à jour → doit invalider le cache $this->cached->saveSubjectAverage($tenantId, $studentId, $subjectId, self::PERIOD_ID, 16.0, 3); $result = $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); self::assertSame([16.0], $result); } #[Test] public function itReturnsEmptyArrayWhenNoAverages(): void { $result = $this->cached->findSubjectAveragesForStudent( UserId::fromString(self::STUDENT_ID), self::PERIOD_ID, TenantId::fromString(self::TENANT_ID), ); self::assertSame([], $result); } #[Test] public function itDelegatesToInnerForGeneralAverage(): void { $tenantId = TenantId::fromString(self::TENANT_ID); $studentId = UserId::fromString(self::STUDENT_ID); $this->cached->saveGeneralAverage($tenantId, $studentId, self::PERIOD_ID, 13.5); $result = $this->cached->findGeneralAverageForStudent($studentId, self::PERIOD_ID, $tenantId); self::assertSame(13.5, $result); } #[Test] public function itInvalidatesCacheOnDeleteSubjectAverage(): void { $tenantId = TenantId::fromString(self::TENANT_ID); $studentId = UserId::fromString(self::STUDENT_ID); $subjectId = SubjectId::fromString(self::SUBJECT_ID); $this->cached->saveSubjectAverage($tenantId, $studentId, $subjectId, self::PERIOD_ID, 14.0, 2); // Remplir le cache $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); // Supprimer → doit invalider le cache $this->cached->deleteSubjectAverage($studentId, $subjectId, self::PERIOD_ID, $tenantId); $result = $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); self::assertSame([], $result); } #[Test] public function itCachesMultipleSubjectAverages(): void { $tenantId = TenantId::fromString(self::TENANT_ID); $studentId = UserId::fromString(self::STUDENT_ID); $subject2Id = '77777777-7777-7777-7777-777777777777'; $this->cached->saveSubjectAverage( $tenantId, $studentId, SubjectId::fromString(self::SUBJECT_ID), self::PERIOD_ID, 15.0, 3, ); $this->cached->saveSubjectAverage( $tenantId, $studentId, SubjectId::fromString($subject2Id), self::PERIOD_ID, 12.0, 2, ); $result = $this->cached->findSubjectAveragesForStudent($studentId, self::PERIOD_ID, $tenantId); self::assertCount(2, $result); self::assertContains(15.0, $result); self::assertContains(12.0, $result); } }