diff --git a/tests/Service/CguUserServiceTest.php b/tests/Service/CguUserServiceTest.php new file mode 100644 index 0000000..cb8079e --- /dev/null +++ b/tests/Service/CguUserServiceTest.php @@ -0,0 +1,219 @@ +entityManager = $this->createMock(EntityManagerInterface::class); + $this->service = new CguUserService($this->entityManager); + } + + // ========================================== + // TEST: isLatestCguAccepted + // ========================================== + + public function testIsLatestCguAcceptedReturnsFalseIfNoCguExists(): void + { + $user = $this->createMock(User::class); + + // 1. Create a mock of your ACTUAL custom repository + // Since 'findLatestCgu' exists in CguRepository, PHPUnit allows this. + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn(null); + + $this->entityManager->method('getRepository') + ->with(Cgu::class) + ->willReturn($cguRepo); + + $this->assertFalse($this->service->isLatestCguAccepted($user)); + } + + public function testIsLatestCguAcceptedReturnsFalseIfRelationDoesNotExist(): void + { + $user = $this->createMock(User::class); + $latestCgu = new Cgu(); + + // Mock CguRepository + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn($latestCgu); + + // Mock Generic Repository for CguUser (standard findOneBy) + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->method('findOneBy') + ->with(['users' => $user, 'cgu' => $latestCgu]) + ->willReturn(null); + + $this->entityManager->method('getRepository')->willReturnMap([ + [Cgu::class, $cguRepo], + [CguUser::class, $cguUserRepo], + ]); + + $this->assertFalse($this->service->isLatestCguAccepted($user)); + } + + public function testIsLatestCguAcceptedReturnsTrueIfAccepted(): void + { + $user = $this->createMock(User::class); + $latestCgu = new Cgu(); + + $cguUser = new CguUser(); + $cguUser->setIsAccepted(true); + + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn($latestCgu); + + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->method('findOneBy')->willReturn($cguUser); + + $this->entityManager->method('getRepository')->willReturnMap([ + [Cgu::class, $cguRepo], + [CguUser::class, $cguUserRepo], + ]); + + $this->assertTrue($this->service->isLatestCguAccepted($user)); + } + + // ========================================== + // TEST: acceptLatestCgu + // ========================================== + + public function testAcceptLatestCguDoNothingIfNoCgu(): void + { + $user = $this->createMock(User::class); + + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn(null); + + $this->entityManager->method('getRepository')->willReturn($cguRepo); + + $this->entityManager->expects($this->never())->method('persist'); + $this->entityManager->expects($this->never())->method('flush'); + + $this->service->acceptLatestCgu($user); + } + + public function testAcceptLatestCguCreatesNewRelation(): void + { + $user = $this->createMock(User::class); + $latestCgu = new Cgu(); + + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn($latestCgu); + + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->method('findOneBy')->willReturn(null); + + $this->entityManager->method('getRepository')->willReturnMap([ + [Cgu::class, $cguRepo], + [CguUser::class, $cguUserRepo], + ]); + + // Capture logic for persist + $capturedCguUser = null; + $this->entityManager->expects($this->once()) + ->method('persist') + ->with($this->callback(function ($entity) use ($latestCgu, $user, &$capturedCguUser) { + // Check basic structure + if ($entity instanceof CguUser && $entity->getCgu() === $latestCgu && $entity->getUsers() === $user) { + $capturedCguUser = $entity; + return true; + } + return false; + })); + + $this->entityManager->expects($this->once())->method('flush'); + + $this->service->acceptLatestCgu($user); + + // Assert Final State (after setIsAccepted(true) was called) + $this->assertNotNull($capturedCguUser); + $this->assertTrue($capturedCguUser->isAccepted()); + } + + public function testAcceptLatestCguUpdatesExistingRelation(): void + { + $user = $this->createMock(User::class); + $latestCgu = new Cgu(); + + $cguUser = new CguUser(); + $cguUser->setIsAccepted(false); + + $cguRepo = $this->createMock(CguRepository::class); + $cguRepo->method('findLatestCgu')->willReturn($latestCgu); + + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->method('findOneBy')->willReturn($cguUser); + + $this->entityManager->method('getRepository')->willReturnMap([ + [Cgu::class, $cguRepo], + [CguUser::class, $cguUserRepo], + ]); + + $this->entityManager->expects($this->never())->method('persist'); + $this->entityManager->expects($this->once())->method('flush'); + + $this->service->acceptLatestCgu($user); + + $this->assertTrue($cguUser->isAccepted()); + } + + // ========================================== + // TEST: declineCgu + // ========================================== + + public function testDeclineCguSuccess(): void + { + $user = $this->createMock(User::class); + $cgu = new Cgu(); + + $cguUser = new CguUser(); + $cguUser->setIsAccepted(true); + + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->expects($this->once()) + ->method('findOneBy') + ->with(['users' => $user, 'cgu' => $cgu]) + ->willReturn($cguUser); + + $this->entityManager->method('getRepository') + ->with(CguUser::class) + ->willReturn($cguUserRepo); + + $this->entityManager->expects($this->once())->method('flush'); + + $this->service->declineCgu($user, $cgu); + + $this->assertFalse($cguUser->isAccepted()); + } + + public function testDeclineCguThrowsExceptionIfNotFound(): void + { + $user = $this->createMock(User::class); + $cgu = new Cgu(); + + $cguUserRepo = $this->createMock(EntityRepository::class); + $cguUserRepo->method('findOneBy')->willReturn(null); + + $this->entityManager->method('getRepository')->willReturn($cguUserRepo); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('CGU not found for this user'); + + $this->service->declineCgu($user, $cgu); + } +} \ No newline at end of file