Easy_solution/tests/Service/CguUserServiceTest.php

219 lines
7.3 KiB
PHP

<?php
namespace App\Tests\Service;
use App\Entity\Cgu;
use App\Entity\CguUser;
use App\Entity\User;
use App\Repository\CguRepository; // <--- Import your actual repository
use App\Service\CguUserService;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class CguUserServiceTest extends TestCase
{
private CguUserService $service;
private MockObject|EntityManagerInterface $entityManager;
protected function setUp(): void
{
$this->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);
}
}