From 1fb7460f8e803770cee38cfa488edacff5b5c314 Mon Sep 17 00:00:00 2001 From: matthieu Date: Tue, 19 May 2026 23:38:40 +0200 Subject: [PATCH] feat(mail) : commande app:mail:sync avec options --folder et --dry-run --- src/Command/MailSyncCommand.php | 110 ++++++++++++++++++ .../Command/MailSyncCommandTest.php | 40 +++++++ 2 files changed, 150 insertions(+) create mode 100644 src/Command/MailSyncCommand.php create mode 100644 tests/Functional/Command/MailSyncCommandTest.php diff --git a/src/Command/MailSyncCommand.php b/src/Command/MailSyncCommand.php new file mode 100644 index 0000000..1f787af --- /dev/null +++ b/src/Command/MailSyncCommand.php @@ -0,0 +1,110 @@ +addOption( + 'folder', + null, + InputOption::VALUE_OPTIONAL, + 'Synchronise uniquement le dossier spécifié (ex: INBOX)', + ) + ->addOption( + 'dry-run', + null, + InputOption::VALUE_NONE, + 'Simule la synchronisation sans écrire en base (lecture IMAP uniquement)', + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $config = $this->configRepository->findSingleton(); + + if (null === $config || !$config->isEnabled()) { + $io->info('Mail config disabled, skipping.'); + + return Command::SUCCESS; + } + + $isDryRun = (bool) $input->getOption('dry-run'); + $folderPath = $input->getOption('folder'); + + if ($isDryRun) { + $io->note('Mode --dry-run activé : aucune écriture en base.'); + $io->success('Dry-run terminé — config IMAP active, aucune sync exécutée.'); + + return Command::SUCCESS; + } + + $io->text('Démarrage de la synchronisation mail...'); + $startTime = microtime(true); + + if (null !== $folderPath) { + $folder = $this->folderRepository->findByPath((string) $folderPath); + + if (null === $folder) { + $io->error(sprintf('Dossier "%s" introuvable en base — lance une sync complète au moins une fois.', $folderPath)); + + return Command::FAILURE; + } + + $io->text(sprintf('Synchronisation du dossier : %s', $folderPath)); + $report = $this->mailSyncService->syncFolder($folder); + } else { + $report = $this->mailSyncService->syncAll(); + } + + $elapsed = round(microtime(true) - $startTime, 2); + + $io->success(sprintf( + 'Sync terminée en %.1fs : %d créés, %d mis à jour, %d supprimés, %d dossiers scannés.', + $elapsed, + $report->createdCount, + $report->updatedCount, + $report->deletedCount, + $report->foldersScanned, + )); + + if ([] !== $report->errors) { + $io->warning(sprintf('%d erreur(s) :', count($report->errors))); + + foreach ($report->errors as $error) { + $io->text(' - '.$error); + } + } + + return [] === $report->errors ? Command::SUCCESS : Command::FAILURE; + } +} diff --git a/tests/Functional/Command/MailSyncCommandTest.php b/tests/Functional/Command/MailSyncCommandTest.php new file mode 100644 index 0000000..9ad3a5e --- /dev/null +++ b/tests/Functional/Command/MailSyncCommandTest.php @@ -0,0 +1,40 @@ +find('app:mail:sync'); + $tester = new CommandTester($command); + + $exitCode = $tester->execute([]); + + self::assertSame(0, $exitCode); + self::assertStringContainsString('disabled', strtolower($tester->getDisplay())); + } + + public function testCommandDryRunExitsSuccess(): void + { + self::bootKernel(); + $application = new Application(self::$kernel); + $command = $application->find('app:mail:sync'); + $tester = new CommandTester($command); + + $exitCode = $tester->execute(['--dry-run' => true]); + + self::assertSame(0, $exitCode); + } +}