inner = new InMemoryEvaluationStatisticsRepository(); $this->cached = new CachingEvaluationStatisticsRepository( inner: $this->inner, cache: new ArrayAdapter(), ); } #[Test] public function itCachesStatisticsOnRead(): void { $evaluationId = EvaluationId::generate(); $stats = new ClassStatistics(average: 14.5, min: 8.0, max: 19.0, median: 15.0, gradedCount: 5); $this->inner->save($evaluationId, $stats); // Premier appel : va au inner $result1 = $this->cached->findByEvaluation($evaluationId); self::assertNotNull($result1); self::assertSame(14.5, $result1->average); // Deuxième appel : devrait venir du cache (même résultat) $result2 = $this->cached->findByEvaluation($evaluationId); self::assertNotNull($result2); self::assertSame(14.5, $result2->average); } #[Test] public function itInvalidatesCacheOnSave(): void { $evaluationId = EvaluationId::generate(); $stats1 = new ClassStatistics(average: 14.0, min: 8.0, max: 19.0, median: 14.0, gradedCount: 3); // Sauvegarder et lire pour remplir le cache $this->cached->save($evaluationId, $stats1); $this->cached->findByEvaluation($evaluationId); // Mettre à jour $stats2 = new ClassStatistics(average: 16.0, min: 10.0, max: 20.0, median: 16.0, gradedCount: 4); $this->cached->save($evaluationId, $stats2); $result = $this->cached->findByEvaluation($evaluationId); self::assertNotNull($result); self::assertSame(16.0, $result->average); } #[Test] public function itReturnsNullForUnknownEvaluation(): void { $result = $this->cached->findByEvaluation(EvaluationId::generate()); self::assertNull($result); } #[Test] public function itInvalidatesCacheOnDelete(): void { $evaluationId = EvaluationId::generate(); $stats = new ClassStatistics(average: 14.5, min: 8.0, max: 19.0, median: 15.0, gradedCount: 5); $this->cached->save($evaluationId, $stats); // Remplir le cache $this->cached->findByEvaluation($evaluationId); // Supprimer $this->cached->delete($evaluationId); // Le cache ne doit plus retourner l'ancienne valeur self::assertNull($this->cached->findByEvaluation($evaluationId)); } #[Test] public function itCachesNullResultForUnknownEvaluation(): void { $evaluationId = EvaluationId::generate(); // Premier appel : null → mis en cache self::assertNull($this->cached->findByEvaluation($evaluationId)); // Sauvegarder directement dans inner (sans passer par le cache) $this->inner->save($evaluationId, new ClassStatistics( average: 12.0, min: 10.0, max: 14.0, median: 12.0, gradedCount: 2, )); // Le cache retourne encore null (valeur cachée) $result = $this->cached->findByEvaluation($evaluationId); self::assertNull($result); } }