Files
ludikevent_crm/tests/Command/BackupCommandTest.php

173 lines
6.0 KiB
PHP
Raw Permalink Normal View History

<?php
namespace App\Tests\Command;
use App\Command\BackupCommand;
use App\Entity\Backup;
use App\Service\Mailer\Mailer;
use App\Service\System\DatabaseDumper;
use App\Service\System\ZipArchiver;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\KernelInterface;
#[AllowMockObjectsWithoutExpectations]
class BackupCommandTest extends TestCase
{
private $kernel;
private $entityManager;
private $mailer;
private $databaseDumper;
private $zipArchiver;
protected function setUp(): void
{
$this->kernel = $this->createStub(KernelInterface::class);
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->mailer = $this->createMock(Mailer::class);
$this->databaseDumper = $this->createMock(DatabaseDumper::class);
$this->zipArchiver = $this->createMock(ZipArchiver::class);
}
public function testExecuteSuccess()
{
// 1. Setup Data
$projectDir = sys_get_temp_dir() . '/backup_test_' . uniqid();
mkdir($projectDir . '/sauvegarde', 0777, true);
$this->kernel->method('getProjectDir')->willReturn($projectDir);
// 2. Expectations
// EntityManager
$this->entityManager->expects($this->once())->method('persist')->with($this->isInstanceOf(Backup::class));
$this->entityManager->expects($this->atLeast(2))->method('flush'); // Once at start, once at end
// Cleanup expectations
// Mocking Query class which might be final. If so, we'll see an error.
// But commonly in Doctrine mocks, we have to deal with this.
$query = $this->createStub(Query::class);
$query->method('setParameter')->willReturnSelf();
$query->method('execute');
$this->entityManager->method('createQuery')->willReturn($query);
// Database Dumper
$this->databaseDumper->expects($this->once())
->method('dump')
->with($this->anything(), $this->stringEndsWith('temp_db.sql'));
// Zip Archiver
$this->zipArchiver->expects($this->once())
->method('createArchive')
->willReturnCallback(function($zipPath, $sqlPath, $dirs) {
// Create a dummy zip file so filesize() works
touch($zipPath);
});
// Mailer
$this->mailer->expects($this->once())
->method('send')
->with(
'notification@siteconseil.fr',
'Intranet Ludievent',
$this->stringContains('✅ Sauvegarde'),
'mails/backup_notification.twig',
$this->callback(function($context) {
return isset($context['backup']) && $context['backup']->getStatus() === 'SUCCESS';
})
);
// 3. Execution
$command = new BackupCommand(
$this->kernel,
$this->entityManager,
$this->mailer,
$this->databaseDumper,
$this->zipArchiver
);
$application = new Application();
$application->addCommand($command);
$commandTester = new CommandTester($application->find('app:backup'));
$commandTester->execute([]);
// 4. Assertions
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Sauvegarde réussie', $output);
// Cleanup
$this->removeDirectory($projectDir);
}
public function testExecuteFailure()
{
// 1. Setup Data
$projectDir = sys_get_temp_dir() . '/backup_test_fail_' . uniqid();
mkdir($projectDir . '/sauvegarde', 0777, true);
$this->kernel->method('getProjectDir')->willReturn($projectDir);
// 2. Expectations - Fail at Dump
$this->databaseDumper->expects($this->once())
->method('dump')
->willThrowException(new \Exception("Simulated Dump Error"));
// Mailer - Should send Error notification
$this->mailer->expects($this->once())
->method('send')
->with(
'notification@siteconseil.fr',
'Intranet Ludievent',
$this->stringContains('❌ Sauvegarde'),
'mails/backup_notification.twig',
$this->callback(function($context) {
return isset($context['backup'])
&& $context['backup']->getStatus() === 'ERROR'
&& $context['backup']->getErrorMessage() === 'Simulated Dump Error';
})
);
// Cleanup expectations
$query = $this->createStub(Query::class);
$query->method('setParameter')->willReturnSelf();
$query->method('execute');
$this->entityManager->method('createQuery')->willReturn($query);
// 3. Execution
$command = new BackupCommand(
$this->kernel,
$this->entityManager,
$this->mailer,
$this->databaseDumper,
$this->zipArchiver
);
$application = new Application();
$application->addCommand($command);
$commandTester = new CommandTester($application->find('app:backup'));
$commandTester->execute([]);
// 4. Assertions
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Échec : Simulated Dump Error', $output);
// Cleanup
$this->removeDirectory($projectDir);
}
private function removeDirectory($dir) {
if (!is_dir($dir)) return;
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? $this->removeDirectory("$dir/$file") : unlink("$dir/$file");
}
rmdir($dir);
}
}