diff --git a/config/PHPMD/rules.xml b/config/PHPMD/rules.xml index a0fbf650..081ed9f3 100644 --- a/config/PHPMD/rules.xml +++ b/config/PHPMD/rules.xml @@ -45,7 +45,11 @@ - + + + + + diff --git a/config/doctrine.yml b/config/doctrine.yml index 7b53b7ff..327cf305 100644 --- a/config/doctrine.yml +++ b/config/doctrine.yml @@ -17,12 +17,6 @@ doctrine: naming_strategy: doctrine.orm.naming_strategy.underscore auto_mapping: false mappings: - TatevikGrRssBundle: - is_bundle: false - type: attribute - dir: '%kernel.project_dir%/vendor/tatevikgr/rss-feed/src/Entity' - prefix: 'TatevikGr\RssFeedBundle\Entity' - alias: 'RssBundle' Identity: is_bundle: false type: attribute diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 6841eed5..38a75a1b 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -6,6 +6,7 @@ framework: transports: # https://symfony.com/doc/current/messenger.html#transport-configuration + sync: 'sync://' async_email: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: @@ -25,3 +26,8 @@ framework: # Route your messages to the transports 'PhpList\Core\Domain\Messaging\Message\AsyncEmailMessage': async_email 'PhpList\Core\Domain\Messaging\Message\SubscriberConfirmationMessage': async_email + 'PhpList\Core\Domain\Messaging\Message\SubscriptionConfirmationMessage': async_email + 'PhpList\Core\Domain\Messaging\Message\PasswordResetMessage': async_email + 'PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage': async_email + 'PhpList\Core\Domain\Messaging\Message\SyncCampaignProcessorMessage': sync + diff --git a/config/services/commands.yml b/config/services/commands.yml index 4f30b06b..7e16ac87 100644 --- a/config/services/commands.yml +++ b/config/services/commands.yml @@ -12,7 +12,7 @@ services: resource: '../../src/Domain/Identity/Command' tags: ['console.command'] - PhpList\Core\Domain\Messaging\Command\ProcessBouncesCommand: + PhpList\Core\Bounce\Command\ProcessBouncesCommand: arguments: $protocolProcessors: !tagged_iterator 'phplist.bounce_protocol_processor' diff --git a/config/services/managers.yml b/config/services/managers.yml index 22dbe066..2f72bd7e 100644 --- a/config/services/managers.yml +++ b/config/services/managers.yml @@ -80,7 +80,7 @@ services: autowire: true autoconfigure: true - PhpList\Core\Domain\Messaging\Service\Manager\BounceManager: + PhpList\Core\Bounce\Service\Manager\BounceManager: autowire: true autoconfigure: true diff --git a/config/services/messenger.yml b/config/services/messenger.yml index 80f893f4..214a4c86 100644 --- a/config/services/messenger.yml +++ b/config/services/messenger.yml @@ -1,6 +1,7 @@ services: # Register message handlers for Symfony Messenger PhpList\Core\Domain\Messaging\MessageHandler\: + autowire: true resource: '../../src/Domain/Messaging/MessageHandler' tags: [ 'messenger.message_handler' ] @@ -24,7 +25,7 @@ services: $passwordResetUrl: '%app.password_reset_url%' PhpList\Core\Domain\Messaging\MessageHandler\SubscriptionConfirmationMessageHandler: - autowire: true - autoconfigure: true - tags: [ 'messenger.message_handler' ] + autowire: true + autoconfigure: true + tags: [ 'messenger.message_handler' ] diff --git a/config/services/processor.yml b/config/services/processor.yml index acbd11c0..8ef01135 100644 --- a/config/services/processor.yml +++ b/config/services/processor.yml @@ -4,18 +4,18 @@ services: autoconfigure: true public: false - PhpList\Core\Domain\Messaging\Service\Processor\PopBounceProcessor: + PhpList\Core\Bounce\Service\Processor\PopBounceProcessor: arguments: $host: '%imap_bounce.host%' $port: '%imap_bounce.port%' $mailboxNames: '%imap_bounce.mailbox_name%' tags: ['phplist.bounce_protocol_processor'] - PhpList\Core\Domain\Messaging\Service\Processor\MboxBounceProcessor: + PhpList\Core\Bounce\Service\Processor\MboxBounceProcessor: tags: ['phplist.bounce_protocol_processor'] - PhpList\Core\Domain\Messaging\Service\Processor\AdvancedBounceRulesProcessor: ~ + PhpList\Core\Bounce\Service\Processor\AdvancedBounceRulesProcessor: ~ - PhpList\Core\Domain\Messaging\Service\Processor\UnidentifiedBounceReprocessor: ~ + PhpList\Core\Bounce\Service\Processor\UnidentifiedBounceReprocessor: ~ - PhpList\Core\Domain\Messaging\Service\Processor\BounceDataProcessor: ~ + PhpList\Core\Bounce\Service\Processor\BounceDataProcessor: ~ diff --git a/config/services/resolvers.yml b/config/services/resolvers.yml index bf8f9fc7..99c08356 100644 --- a/config/services/resolvers.yml +++ b/config/services/resolvers.yml @@ -10,6 +10,6 @@ services: autowire: true autoconfigure: true - PhpList\Core\Domain\Messaging\Service\BounceActionResolver: + PhpList\Core\Bounce\Service\BounceActionResolver: arguments: - !tagged_iterator { tag: 'phplist.bounce_action_handler' } diff --git a/config/services/services.yml b/config/services/services.yml index bc236399..65ede6b7 100644 --- a/config/services/services.yml +++ b/config/services/services.yml @@ -31,11 +31,6 @@ services: autoconfigure: true public: true - PhpList\Core\Domain\Messaging\Service\Processor\CampaignProcessor: - autowire: true - autoconfigure: true - public: true - PhpList\Core\Domain\Messaging\Service\SendRateLimiter: autowire: true autoconfigure: true @@ -52,7 +47,7 @@ services: autowire: true autoconfigure: true - PhpList\Core\Domain\Messaging\Service\ConsecutiveBounceHandler: + PhpList\Core\Bounce\Service\ConsecutiveBounceHandler: autowire: true autoconfigure: true arguments: @@ -61,7 +56,7 @@ services: Webklex\PHPIMAP\ClientManager: ~ - PhpList\Core\Domain\Messaging\Service\WebklexImapClientFactory: + PhpList\Core\Bounce\Service\WebklexImapClientFactory: autowire: true autoconfigure: true arguments: @@ -78,34 +73,34 @@ services: $username: '%imap_bounce.email%' $password: '%imap_bounce.password%' - PhpList\Core\Domain\Messaging\Service\NativeBounceProcessingService: + PhpList\Core\Bounce\Service\NativeBounceProcessingService: autowire: true autoconfigure: true arguments: $purgeProcessed: '%imap_bounce.purge%' $purgeUnprocessed: '%imap_bounce.purge_unprocessed%' - PhpList\Core\Domain\Messaging\Service\WebklexBounceProcessingService: + PhpList\Core\Bounce\Service\WebklexBounceProcessingService: autowire: true autoconfigure: true arguments: $purgeProcessed: '%imap_bounce.purge%' $purgeUnprocessed: '%imap_bounce.purge_unprocessed%' - PhpList\Core\Domain\Messaging\Service\LockService: + PhpList\Core\Bounce\Service\LockService: autowire: true autoconfigure: true - PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService: + PhpList\Core\Bounce\Service\SubscriberBlacklistService: autowire: true autoconfigure: true - PhpList\Core\Domain\Messaging\Service\MessageParser: + PhpList\Core\Bounce\Service\MessageParser: autowire: true autoconfigure: true _instanceof: - PhpList\Core\Domain\Messaging\Service\Handler\BounceActionHandlerInterface: + PhpList\Core\Bounce\Service\Handler\BounceActionHandlerInterface: tags: - { name: 'phplist.bounce_action_handler' } diff --git a/resources/translations/messages.en.xlf b/resources/translations/messages.en.xlf index 9a9fae29..b3204742 100644 --- a/resources/translations/messages.en.xlf +++ b/resources/translations/messages.en.xlf @@ -726,6 +726,10 @@ Thank you. No data changed __No data changed + + Campaign not found or not in submitted status + __Campaign not found or not in submitted status + diff --git a/src/Domain/Messaging/Command/ProcessBouncesCommand.php b/src/Bounce/Command/ProcessBouncesCommand.php similarity index 89% rename from src/Domain/Messaging/Command/ProcessBouncesCommand.php rename to src/Bounce/Command/ProcessBouncesCommand.php index 0d51d4f1..fcb37ba2 100644 --- a/src/Domain/Messaging/Command/ProcessBouncesCommand.php +++ b/src/Bounce/Command/ProcessBouncesCommand.php @@ -2,14 +2,15 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Command; +namespace PhpList\Core\Bounce\Command; +use Doctrine\ORM\EntityManagerInterface; use Exception; -use PhpList\Core\Domain\Messaging\Service\ConsecutiveBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceProtocolProcessor; -use PhpList\Core\Domain\Messaging\Service\Processor\AdvancedBounceRulesProcessor; -use PhpList\Core\Domain\Messaging\Service\Processor\UnidentifiedBounceReprocessor; -use PhpList\Core\Domain\Messaging\Service\LockService; +use PhpList\Core\Bounce\Service\ConsecutiveBounceHandler; +use PhpList\Core\Bounce\Service\LockService; +use PhpList\Core\Bounce\Service\Processor\AdvancedBounceRulesProcessor; +use PhpList\Core\Bounce\Service\Processor\BounceProtocolProcessor; +use PhpList\Core\Bounce\Service\Processor\UnidentifiedBounceReprocessor; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -46,6 +47,7 @@ public function __construct( private readonly UnidentifiedBounceReprocessor $unidentifiedReprocessor, private readonly ConsecutiveBounceHandler $consecutiveBounceHandler, private readonly TranslatorInterface $translator, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct(); } @@ -62,6 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $force = (bool)$input->getOption('force'); $lock = $this->lockService->acquirePageLock('bounce_processor', $force); + $this->entityManager->flush(); if (($lock ?? 0) === 0) { $forceLockFailed = $this->translator->trans('Could not apply force lock. Aborting.'); diff --git a/src/Domain/Messaging/Exception/ImapConnectionException.php b/src/Bounce/Exception/ImapConnectionException.php similarity index 84% rename from src/Domain/Messaging/Exception/ImapConnectionException.php rename to src/Bounce/Exception/ImapConnectionException.php index 8e5295e2..58d3495d 100644 --- a/src/Domain/Messaging/Exception/ImapConnectionException.php +++ b/src/Bounce/Exception/ImapConnectionException.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Exception; +namespace PhpList\Core\Bounce\Exception; use RuntimeException; use Throwable; diff --git a/src/Domain/Messaging/Exception/OpenMboxFileException.php b/src/Bounce/Exception/OpenMboxFileException.php similarity index 84% rename from src/Domain/Messaging/Exception/OpenMboxFileException.php rename to src/Bounce/Exception/OpenMboxFileException.php index 2fc7c458..c5dc775f 100644 --- a/src/Domain/Messaging/Exception/OpenMboxFileException.php +++ b/src/Bounce/Exception/OpenMboxFileException.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Exception; +namespace PhpList\Core\Bounce\Exception; use RuntimeException; use Throwable; diff --git a/src/Domain/Messaging/Service/BounceActionResolver.php b/src/Bounce/Service/BounceActionResolver.php similarity index 92% rename from src/Domain/Messaging/Service/BounceActionResolver.php rename to src/Bounce/Service/BounceActionResolver.php index 93d432dd..0359866c 100644 --- a/src/Domain/Messaging/Service/BounceActionResolver.php +++ b/src/Bounce/Service/BounceActionResolver.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; -use PhpList\Core\Domain\Messaging\Service\Handler\BounceActionHandlerInterface; +use PhpList\Core\Bounce\Service\Handler\BounceActionHandlerInterface; use RuntimeException; class BounceActionResolver diff --git a/src/Domain/Messaging/Service/BounceProcessingServiceInterface.php b/src/Bounce/Service/BounceProcessingServiceInterface.php similarity index 77% rename from src/Domain/Messaging/Service/BounceProcessingServiceInterface.php rename to src/Bounce/Service/BounceProcessingServiceInterface.php index 9d16702f..8050a400 100644 --- a/src/Domain/Messaging/Service/BounceProcessingServiceInterface.php +++ b/src/Bounce/Service/BounceProcessingServiceInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; interface BounceProcessingServiceInterface { diff --git a/src/Domain/Messaging/Service/ConsecutiveBounceHandler.php b/src/Bounce/Service/ConsecutiveBounceHandler.php similarity index 96% rename from src/Domain/Messaging/Service/ConsecutiveBounceHandler.php rename to src/Bounce/Service/ConsecutiveBounceHandler.php index 91c4c041..6a2687f2 100644 --- a/src/Domain/Messaging/Service/ConsecutiveBounceHandler.php +++ b/src/Bounce/Service/ConsecutiveBounceHandler.php @@ -2,16 +2,15 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; use PhpList\Core\Domain\Messaging\Model\UserMessage; use PhpList\Core\Domain\Messaging\Model\UserMessageBounce; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Contracts\Translation\TranslatorInterface; diff --git a/src/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php b/src/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php similarity index 90% rename from src/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php rename to src/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php index e3b743cb..9f224007 100644 --- a/src/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php +++ b/src/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandler.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use Symfony\Contracts\Translation\TranslatorInterface; class BlacklistEmailAndDeleteBounceHandler implements BounceActionHandlerInterface diff --git a/src/Domain/Messaging/Service/Handler/BlacklistEmailHandler.php b/src/Bounce/Service/Handler/BlacklistEmailHandler.php similarity index 92% rename from src/Domain/Messaging/Service/Handler/BlacklistEmailHandler.php rename to src/Bounce/Service/Handler/BlacklistEmailHandler.php index 4f95c18b..f2bd12b9 100644 --- a/src/Domain/Messaging/Service/Handler/BlacklistEmailHandler.php +++ b/src/Bounce/Service/Handler/BlacklistEmailHandler.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use Symfony\Contracts\Translation\TranslatorInterface; class BlacklistEmailHandler implements BounceActionHandlerInterface diff --git a/src/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandler.php b/src/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandler.php similarity index 90% rename from src/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandler.php rename to src/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandler.php index 3fda46c2..7c997982 100644 --- a/src/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandler.php +++ b/src/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandler.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use Symfony\Contracts\Translation\TranslatorInterface; class BlacklistUserAndDeleteBounceHandler implements BounceActionHandlerInterface diff --git a/src/Domain/Messaging/Service/Handler/BlacklistUserHandler.php b/src/Bounce/Service/Handler/BlacklistUserHandler.php similarity index 92% rename from src/Domain/Messaging/Service/Handler/BlacklistUserHandler.php rename to src/Bounce/Service/Handler/BlacklistUserHandler.php index 555ad3bf..c5dd2fd5 100644 --- a/src/Domain/Messaging/Service/Handler/BlacklistUserHandler.php +++ b/src/Bounce/Service/Handler/BlacklistUserHandler.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use Symfony\Contracts\Translation\TranslatorInterface; class BlacklistUserHandler implements BounceActionHandlerInterface diff --git a/src/Domain/Messaging/Service/Handler/BounceActionHandlerInterface.php b/src/Bounce/Service/Handler/BounceActionHandlerInterface.php similarity index 76% rename from src/Domain/Messaging/Service/Handler/BounceActionHandlerInterface.php rename to src/Bounce/Service/Handler/BounceActionHandlerInterface.php index 6b90cb49..ce43f7c7 100644 --- a/src/Domain/Messaging/Service/Handler/BounceActionHandlerInterface.php +++ b/src/Bounce/Service/Handler/BounceActionHandlerInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; interface BounceActionHandlerInterface { diff --git a/src/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php b/src/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php similarity index 81% rename from src/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php rename to src/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php index 4b7471eb..fa09f4a0 100644 --- a/src/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php +++ b/src/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandler.php @@ -2,31 +2,27 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use Symfony\Contracts\Translation\TranslatorInterface; class DecreaseCountConfirmUserAndDeleteBounceHandler implements BounceActionHandlerInterface { private SubscriberHistoryManager $subscriberHistoryManager; - private SubscriberManager $subscriberManager; private BounceManager $bounceManager; private SubscriberRepository $subscriberRepository; private TranslatorInterface $translator; public function __construct( SubscriberHistoryManager $subscriberHistoryManager, - SubscriberManager $subscriberManager, BounceManager $bounceManager, SubscriberRepository $subscriberRepository, TranslatorInterface $translator, ) { $this->subscriberHistoryManager = $subscriberHistoryManager; - $this->subscriberManager = $subscriberManager; $this->bounceManager = $bounceManager; $this->subscriberRepository = $subscriberRepository; $this->translator = $translator; @@ -40,7 +36,7 @@ public function supports(string $action): bool public function handle(array $closureData): void { if (!empty($closureData['subscriber'])) { - $this->subscriberManager->decrementBounceCount($closureData['subscriber']); + $this->subscriberRepository->decrementBounceCount($closureData['subscriber']); if (!$closureData['confirmed']) { $this->subscriberRepository->markConfirmed($closureData['userId']); $this->subscriberHistoryManager->addHistory( diff --git a/src/Domain/Messaging/Service/Handler/DeleteBounceHandler.php b/src/Bounce/Service/Handler/DeleteBounceHandler.php similarity index 80% rename from src/Domain/Messaging/Service/Handler/DeleteBounceHandler.php rename to src/Bounce/Service/Handler/DeleteBounceHandler.php index 80c881a1..9bf0d93e 100644 --- a/src/Domain/Messaging/Service/Handler/DeleteBounceHandler.php +++ b/src/Bounce/Service/Handler/DeleteBounceHandler.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; class DeleteBounceHandler implements BounceActionHandlerInterface { diff --git a/src/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandler.php b/src/Bounce/Service/Handler/DeleteUserAndBounceHandler.php similarity index 87% rename from src/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandler.php rename to src/Bounce/Service/Handler/DeleteUserAndBounceHandler.php index d8887545..526f6968 100644 --- a/src/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandler.php +++ b/src/Bounce/Service/Handler/DeleteUserAndBounceHandler.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; class DeleteUserAndBounceHandler implements BounceActionHandlerInterface diff --git a/src/Domain/Messaging/Service/Handler/DeleteUserHandler.php b/src/Bounce/Service/Handler/DeleteUserHandler.php similarity index 94% rename from src/Domain/Messaging/Service/Handler/DeleteUserHandler.php rename to src/Bounce/Service/Handler/DeleteUserHandler.php index 64b1a073..88f9da8f 100644 --- a/src/Domain/Messaging/Service/Handler/DeleteUserHandler.php +++ b/src/Bounce/Service/Handler/DeleteUserHandler.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use Psr\Log\LoggerInterface; diff --git a/src/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php b/src/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php similarity index 93% rename from src/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php rename to src/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php index 0653900f..e13afb7a 100644 --- a/src/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php +++ b/src/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandler.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; use Symfony\Contracts\Translation\TranslatorInterface; diff --git a/src/Domain/Messaging/Service/Handler/UnconfirmUserHandler.php b/src/Bounce/Service/Handler/UnconfirmUserHandler.php similarity index 96% rename from src/Domain/Messaging/Service/Handler/UnconfirmUserHandler.php rename to src/Bounce/Service/Handler/UnconfirmUserHandler.php index 971863f3..bef028a6 100644 --- a/src/Domain/Messaging/Service/Handler/UnconfirmUserHandler.php +++ b/src/Bounce/Service/Handler/UnconfirmUserHandler.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Bounce\Service\Handler; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; diff --git a/src/Domain/Messaging/Service/LockService.php b/src/Bounce/Service/LockService.php similarity index 99% rename from src/Domain/Messaging/Service/LockService.php rename to src/Bounce/Service/LockService.php index d2f1eb34..c3948c1f 100644 --- a/src/Domain/Messaging/Service/LockService.php +++ b/src/Bounce/Service/LockService.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; use PhpList\Core\Domain\Messaging\Repository\SendProcessRepository; use PhpList\Core\Domain\Messaging\Service\Manager\SendProcessManager; diff --git a/src/Domain/Messaging/Service/Manager/BounceManager.php b/src/Bounce/Service/Manager/BounceManager.php similarity index 96% rename from src/Domain/Messaging/Service/Manager/BounceManager.php rename to src/Bounce/Service/Manager/BounceManager.php index 4945b881..230ad279 100644 --- a/src/Domain/Messaging/Service/Manager/BounceManager.php +++ b/src/Bounce/Service/Manager/BounceManager.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Manager; +namespace PhpList\Core\Bounce\Service\Manager; use DateTime; use DateTimeImmutable; @@ -53,7 +53,8 @@ public function create( comment: $comment ); - $this->bounceRepository->save($bounce); + $this->bounceRepository->persist($bounce); + $this->entityManager->flush(); return $bounce; } @@ -62,7 +63,7 @@ public function update(Bounce $bounce, ?string $status = null, ?string $comment { $bounce->setStatus($status); $bounce->setComment($comment); - $this->bounceRepository->save($bounce); + $this->entityManager->flush(); return $bounce; } @@ -70,6 +71,7 @@ public function update(Bounce $bounce, ?string $status = null, ?string $comment public function delete(Bounce $bounce): void { $this->bounceRepository->remove($bounce); + $this->entityManager->flush(); } /** @return Bounce[] */ @@ -94,7 +96,6 @@ public function linkUserMessageBounce( $userMessageBounce = new UserMessageBounce($bounce->getId(), new DateTime($date->format('Y-m-d H:i:s'))); $userMessageBounce->setUserId($subscriberId); $userMessageBounce->setMessageId($messageId); - $this->entityManager->flush(); return $userMessageBounce; } diff --git a/src/Domain/Messaging/Service/MessageParser.php b/src/Bounce/Service/MessageParser.php similarity index 98% rename from src/Domain/Messaging/Service/MessageParser.php rename to src/Bounce/Service/MessageParser.php index 14b4f952..336cbe02 100644 --- a/src/Domain/Messaging/Service/MessageParser.php +++ b/src/Bounce/Service/MessageParser.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; diff --git a/src/Domain/Messaging/Service/NativeBounceProcessingService.php b/src/Bounce/Service/NativeBounceProcessingService.php similarity index 90% rename from src/Domain/Messaging/Service/NativeBounceProcessingService.php rename to src/Bounce/Service/NativeBounceProcessingService.php index 0cdc7cb4..887aa94d 100644 --- a/src/Domain/Messaging/Service/NativeBounceProcessingService.php +++ b/src/Bounce/Service/NativeBounceProcessingService.php @@ -2,13 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; +use Doctrine\ORM\EntityManagerInterface; use IMAP\Connection; +use PhpList\Core\Bounce\Exception\OpenMboxFileException; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Processor\BounceDataProcessor; use PhpList\Core\Domain\Common\Mail\NativeImapMailReader; -use PhpList\Core\Domain\Messaging\Exception\OpenMboxFileException; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceDataProcessor; use Psr\Log\LoggerInterface; use Throwable; @@ -21,6 +22,7 @@ class NativeBounceProcessingService implements BounceProcessingServiceInterface private LoggerInterface $logger; private bool $purgeProcessed; private bool $purgeUnprocessed; + private EntityManagerInterface $entityManager; public function __construct( BounceManager $bounceManager, @@ -28,6 +30,7 @@ public function __construct( MessageParser $messageParser, BounceDataProcessor $bounceDataProcessor, LoggerInterface $logger, + EntityManagerInterface $entityManager, bool $purgeProcessed, bool $purgeUnprocessed ) { @@ -36,6 +39,7 @@ public function __construct( $this->messageParser = $messageParser; $this->bounceDataProcessor = $bounceDataProcessor; $this->logger = $logger; + $this->entityManager = $entityManager; $this->purgeProcessed = $purgeProcessed; $this->purgeUnprocessed = $purgeUnprocessed; } @@ -135,7 +139,7 @@ private function processImapBounce($link, int $num, string $header): bool $userId = $this->messageParser->findUserId($body); $bounce = $this->bounceManager->create($bounceDate, $header, $body); - + $this->entityManager->flush(); return $this->bounceDataProcessor->process($bounce, $msgId, $userId, $bounceDate); } } diff --git a/src/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessor.php b/src/Bounce/Service/Processor/AdvancedBounceRulesProcessor.php similarity index 95% rename from src/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessor.php rename to src/Bounce/Service/Processor/AdvancedBounceRulesProcessor.php index 0e1c3fe0..3d6fb116 100644 --- a/src/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessor.php +++ b/src/Bounce/Service/Processor/AdvancedBounceRulesProcessor.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; +use PhpList\Core\Bounce\Service\BounceActionResolver; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\BounceActionResolver; -use PhpList\Core\Domain\Subscription\Model\Subscriber; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Service\Manager\BounceRuleManager; +use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Contracts\Translation\TranslatorInterface; diff --git a/src/Domain/Messaging/Service/Processor/BounceDataProcessor.php b/src/Bounce/Service/Processor/BounceDataProcessor.php similarity index 93% rename from src/Domain/Messaging/Service/Processor/BounceDataProcessor.php rename to src/Bounce/Service/Processor/BounceDataProcessor.php index 7a33a7e9..d40707b3 100644 --- a/src/Domain/Messaging/Service/Processor/BounceDataProcessor.php +++ b/src/Bounce/Service/Processor/BounceDataProcessor.php @@ -2,13 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; use DateTimeImmutable; +use Doctrine\ORM\EntityManagerInterface; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; use PhpList\Core\Domain\Messaging\Model\BounceStatus; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; @@ -22,6 +23,7 @@ class BounceDataProcessor private readonly LoggerInterface $logger; private readonly SubscriberManager $subscriberManager; private readonly SubscriberHistoryManager $subscriberHistoryManager; + private EntityManagerInterface $entityManager; public function __construct( BounceManager $bounceManager, @@ -30,6 +32,7 @@ public function __construct( LoggerInterface $logger, SubscriberManager $subscriberManager, SubscriberHistoryManager $subscriberHistoryManager, + EntityManagerInterface $entityManager, ) { $this->bounceManager = $bounceManager; $this->subscriberRepository = $subscriberRepository; @@ -37,6 +40,7 @@ public function __construct( $this->logger = $logger; $this->subscriberManager = $subscriberManager; $this->subscriberHistoryManager = $subscriberHistoryManager; + $this->entityManager = $entityManager; } public function process(Bounce $bounce, ?string $msgId, ?int $userId, DateTimeImmutable $bounceDate): bool @@ -90,6 +94,7 @@ private function handleSystemMessageWithUser( comment: sprintf('%d marked unconfirmed', $userId) ); $this->bounceManager->linkUserMessageBounce(bounce: $bounce, date: $date, subscriberId: $userId); + $this->entityManager->flush(); $this->subscriberRepository->markUnconfirmed($userId); $this->logger->info('system message bounced, user marked unconfirmed', ['userId' => $userId]); @@ -129,6 +134,7 @@ private function handleKnownMessageAndUser( subscriberId: $userId, messageId: $msgId ); + $this->entityManager->flush(); $this->bounceManager->update( bounce: $bounce, status: BounceStatus::BouncedList->format($msgId), @@ -143,6 +149,7 @@ private function handleKnownMessageAndUser( subscriberId: $userId, messageId: $msgId ); + $this->entityManager->flush(); $this->bounceManager->update( bounce: $bounce, status: BounceStatus::DuplicateBounce->format($userId), diff --git a/src/Domain/Messaging/Service/Processor/BounceProtocolProcessor.php b/src/Bounce/Service/Processor/BounceProtocolProcessor.php similarity index 91% rename from src/Domain/Messaging/Service/Processor/BounceProtocolProcessor.php rename to src/Bounce/Service/Processor/BounceProtocolProcessor.php index a0e7d904..6bb77a49 100644 --- a/src/Domain/Messaging/Service/Processor/BounceProtocolProcessor.php +++ b/src/Bounce/Service/Processor/BounceProtocolProcessor.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Style\SymfonyStyle; diff --git a/src/Domain/Messaging/Service/Processor/MboxBounceProcessor.php b/src/Bounce/Service/Processor/MboxBounceProcessor.php similarity index 91% rename from src/Domain/Messaging/Service/Processor/MboxBounceProcessor.php rename to src/Bounce/Service/Processor/MboxBounceProcessor.php index d61742d5..b3f8c79b 100644 --- a/src/Domain/Messaging/Service/Processor/MboxBounceProcessor.php +++ b/src/Bounce/Service/Processor/MboxBounceProcessor.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; -use PhpList\Core\Domain\Messaging\Service\BounceProcessingServiceInterface; +use PhpList\Core\Bounce\Service\BounceProcessingServiceInterface; use RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Style\SymfonyStyle; diff --git a/src/Domain/Messaging/Service/Processor/PopBounceProcessor.php b/src/Bounce/Service/Processor/PopBounceProcessor.php similarity index 93% rename from src/Domain/Messaging/Service/Processor/PopBounceProcessor.php rename to src/Bounce/Service/Processor/PopBounceProcessor.php index b0079774..9ebb26c4 100644 --- a/src/Domain/Messaging/Service/Processor/PopBounceProcessor.php +++ b/src/Bounce/Service/Processor/PopBounceProcessor.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; -use PhpList\Core\Domain\Messaging\Service\BounceProcessingServiceInterface; +use PhpList\Core\Bounce\Service\BounceProcessingServiceInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Contracts\Translation\TranslatorInterface; diff --git a/src/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessor.php b/src/Bounce/Service/Processor/UnidentifiedBounceReprocessor.php similarity index 93% rename from src/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessor.php rename to src/Bounce/Service/Processor/UnidentifiedBounceReprocessor.php index 2646ede6..416684b2 100644 --- a/src/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessor.php +++ b/src/Bounce/Service/Processor/UnidentifiedBounceReprocessor.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Bounce\Service\Processor; use DateTimeImmutable; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\MessageParser; use PhpList\Core\Domain\Messaging\Model\BounceStatus; -use PhpList\Core\Domain\Messaging\Service\MessageParser; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Contracts\Translation\TranslatorInterface; diff --git a/src/Domain/Subscription/Service/SubscriberBlacklistService.php b/src/Bounce/Service/SubscriberBlacklistService.php similarity index 95% rename from src/Domain/Subscription/Service/SubscriberBlacklistService.php rename to src/Bounce/Service/SubscriberBlacklistService.php index 3a40f042..eee70215 100644 --- a/src/Domain/Subscription/Service/SubscriberBlacklistService.php +++ b/src/Bounce/Service/SubscriberBlacklistService.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Subscription\Service; +namespace PhpList\Core\Bounce\Service; use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Subscription\Model\Subscriber; @@ -41,6 +41,7 @@ public function blacklist(Subscriber $subscriber, string $reason): void $subscriber->setBlacklisted(true); $this->entityManager->flush(); $this->blacklistManager->addEmailToBlacklist($subscriber->getEmail(), $reason); + $this->entityManager->flush(); foreach (['REMOTE_ADDR','HTTP_X_FORWARDED_FOR'] as $item) { $request = $this->requestStack->getCurrentRequest(); @@ -53,6 +54,7 @@ public function blacklist(Subscriber $subscriber, string $reason): void name: $item, data: $request->server->get($item) ); + $this->entityManager->flush(); } } diff --git a/src/Domain/Messaging/Service/WebklexBounceProcessingService.php b/src/Bounce/Service/WebklexBounceProcessingService.php similarity index 97% rename from src/Domain/Messaging/Service/WebklexBounceProcessingService.php rename to src/Bounce/Service/WebklexBounceProcessingService.php index 09a1c14a..4ca20461 100644 --- a/src/Domain/Messaging/Service/WebklexBounceProcessingService.php +++ b/src/Bounce/Service/WebklexBounceProcessingService.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; use DateTimeImmutable; use DateTimeInterface; -use PhpList\Core\Domain\Messaging\Exception\ImapConnectionException; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceDataProcessor; +use PhpList\Core\Bounce\Exception\ImapConnectionException; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Processor\BounceDataProcessor; use Psr\Log\LoggerInterface; use Throwable; use Webklex\PHPIMAP\Client; diff --git a/src/Domain/Messaging/Service/WebklexImapClientFactory.php b/src/Bounce/Service/WebklexImapClientFactory.php similarity index 97% rename from src/Domain/Messaging/Service/WebklexImapClientFactory.php rename to src/Bounce/Service/WebklexImapClientFactory.php index 10271e4c..48fc26bc 100644 --- a/src/Domain/Messaging/Service/WebklexImapClientFactory.php +++ b/src/Bounce/Service/WebklexImapClientFactory.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service; +namespace PhpList\Core\Bounce\Service; use Webklex\PHPIMAP\Client; use Webklex\PHPIMAP\ClientManager; diff --git a/src/Core/BounceProcessorPass.php b/src/Core/BounceProcessorPass.php index 2ab5c9c5..6ec27dae 100644 --- a/src/Core/BounceProcessorPass.php +++ b/src/Core/BounceProcessorPass.php @@ -4,9 +4,9 @@ namespace PhpList\Core\Core; -use PhpList\Core\Domain\Messaging\Service\BounceProcessingServiceInterface; -use PhpList\Core\Domain\Messaging\Service\NativeBounceProcessingService; -use PhpList\Core\Domain\Messaging\Service\WebklexBounceProcessingService; +use PhpList\Core\Bounce\Service\BounceProcessingServiceInterface; +use PhpList\Core\Bounce\Service\NativeBounceProcessingService; +use PhpList\Core\Bounce\Service\WebklexBounceProcessingService; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/src/Domain/Analytics/Service/LinkTrackService.php b/src/Domain/Analytics/Service/LinkTrackService.php index 75242104..ad2df206 100644 --- a/src/Domain/Analytics/Service/LinkTrackService.php +++ b/src/Domain/Analytics/Service/LinkTrackService.php @@ -72,7 +72,7 @@ public function extractAndSaveLinks(Message $message, int $userId): array $linkTrack->setUserId($userId); $linkTrack->setUrl($url); - $this->linkTrackRepository->save($linkTrack); + $this->linkTrackRepository->persist($linkTrack); $savedLinks[] = $linkTrack; } diff --git a/src/Domain/Common/Repository/AbstractRepository.php b/src/Domain/Common/Repository/AbstractRepository.php index 284ef544..bfefd054 100644 --- a/src/Domain/Common/Repository/AbstractRepository.php +++ b/src/Domain/Common/Repository/AbstractRepository.php @@ -31,6 +31,11 @@ public function save(DomainModel $model): void $this->getEntityManager()->flush(); } + public function persist(DomainModel $model): void + { + $this->getEntityManager()->persist($model); + } + /** * Removes $model and flushes the entity manager change list. * @@ -41,9 +46,14 @@ public function save(DomainModel $model): void * * @return void */ - public function remove(DomainModel $model): void + public function delete(DomainModel $model): void { $this->getEntityManager()->remove($model); $this->getEntityManager()->flush(); } + + public function remove(DomainModel $model): void + { + $this->getEntityManager()->remove($model); + } } diff --git a/src/Domain/Configuration/Service/Manager/ConfigManager.php b/src/Domain/Configuration/Service/Manager/ConfigManager.php index cae380be..a61aa7d2 100644 --- a/src/Domain/Configuration/Service/Manager/ConfigManager.php +++ b/src/Domain/Configuration/Service/Manager/ConfigManager.php @@ -45,8 +45,6 @@ public function update(Config $config, string $value): void throw new ConfigNotEditableException($config->getKey()); } $config->setValue($value); - - $this->configRepository->save($config); } public function create(string $key, string $value, bool $editable, ?string $type = null): void @@ -57,7 +55,7 @@ public function create(string $key, string $value, bool $editable, ?string $type ->setEditable($editable) ->setType($type); - $this->configRepository->save($config); + $this->configRepository->persist($config); } public function delete(Config $config): void diff --git a/src/Domain/Identity/Command/CleanUpOldSessionTokens.php b/src/Domain/Identity/Command/CleanUpOldSessionTokens.php index 364d5ea9..820db648 100644 --- a/src/Domain/Identity/Command/CleanUpOldSessionTokens.php +++ b/src/Domain/Identity/Command/CleanUpOldSessionTokens.php @@ -4,6 +4,7 @@ namespace PhpList\Core\Domain\Identity\Command; +use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Identity\Repository\AdministratorTokenRepository; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -18,11 +19,13 @@ class CleanUpOldSessionTokens extends Command { private AdministratorTokenRepository $tokenRepository; + private EntityManagerInterface $entityManager; - public function __construct(AdministratorTokenRepository $tokenRepository) + public function __construct(AdministratorTokenRepository $tokenRepository, EntityManagerInterface $entityManager) { parent::__construct(); $this->tokenRepository = $tokenRepository; + $this->entityManager = $entityManager; } /** @@ -31,7 +34,17 @@ public function __construct(AdministratorTokenRepository $tokenRepository) protected function execute(InputInterface $input, OutputInterface $output): int { try { - $deletedCount = $this->tokenRepository->removeExpired(); + $expiredTokens = $this->tokenRepository->getExpired(); + + $deletedCount = 0; + + foreach ($expiredTokens as $token) { + $this->entityManager->remove($token); + $deletedCount++; + } + + $this->entityManager->flush(); + $output->writeln(sprintf('Successfully removed %d expired session token(s).', $deletedCount)); } catch (Throwable $throwable) { $output->writeln(sprintf('Error removing expired session tokens: %s', $throwable->getMessage())); diff --git a/src/Domain/Identity/Repository/AdministratorTokenRepository.php b/src/Domain/Identity/Repository/AdministratorTokenRepository.php index fef697cd..811f3bd1 100644 --- a/src/Domain/Identity/Repository/AdministratorTokenRepository.php +++ b/src/Domain/Identity/Repository/AdministratorTokenRepository.php @@ -8,6 +8,7 @@ use DateTimeImmutable; use DateTimeZone; use Doctrine\Common\Collections\Criteria; +use Exception; use PhpList\Core\Domain\Common\Repository\AbstractRepository; use PhpList\Core\Domain\Common\Repository\CursorPaginationTrait; use PhpList\Core\Domain\Common\Repository\Interfaces\PaginatableRepositoryInterface; @@ -45,31 +46,19 @@ public function findOneUnexpiredByKey(string $key): ?AdministratorToken } /** - * Removes all expired tokens. + * Get all expired tokens. * - * This method should be called regularly to clean up the tokens. - * - * @return int the number of removed tokens + * @return AdministratorToken[] + * @throws Exception */ - public function removeExpired(): int + public function getExpired(): array { $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); - $expiredTokens = $this->createQueryBuilder('at') + return $this->createQueryBuilder('at') ->where('at.expiry <= :date') ->setParameter('date', $now) ->getQuery() ->getResult(); - - $deletedCount = 0; - - foreach ($expiredTokens as $token) { - $this->getEntityManager()->remove($token); - $deletedCount++; - } - - $this->getEntityManager()->flush(); - - return $deletedCount; } } diff --git a/src/Domain/Identity/Service/AdminAttributeDefinitionManager.php b/src/Domain/Identity/Service/AdminAttributeDefinitionManager.php index 24a70de8..e868cbc4 100644 --- a/src/Domain/Identity/Service/AdminAttributeDefinitionManager.php +++ b/src/Domain/Identity/Service/AdminAttributeDefinitionManager.php @@ -45,7 +45,7 @@ public function create(AdminAttributeDefinitionDto $attributeDefinitionDto): Adm ->setDefaultValue($attributeDefinitionDto->defaultValue) ->setTableName($attributeDefinitionDto->tableName); - $this->definitionRepository->save($attributeDefinition); + $this->definitionRepository->persist($attributeDefinition); return $attributeDefinition; } @@ -68,8 +68,6 @@ public function update( ->setDefaultValue($attributeDefinitionDto->defaultValue) ->setTableName($attributeDefinitionDto->tableName); - $this->definitionRepository->save($attributeDefinition); - return $attributeDefinition; } diff --git a/src/Domain/Identity/Service/AdminAttributeManager.php b/src/Domain/Identity/Service/AdminAttributeManager.php index b5cb13f5..53fa330e 100644 --- a/src/Domain/Identity/Service/AdminAttributeManager.php +++ b/src/Domain/Identity/Service/AdminAttributeManager.php @@ -39,7 +39,7 @@ public function createOrUpdate( } $adminAttribute->setValue($value); - $this->attributeRepository->save($adminAttribute); + $this->attributeRepository->persist($adminAttribute); return $adminAttribute; } diff --git a/src/Domain/Identity/Service/AdministratorManager.php b/src/Domain/Identity/Service/AdministratorManager.php index 82d3d36f..814557a1 100644 --- a/src/Domain/Identity/Service/AdministratorManager.php +++ b/src/Domain/Identity/Service/AdministratorManager.php @@ -32,7 +32,6 @@ public function createAdministrator(CreateAdministratorDto $dto): Administrator $administrator->setPrivilegesFromArray($dto->privileges); $this->entityManager->persist($administrator); - $this->entityManager->flush(); return $administrator; } @@ -53,13 +52,10 @@ public function updateAdministrator(Administrator $administrator, UpdateAdminist $administrator->setPasswordHash($hashedPassword); } $administrator->setPrivilegesFromArray($dto->privileges); - - $this->entityManager->flush(); } public function deleteAdministrator(Administrator $administrator): void { $this->entityManager->remove($administrator); - $this->entityManager->flush(); } } diff --git a/src/Domain/Identity/Service/PasswordManager.php b/src/Domain/Identity/Service/PasswordManager.php index 36c88570..35d5d1ff 100644 --- a/src/Domain/Identity/Service/PasswordManager.php +++ b/src/Domain/Identity/Service/PasswordManager.php @@ -65,7 +65,7 @@ public function generatePasswordResetToken(string $email): string $expiryDate = new DateTime(self::TOKEN_EXPIRY); $passwordRequest = new AdminPasswordRequest(date: $expiryDate, admin: $administrator, keyValue: $token); - $this->passwordRequestRepository->save($passwordRequest); + $this->passwordRequestRepository->persist($passwordRequest); $message = new PasswordResetMessage(email: $email, token: $token); $this->messageBus->dispatch($message); @@ -113,7 +113,7 @@ public function updatePasswordWithToken(string $token, string $newPassword): boo $passwordHash = $this->hashGenerator->createPasswordHash($newPassword); $administrator->setPasswordHash($passwordHash); - $this->administratorRepository->save($administrator); + $this->administratorRepository->persist($administrator); $passwordRequest = $this->passwordRequestRepository->findOneByToken($token); $this->passwordRequestRepository->remove($passwordRequest); diff --git a/src/Domain/Identity/Service/SessionManager.php b/src/Domain/Identity/Service/SessionManager.php index 105d3645..658799f7 100644 --- a/src/Domain/Identity/Service/SessionManager.php +++ b/src/Domain/Identity/Service/SessionManager.php @@ -51,7 +51,7 @@ public function createSession(string $loginName, string $password): Administrato $token->setAdministrator($administrator); $token->generateExpiry(); $token->generateKey(); - $this->tokenRepository->save($token); + $this->tokenRepository->persist($token); return $token; } diff --git a/src/Domain/Messaging/Command/ProcessQueueCommand.php b/src/Domain/Messaging/Command/ProcessQueueCommand.php index 7ed9c0b5..600246cb 100644 --- a/src/Domain/Messaging/Command/ProcessQueueCommand.php +++ b/src/Domain/Messaging/Command/ProcessQueueCommand.php @@ -5,20 +5,25 @@ namespace PhpList\Core\Domain\Messaging\Command; use DateTimeImmutable; +use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Configuration\Model\ConfigOption; use PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider; +use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Model\Message\MessageStatus; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Messaging\Service\MessageProcessingPreparator; -use PhpList\Core\Domain\Messaging\Service\Processor\CampaignProcessor; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Lock\LockFactory; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Throwable; +/** + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") + */ #[AsCommand( name: 'phplist:process-queue', description: 'Processes the email campaign queue.' @@ -28,25 +33,28 @@ class ProcessQueueCommand extends Command private MessageRepository $messageRepository; private LockFactory $lockFactory; private MessageProcessingPreparator $messagePreparator; - private CampaignProcessor $campaignProcessor; + private MessageBusInterface $messageBus; private ConfigProvider $configProvider; private TranslatorInterface $translator; + private EntityManagerInterface $entityManager; public function __construct( MessageRepository $messageRepository, LockFactory $lockFactory, MessageProcessingPreparator $messagePreparator, - CampaignProcessor $campaignProcessor, + MessageBusInterface $messageBus, ConfigProvider $configProvider, - TranslatorInterface $translator + TranslatorInterface $translator, + EntityManagerInterface $entityManager, ) { parent::__construct(); $this->messageRepository = $messageRepository; $this->lockFactory = $lockFactory; $this->messagePreparator = $messagePreparator; - $this->campaignProcessor = $campaignProcessor; + $this->messageBus = $messageBus; $this->configProvider = $configProvider; $this->translator = $translator; + $this->entityManager = $entityManager; } /** @@ -73,13 +81,22 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->messagePreparator->ensureSubscribersHaveUuid($output); $this->messagePreparator->ensureCampaignsHaveUuid($output); - $campaigns = $this->messageRepository->getByStatusAndEmbargo( - status: MessageStatus::Submitted, - embargo: new DateTimeImmutable() - ); + $this->entityManager->flush(); + } catch (Throwable $throwable) { + $output->writeln($throwable->getMessage()); + $lock->release(); + return Command::FAILURE; + } + + $campaigns = $this->messageRepository->getByStatusAndEmbargo( + status: MessageStatus::Submitted, + embargo: new DateTimeImmutable() + ); + + try { foreach ($campaigns as $campaign) { - $this->campaignProcessor->process($campaign, $output); + $this->messageBus->dispatch(new CampaignProcessorMessage(messageId: $campaign->getId())); } } catch (Throwable $throwable) { $output->writeln($throwable->getMessage()); diff --git a/src/Domain/Messaging/Message/CampaignProcessorMessage.php b/src/Domain/Messaging/Message/CampaignProcessorMessage.php new file mode 100644 index 00000000..e7680a44 --- /dev/null +++ b/src/Domain/Messaging/Message/CampaignProcessorMessage.php @@ -0,0 +1,20 @@ +messageId = $messageId; + } + + public function getMessageId(): int + { + return $this->messageId; + } +} diff --git a/src/Domain/Messaging/Message/SyncCampaignProcessorMessage.php b/src/Domain/Messaging/Message/SyncCampaignProcessorMessage.php new file mode 100644 index 00000000..05be675f --- /dev/null +++ b/src/Domain/Messaging/Message/SyncCampaignProcessorMessage.php @@ -0,0 +1,20 @@ +messageId = $messageId; + } + + public function getMessageId(): int + { + return $this->messageId; + } +} diff --git a/src/Domain/Messaging/Service/Processor/CampaignProcessor.php b/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php similarity index 59% rename from src/Domain/Messaging/Service/Processor/CampaignProcessor.php rename to src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php index e16d4246..82e1e664 100644 --- a/src/Domain/Messaging/Service/Processor/CampaignProcessor.php +++ b/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php @@ -2,23 +2,26 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Domain\Messaging\MessageHandler; use Doctrine\ORM\EntityManagerInterface; +use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; +use PhpList\Core\Domain\Messaging\Message\SyncCampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Model\Message; -use PhpList\Core\Domain\Messaging\Model\UserMessage; -use PhpList\Core\Domain\Messaging\Model\Message\UserMessageStatus; use PhpList\Core\Domain\Messaging\Model\Message\MessageStatus; +use PhpList\Core\Domain\Messaging\Model\Message\UserMessageStatus; +use PhpList\Core\Domain\Messaging\Model\UserMessage; +use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Messaging\Repository\UserMessageRepository; use PhpList\Core\Domain\Messaging\Service\Handler\RequeueHandler; -use PhpList\Core\Domain\Messaging\Service\RateLimitedCampaignMailer; use PhpList\Core\Domain\Messaging\Service\MaxProcessTimeLimiter; use PhpList\Core\Domain\Messaging\Service\MessageProcessingPreparator; +use PhpList\Core\Domain\Messaging\Service\RateLimitedCampaignMailer; +use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; use PhpList\Core\Domain\Subscription\Service\Provider\SubscriberProvider; -use PhpList\Core\Domain\Subscription\Model\Subscriber; use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Contracts\Translation\TranslatorInterface; use Throwable; @@ -27,7 +30,8 @@ * @SuppressWarnings(PHPMD.StaticAccess) * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ -class CampaignProcessor +#[AsMessageHandler] +class CampaignProcessorMessageHandler { private RateLimitedCampaignMailer $mailer; private EntityManagerInterface $entityManager; @@ -39,6 +43,7 @@ class CampaignProcessor private RequeueHandler $requeueHandler; private TranslatorInterface $translator; private SubscriberHistoryManager $subscriberHistoryManager; + private MessageRepository $messageRepository; public function __construct( RateLimitedCampaignMailer $mailer, @@ -51,6 +56,7 @@ public function __construct( RequeueHandler $requeueHandler, TranslatorInterface $translator, SubscriberHistoryManager $subscriberHistoryManager, + MessageRepository $messageRepository, ) { $this->mailer = $mailer; $this->entityManager = $entityManager; @@ -62,10 +68,21 @@ public function __construct( $this->requeueHandler = $requeueHandler; $this->translator = $translator; $this->subscriberHistoryManager = $subscriberHistoryManager; + $this->messageRepository = $messageRepository; } - public function process(Message $campaign, ?OutputInterface $output = null): void + public function __invoke(CampaignProcessorMessage|SyncCampaignProcessorMessage $message): void { + $campaign = $this->messageRepository->findByIdAndStatus($message->getMessageId(), MessageStatus::Submitted); + if (!$campaign) { + $this->logger->warning( + $this->translator->trans('Campaign not found or not in submitted status'), + ['campaign_id' => $message->getMessageId()] + ); + + return; + } + $this->updateMessageStatus($campaign, MessageStatus::Prepared); $subscribers = $this->subscriberProvider->getSubscribersForMessage($campaign); @@ -75,7 +92,7 @@ public function process(Message $campaign, ?OutputInterface $output = null): voi $stoppedEarly = false; foreach ($subscribers as $subscriber) { - if ($this->timeLimiter->shouldStop($output)) { + if ($this->timeLimiter->shouldStop()) { $stoppedEarly = true; break; } @@ -90,41 +107,16 @@ public function process(Message $campaign, ?OutputInterface $output = null): voi $this->userMessageRepository->save($userMessage); if (!filter_var($subscriber->getEmail(), FILTER_VALIDATE_EMAIL)) { - $this->updateUserMessageStatus($userMessage, UserMessageStatus::InvalidEmailAddress); - $this->unconfirmSubscriber($subscriber); - $output?->writeln($this->translator->trans('Invalid email, marking unconfirmed: %email%', [ - '%email%' => $subscriber->getEmail(), - ])); - $this->subscriberHistoryManager->addHistory( - subscriber: $subscriber, - message: $this->translator->trans('Subscriber marked unconfirmed for invalid email address'), - details: $this->translator->trans( - 'Marked unconfirmed while sending campaign %message_id%', - ['%message_id%' => $campaign->getId()] - ) - ); + $this->handleInvalidEmail($userMessage, $subscriber, $campaign); + $this->entityManager->flush(); continue; } - $processed = $this->messagePreparator->processMessageLinks($campaign, $subscriber->getId()); - - try { - $email = $this->mailer->composeEmail($processed, $subscriber); - $this->mailer->send($email); - $this->updateUserMessageStatus($userMessage, UserMessageStatus::Sent); - } catch (Throwable $e) { - $this->updateUserMessageStatus($userMessage, UserMessageStatus::NotSent); - $this->logger->error($e->getMessage(), [ - 'subscriber_id' => $subscriber->getId(), - 'campaign_id' => $campaign->getId(), - ]); - $output?->writeln($this->translator->trans('Failed to send to: %email%', [ - '%email%' => $subscriber->getEmail(), - ])); - } + $this->handleEmailSending($campaign, $subscriber, $userMessage); } - if ($stoppedEarly && $this->requeueHandler->handle($campaign, $output)) { + if ($stoppedEarly && $this->requeueHandler->handle($campaign)) { + $this->entityManager->flush(); return; } @@ -150,4 +142,41 @@ private function updateUserMessageStatus(UserMessage $userMessage, UserMessageSt $userMessage->setStatus($status); $this->entityManager->flush(); } + + private function handleInvalidEmail(UserMessage $userMessage, Subscriber $subscriber, mixed $campaign): void + { + $this->updateUserMessageStatus($userMessage, UserMessageStatus::InvalidEmailAddress); + $this->unconfirmSubscriber($subscriber); + $this->logger->warning($this->translator->trans('Invalid email, marking unconfirmed: %email%', [ + '%email%' => $subscriber->getEmail(), + ])); + $this->subscriberHistoryManager->addHistory( + subscriber: $subscriber, + message: $this->translator->trans('Subscriber marked unconfirmed for invalid email address'), + details: $this->translator->trans( + 'Marked unconfirmed while sending campaign %message_id%', + ['%message_id%' => $campaign->getId()] + ) + ); + } + + private function handleEmailSending(mixed $campaign, Subscriber $subscriber, UserMessage $userMessage): void + { + $processed = $this->messagePreparator->processMessageLinks($campaign, $subscriber->getId()); + + try { + $email = $this->mailer->composeEmail($processed, $subscriber); + $this->mailer->send($email); + $this->updateUserMessageStatus($userMessage, UserMessageStatus::Sent); + } catch (Throwable $e) { + $this->updateUserMessageStatus($userMessage, UserMessageStatus::NotSent); + $this->logger->error($e->getMessage(), [ + 'subscriber_id' => $subscriber->getId(), + 'campaign_id' => $campaign->getId(), + ]); + $this->logger->warning($this->translator->trans('Failed to send to: %email%', [ + '%email%' => $subscriber->getEmail(), + ])); + } + } } diff --git a/src/Domain/Messaging/Repository/MessageRepository.php b/src/Domain/Messaging/Repository/MessageRepository.php index 0ae8bc18..30d5f1fd 100644 --- a/src/Domain/Messaging/Repository/MessageRepository.php +++ b/src/Domain/Messaging/Repository/MessageRepository.php @@ -69,7 +69,7 @@ public function incrementBounceCount(int $messageId): void { $this->createQueryBuilder('m') ->update() - ->set('m.bounceCount', 'm.bounceCount + 1') + ->set('m.metadata.bounceCount', 'm.bounceCount + 1') ->where('m.id = :messageId') ->setParameter('messageId', $messageId) ->getQuery() @@ -79,11 +79,22 @@ public function incrementBounceCount(int $messageId): void public function getByStatusAndEmbargo(Message\MessageStatus $status, DateTimeImmutable $embargo): array { return $this->createQueryBuilder('m') - ->where('m.status = :status') - ->andWhere('m.embargo IS NULL OR m.embargo <= :embargo') + ->where('m.metadata.status = :status') + ->andWhere('m.schedule.embargo IS NULL OR m.embargo <= :embargo') ->setParameter('status', $status->value) ->setParameter('embargo', $embargo) ->getQuery() ->getResult(); } + + public function findByIdAndStatus(int $id, Message\MessageStatus $status) + { + return $this->createQueryBuilder('m') + ->where('m.id = :id') + ->andWhere('m.metadata.status = :status') + ->setParameter('id', $id) + ->setParameter('status', $status->value) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/Domain/Messaging/Service/Handler/RequeueHandler.php b/src/Domain/Messaging/Service/Handler/RequeueHandler.php index ddd0035d..3fbca634 100644 --- a/src/Domain/Messaging/Service/Handler/RequeueHandler.php +++ b/src/Domain/Messaging/Service/Handler/RequeueHandler.php @@ -6,7 +6,6 @@ use DateInterval; use DateTime; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Model\Message\MessageStatus; use Psr\Log\LoggerInterface; @@ -17,7 +16,6 @@ class RequeueHandler { public function __construct( private readonly LoggerInterface $logger, - private readonly EntityManagerInterface $entityManager, private readonly TranslatorInterface $translator, ) { } @@ -46,7 +44,6 @@ public function handle(Message $campaign, ?OutputInterface $output = null): bool $schedule->setEmbargo($next); $campaign->setSchedule($schedule); $campaign->getMetadata()->setStatus(MessageStatus::Submitted); - $this->entityManager->flush(); $output?->writeln($this->translator->trans( 'Requeued campaign; next embargo at %time%', diff --git a/src/Domain/Messaging/Service/Manager/BounceRegexManager.php b/src/Domain/Messaging/Service/Manager/BounceRegexManager.php index c9d60580..3ebcc539 100644 --- a/src/Domain/Messaging/Service/Manager/BounceRegexManager.php +++ b/src/Domain/Messaging/Service/Manager/BounceRegexManager.php @@ -46,8 +46,6 @@ public function createOrUpdateFromPattern( ->setComment($comment ?? $existing->getComment()) ->setStatus($status ?? $existing->getStatus()); - $this->bounceRegexRepository->save($existing); - return $existing; } @@ -62,7 +60,7 @@ public function createOrUpdateFromPattern( count: 0 ); - $this->bounceRegexRepository->save($bounceRegex); + $this->bounceRegexRepository->persist($bounceRegex); return $bounceRegex; } @@ -92,7 +90,6 @@ public function associateBounce(BounceRegex $regex, Bounce $bounce): BounceRegex $this->entityManager->persist($relation); $regex->setCount(($regex->getCount() ?? 0) + 1); - $this->entityManager->flush(); return $relation; } diff --git a/src/Domain/Messaging/Service/Manager/ListMessageManager.php b/src/Domain/Messaging/Service/Manager/ListMessageManager.php index 22176113..c481e5f8 100644 --- a/src/Domain/Messaging/Service/Manager/ListMessageManager.php +++ b/src/Domain/Messaging/Service/Manager/ListMessageManager.php @@ -43,7 +43,6 @@ public function associateMessageWithList(Message $message, SubscriberList $subsc $listMessage->setEntered(new DateTime()); $this->entityManager->persist($listMessage); - $this->entityManager->flush(); return $listMessage; } diff --git a/src/Domain/Messaging/Service/Manager/MessageManager.php b/src/Domain/Messaging/Service/Manager/MessageManager.php index c73f31ca..c11d34d9 100644 --- a/src/Domain/Messaging/Service/Manager/MessageManager.php +++ b/src/Domain/Messaging/Service/Manager/MessageManager.php @@ -26,7 +26,7 @@ public function createMessage(MessageDtoInterface $createMessageDto, Administrat { $context = new MessageContext($authUser); $message = $this->messageBuilder->build($createMessageDto, $context); - $this->messageRepository->save($message); + $this->messageRepository->persist($message); return $message; } @@ -37,16 +37,12 @@ public function updateMessage( Administrator $authUser ): Message { $context = new MessageContext($authUser, $message); - $message = $this->messageBuilder->build($updateMessageDto, $context); - $this->messageRepository->save($message); - - return $message; + return $this->messageBuilder->build($updateMessageDto, $context); } public function updateStatus(Message $message, Message\MessageStatus $status): Message { $message->getMetadata()->setStatus($status); - $this->messageRepository->save($message); return $message; } diff --git a/src/Domain/Messaging/Service/Manager/SendProcessManager.php b/src/Domain/Messaging/Service/Manager/SendProcessManager.php index 0100ed29..23d16761 100644 --- a/src/Domain/Messaging/Service/Manager/SendProcessManager.php +++ b/src/Domain/Messaging/Service/Manager/SendProcessManager.php @@ -29,7 +29,6 @@ public function create(string $page, string $processIdentifier): SendProcess $sendProcess->setPage($page); $this->entityManager->persist($sendProcess); - $this->entityManager->flush(); return $sendProcess; } diff --git a/src/Domain/Messaging/Service/Manager/TemplateImageManager.php b/src/Domain/Messaging/Service/Manager/TemplateImageManager.php index 30705715..68b04f40 100644 --- a/src/Domain/Messaging/Service/Manager/TemplateImageManager.php +++ b/src/Domain/Messaging/Service/Manager/TemplateImageManager.php @@ -50,8 +50,6 @@ public function createImagesFromImagePaths(array $imagePaths, Template $template $templateImages[] = $image; } - $this->entityManager->flush(); - return $templateImages; } diff --git a/src/Domain/Messaging/Service/Manager/TemplateManager.php b/src/Domain/Messaging/Service/Manager/TemplateManager.php index 7de31843..80447d8b 100644 --- a/src/Domain/Messaging/Service/Manager/TemplateManager.php +++ b/src/Domain/Messaging/Service/Manager/TemplateManager.php @@ -4,7 +4,6 @@ namespace PhpList\Core\Domain\Messaging\Service\Manager; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Common\Model\ValidationContext; use PhpList\Core\Domain\Messaging\Model\Dto\CreateTemplateDto; use PhpList\Core\Domain\Messaging\Model\Template; @@ -17,20 +16,17 @@ class TemplateManager { private TemplateRepository $templateRepository; - private EntityManagerInterface $entityManager; private TemplateImageManager $templateImageManager; private TemplateLinkValidator $templateLinkValidator; private TemplateImageValidator $templateImageValidator; public function __construct( TemplateRepository $templateRepository, - EntityManagerInterface $entityManager, TemplateImageManager $templateImageManager, TemplateLinkValidator $templateLinkValidator, TemplateImageValidator $templateImageValidator ) { $this->templateRepository = $templateRepository; - $this->entityManager = $entityManager; $this->templateImageManager = $templateImageManager; $this->templateLinkValidator = $templateLinkValidator; $this->templateImageValidator = $templateImageValidator; @@ -56,7 +52,7 @@ public function create(CreateTemplateDto $createTemplateDto): Template $imageUrls = $this->templateImageManager->extractAllImages($template->getContent() ?? ''); $this->templateImageValidator->validate($imageUrls, $context); - $this->templateRepository->save($template); + $this->templateRepository->persist($template); $this->templateImageManager->createImagesFromImagePaths($imageUrls, $template); @@ -75,8 +71,6 @@ public function update(UpdateSubscriberDto $updateSubscriberDto): Subscriber $subscriber->setDisabled($updateSubscriberDto->disabled); $subscriber->setExtraData($updateSubscriberDto->additionalData); - $this->entityManager->flush(); - return $subscriber; } diff --git a/src/Domain/Messaging/Service/MessageProcessingPreparator.php b/src/Domain/Messaging/Service/MessageProcessingPreparator.php index 9faa72fb..5255914d 100644 --- a/src/Domain/Messaging/Service/MessageProcessingPreparator.php +++ b/src/Domain/Messaging/Service/MessageProcessingPreparator.php @@ -4,7 +4,6 @@ namespace PhpList\Core\Domain\Messaging\Service; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Analytics\Service\LinkTrackService; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; @@ -17,20 +16,17 @@ class MessageProcessingPreparator // phpcs:ignore Generic.Commenting.Todo // @todo: create functionality to track public const LINT_TRACK_ENDPOINT = '/api/v2/link-track'; - private EntityManagerInterface $entityManager; private SubscriberRepository $subscriberRepository; private MessageRepository $messageRepository; private LinkTrackService $linkTrackService; private TranslatorInterface $translator; public function __construct( - EntityManagerInterface $entityManager, SubscriberRepository $subscriberRepository, MessageRepository $messageRepository, LinkTrackService $linkTrackService, TranslatorInterface $translator, ) { - $this->entityManager = $entityManager; $this->subscriberRepository = $subscriberRepository; $this->messageRepository = $messageRepository; $this->linkTrackService = $linkTrackService; @@ -49,7 +45,6 @@ public function ensureSubscribersHaveUuid(OutputInterface $output): void foreach ($subscribersWithoutUuid as $subscriber) { $subscriber->setUniqueId(bin2hex(random_bytes(16))); } - $this->entityManager->flush(); } } @@ -65,7 +60,6 @@ public function ensureCampaignsHaveUuid(OutputInterface $output): void foreach ($campaignsWithoutUuid as $campaign) { $campaign->setUuid(bin2hex(random_bytes(18))); } - $this->entityManager->flush(); } } diff --git a/src/Domain/Subscription/Repository/SubscriberRepository.php b/src/Domain/Subscription/Repository/SubscriberRepository.php index 3c3583b4..2ea02474 100644 --- a/src/Domain/Subscription/Repository/SubscriberRepository.php +++ b/src/Domain/Subscription/Repository/SubscriberRepository.php @@ -188,4 +188,15 @@ public function distinctUsersWithBouncesConfirmedNotBlacklisted(): array ->getQuery() ->getScalarResult(); } + + public function decrementBounceCount(Subscriber $subscriber): void + { + $this->createQueryBuilder('s') + ->update() + ->set('s.bounceCount', 's.bounceCount - 1') + ->where('s.id = :subscriberId') + ->setParameter('subscriberId', $subscriber->getId()) + ->getQuery() + ->execute(); + } } diff --git a/src/Domain/Subscription/Service/Manager/AttributeDefinitionManager.php b/src/Domain/Subscription/Service/Manager/AttributeDefinitionManager.php index d91956c6..5f95640d 100644 --- a/src/Domain/Subscription/Service/Manager/AttributeDefinitionManager.php +++ b/src/Domain/Subscription/Service/Manager/AttributeDefinitionManager.php @@ -46,7 +46,7 @@ public function create(AttributeDefinitionDto $attributeDefinitionDto): Subscrib ->setDefaultValue($attributeDefinitionDto->defaultValue) ->setTableName($attributeDefinitionDto->tableName); - $this->definitionRepository->save($attributeDefinition); + $this->definitionRepository->persist($attributeDefinition); return $attributeDefinition; } @@ -72,8 +72,6 @@ public function update( ->setDefaultValue($attributeDefinitionDto->defaultValue) ->setTableName($attributeDefinitionDto->tableName); - $this->definitionRepository->save($attributeDefinition); - return $attributeDefinition; } diff --git a/src/Domain/Subscription/Service/Manager/SubscribePageManager.php b/src/Domain/Subscription/Service/Manager/SubscribePageManager.php index b0017e6c..485041a5 100644 --- a/src/Domain/Subscription/Service/Manager/SubscribePageManager.php +++ b/src/Domain/Subscription/Service/Manager/SubscribePageManager.php @@ -33,7 +33,7 @@ public function createPage(string $title, bool $active = false, ?Administrator $ ->setActive($active) ->setOwner($owner); - $this->pageRepository->save($page); + $this->pageRepository->persist($page); return $page; } @@ -65,15 +65,12 @@ public function updatePage( $page->setOwner($owner); } - $this->entityManager->flush(); - return $page; } public function setActive(SubscribePage $page, bool $active): void { $page->setActive($active); - $this->entityManager->flush(); } public function deletePage(SubscribePage $page): void @@ -100,7 +97,6 @@ public function setPageData(SubscribePage $page, string $name, ?string $value): } $data->setData($value); - $this->entityManager->flush(); return $data; } diff --git a/src/Domain/Subscription/Service/Manager/SubscriberBlacklistManager.php b/src/Domain/Subscription/Service/Manager/SubscriberBlacklistManager.php index d5828c2f..3d124a31 100644 --- a/src/Domain/Subscription/Service/Manager/SubscriberBlacklistManager.php +++ b/src/Domain/Subscription/Service/Manager/SubscriberBlacklistManager.php @@ -53,8 +53,6 @@ public function addEmailToBlacklist(string $email, ?string $reasonData = null): $this->entityManager->persist($blacklistData); } - $this->entityManager->flush(); - return $blacklistEntry; } @@ -65,7 +63,6 @@ public function addBlacklistData(string $email, string $name, string $data): voi $blacklistData->setName($name); $blacklistData->setData($data); $this->entityManager->persist($blacklistData); - $this->entityManager->flush(); } public function removeEmailFromBlacklist(string $email): void @@ -84,8 +81,6 @@ public function removeEmailFromBlacklist(string $email): void if ($subscriber) { $subscriber->setBlacklisted(false); } - - $this->entityManager->flush(); } public function getBlacklistReason(string $email): ?string diff --git a/src/Domain/Subscription/Service/Manager/SubscriberListManager.php b/src/Domain/Subscription/Service/Manager/SubscriberListManager.php index a56b48eb..9f51f566 100644 --- a/src/Domain/Subscription/Service/Manager/SubscriberListManager.php +++ b/src/Domain/Subscription/Service/Manager/SubscriberListManager.php @@ -29,7 +29,7 @@ public function createSubscriberList( ->setListPosition($subscriberListDto->listPosition) ->setPublic($subscriberListDto->isPublic); - $this->subscriberListRepository->save($subscriberList); + $this->subscriberListRepository->persist($subscriberList); return $subscriberList; } diff --git a/src/Domain/Subscription/Service/Manager/SubscriberManager.php b/src/Domain/Subscription/Service/Manager/SubscriberManager.php index 40bfcc20..1993cd9b 100644 --- a/src/Domain/Subscription/Service/Manager/SubscriberManager.php +++ b/src/Domain/Subscription/Service/Manager/SubscriberManager.php @@ -16,9 +16,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Contracts\Translation\TranslatorInterface; -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ class SubscriberManager { private SubscriberRepository $subscriberRepository; @@ -51,7 +48,7 @@ public function createSubscriber(CreateSubscriberDto $subscriberDto): Subscriber $subscriber->setHtmlEmail((bool)$subscriberDto->htmlEmail); $subscriber->setDisabled(false); - $this->subscriberRepository->save($subscriber); + $this->subscriberRepository->persist($subscriber); return $subscriber; } @@ -87,7 +84,6 @@ public function updateSubscriber(UpdateSubscriberDto $subscriberDto, Administrat public function resetBounceCount(Subscriber $subscriber): Subscriber { $subscriber->setBounceCount(0); - $this->entityManager->flush(); return $subscriber; } @@ -100,7 +96,6 @@ public function markAsConfirmedByUniqueId(string $uniqueId): Subscriber } $subscriber->setConfirmed(true); - $this->entityManager->flush(); return $subscriber; } @@ -141,10 +136,4 @@ public function updateFromImport(Subscriber $existingSubscriber, ImportSubscribe return ChangeSetDto::fromDoctrineChangeSet($uow->getEntityChangeSet($existingSubscriber)); } - - public function decrementBounceCount(Subscriber $subscriber): void - { - $subscriber->addToBounceCount(-1); - $this->entityManager->flush(); - } } diff --git a/tests/Integration/Domain/Identity/Repository/AdministratorRepositoryTest.php b/tests/Integration/Domain/Identity/Repository/AdministratorRepositoryTest.php index 25ecf0f8..a5215789 100644 --- a/tests/Integration/Domain/Identity/Repository/AdministratorRepositoryTest.php +++ b/tests/Integration/Domain/Identity/Repository/AdministratorRepositoryTest.php @@ -177,7 +177,7 @@ public function testRemoveRemovesModel(): void $this->assertNotEmpty($allModels); $model = $allModels[0]; - $this->repository->remove($model); + $this->repository->delete($model); $remainingModels = $this->repository->findAll(); $this->assertCount(count($allModels) - 1, $remainingModels); diff --git a/tests/Integration/Domain/Identity/Repository/AdministratorTokenRepositoryTest.php b/tests/Integration/Domain/Identity/Repository/AdministratorTokenRepositoryTest.php index 52feeb8c..ff750a63 100644 --- a/tests/Integration/Domain/Identity/Repository/AdministratorTokenRepositoryTest.php +++ b/tests/Integration/Domain/Identity/Repository/AdministratorTokenRepositoryTest.php @@ -122,56 +122,6 @@ public function testFindOneUnexpiredByKeyNotFindsUnexpiredTokenWithNonMatchingKe self::assertNull($model); } - public function testRemoveExpiredRemovesExpiredToken() - { - $this->loadFixtures([DetachedAdministratorTokenFixture::class]); - - $idOfExpiredToken = 1; - $this->repository->removeExpired(); - - $token = $this->repository->find($idOfExpiredToken); - self::assertNull($token); - } - - public function testRemoveExpiredKeepsUnexpiredToken() - { - $this->assertNotYear2037Yet(); - - $this->loadFixtures([DetachedAdministratorTokenFixture::class]); - - $idOfUnexpiredToken = 2; - $this->repository->removeExpired(); - - $token = $this->repository->find($idOfUnexpiredToken); - self::assertNotNull($token); - } - - /** - * Asserts that it's not year 2037 yet (which is the year the "not expired" token in the fixture - * data set expires). - */ - private function assertNotYear2037Yet(): void - { - $currentYear = (int)date('Y'); - if ($currentYear >= 2037) { - self::markTestIncomplete('The tests token has an expiry in the year 2037. Please update this test.'); - } - } - - public function testRemoveExpiredForNoExpiredTokensReturnsZero() - { - self::assertSame(0, $this->repository->removeExpired()); - } - - public function testRemoveExpiredForOneExpiredTokenReturnsOne() - { - $this->assertNotYear2037Yet(); - - $this->loadFixtures([DetachedAdministratorTokenFixture::class]); - - self::assertSame(1, $this->repository->removeExpired()); - } - public function testSavePersistsAndFlushesModel() { $this->loadFixtures([AdministratorFixture::class]); @@ -196,7 +146,7 @@ public function testRemoveRemovesModel() $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->repository->remove($firstModel); + $this->repository->delete($firstModel); $numberOfModelsAfterRemove = count($this->repository->findAll()); self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); diff --git a/tests/Integration/Domain/Messaging/Repository/SubscriberListRepositoryTest.php b/tests/Integration/Domain/Messaging/Repository/SubscriberListRepositoryTest.php index 0f122582..93e99a81 100644 --- a/tests/Integration/Domain/Messaging/Repository/SubscriberListRepositoryTest.php +++ b/tests/Integration/Domain/Messaging/Repository/SubscriberListRepositoryTest.php @@ -206,7 +206,7 @@ public function testRemoveRemovesModel() $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subscriberListRepository->remove($firstModel); + $this->subscriberListRepository->delete($firstModel); $numberOfModelsAfterRemove = count($this->subscriberListRepository->findAll()); self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); diff --git a/tests/Integration/Domain/Subscription/Repository/SubscriberRepositoryTest.php b/tests/Integration/Domain/Subscription/Repository/SubscriberRepositoryTest.php index 91d871d5..9a2ead68 100644 --- a/tests/Integration/Domain/Subscription/Repository/SubscriberRepositoryTest.php +++ b/tests/Integration/Domain/Subscription/Repository/SubscriberRepositoryTest.php @@ -227,7 +227,7 @@ public function testRemoveAlsoRemovesAssociatedSubscriptions() $numberOfAssociatedSubscriptions = count($model->getSubscriptions()); self::assertGreaterThan(0, $numberOfAssociatedSubscriptions); - $this->subscriberRepository->remove($model); + $this->subscriberRepository->delete($model); $newNumberOfSubscriptions = count($this->subscriptionRepository->findAll()); $numberOfRemovedSubscriptions = $initialNumberOfSubscriptions - $newNumberOfSubscriptions; @@ -246,7 +246,7 @@ public function testRemoveRemovesModel() $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subscriberRepository->remove($firstModel); + $this->subscriberRepository->delete($firstModel); $numberOfModelsAfterRemove = count($this->subscriberRepository->findAll()); self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); diff --git a/tests/Integration/Domain/Subscription/Repository/SubscriptionRepositoryTest.php b/tests/Integration/Domain/Subscription/Repository/SubscriptionRepositoryTest.php index de18894c..3086b178 100644 --- a/tests/Integration/Domain/Subscription/Repository/SubscriptionRepositoryTest.php +++ b/tests/Integration/Domain/Subscription/Repository/SubscriptionRepositoryTest.php @@ -161,7 +161,7 @@ public function testRemoveRemovesModel() $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subscriptionRepository->remove($firstModel); + $this->subscriptionRepository->delete($firstModel); $numberOfModelsAfterRemove = count($this->subscriptionRepository->findAll()); self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); diff --git a/tests/Unit/Domain/Messaging/Command/ProcessBouncesCommandTest.php b/tests/Unit/Bounce/Command/ProcessBouncesCommandTest.php similarity index 93% rename from tests/Unit/Domain/Messaging/Command/ProcessBouncesCommandTest.php rename to tests/Unit/Bounce/Command/ProcessBouncesCommandTest.php index 3e8e24b6..b3840dfb 100644 --- a/tests/Unit/Domain/Messaging/Command/ProcessBouncesCommandTest.php +++ b/tests/Unit/Bounce/Command/ProcessBouncesCommandTest.php @@ -2,15 +2,16 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Command; +namespace PhpList\Core\Tests\Unit\Bounce\Command; +use Doctrine\ORM\EntityManagerInterface; use Exception; -use PhpList\Core\Domain\Messaging\Command\ProcessBouncesCommand; -use PhpList\Core\Domain\Messaging\Service\ConsecutiveBounceHandler; -use PhpList\Core\Domain\Messaging\Service\LockService; -use PhpList\Core\Domain\Messaging\Service\Processor\AdvancedBounceRulesProcessor; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceProtocolProcessor; -use PhpList\Core\Domain\Messaging\Service\Processor\UnidentifiedBounceReprocessor; +use PhpList\Core\Bounce\Command\ProcessBouncesCommand; +use PhpList\Core\Bounce\Service\ConsecutiveBounceHandler; +use PhpList\Core\Bounce\Service\LockService; +use PhpList\Core\Bounce\Service\Processor\AdvancedBounceRulesProcessor; +use PhpList\Core\Bounce\Service\Processor\BounceProtocolProcessor; +use PhpList\Core\Bounce\Service\Processor\UnidentifiedBounceReprocessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; @@ -48,6 +49,7 @@ protected function setUp(): void unidentifiedReprocessor: $this->unidentifiedReprocessor, consecutiveBounceHandler: $this->consecutiveBounceHandler, translator: $this->translator, + entityManager: $this->createMock(EntityManagerInterface::class), ); $this->commandTester = new CommandTester($command); diff --git a/tests/Unit/Domain/Messaging/Service/BounceActionResolverTest.php b/tests/Unit/Bounce/Service/BounceActionResolverTest.php similarity index 91% rename from tests/Unit/Domain/Messaging/Service/BounceActionResolverTest.php rename to tests/Unit/Bounce/Service/BounceActionResolverTest.php index 49d4aadb..92b1054d 100644 --- a/tests/Unit/Domain/Messaging/Service/BounceActionResolverTest.php +++ b/tests/Unit/Bounce/Service/BounceActionResolverTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; +namespace PhpList\Core\Tests\Unit\Bounce\Service; -use PhpList\Core\Domain\Messaging\Service\BounceActionResolver; -use PhpList\Core\Domain\Messaging\Service\Handler\BounceActionHandlerInterface; +use PhpList\Core\Bounce\Service\BounceActionResolver; +use PhpList\Core\Bounce\Service\Handler\BounceActionHandlerInterface; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use RuntimeException; diff --git a/tests/Unit/Domain/Messaging/Service/ConsecutiveBounceHandlerTest.php b/tests/Unit/Bounce/Service/ConsecutiveBounceHandlerTest.php similarity index 96% rename from tests/Unit/Domain/Messaging/Service/ConsecutiveBounceHandlerTest.php rename to tests/Unit/Bounce/Service/ConsecutiveBounceHandlerTest.php index 5fc375cd..fbfdfa8a 100644 --- a/tests/Unit/Domain/Messaging/Service/ConsecutiveBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/ConsecutiveBounceHandlerTest.php @@ -2,15 +2,15 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; +namespace PhpList\Core\Tests\Unit\Bounce\Service; +use PhpList\Core\Bounce\Service\ConsecutiveBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\ConsecutiveBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Style\SymfonyStyle; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php similarity index 90% rename from tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php index cc0ff38d..c7c2260d 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/BlacklistEmailAndDeleteBounceHandlerTest.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\BlacklistEmailAndDeleteBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\BlacklistEmailAndDeleteBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailHandlerTest.php b/tests/Unit/Bounce/Service/Handler/BlacklistEmailHandlerTest.php similarity index 91% rename from tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/BlacklistEmailHandlerTest.php index cb009022..b5b06e59 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistEmailHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/BlacklistEmailHandlerTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Handler\BlacklistEmailHandler; +use PhpList\Core\Bounce\Service\Handler\BlacklistEmailHandler; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php similarity index 91% rename from tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php index 0368d695..e2975d37 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/BlacklistUserAndDeleteBounceHandlerTest.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\BlacklistUserAndDeleteBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\BlacklistUserAndDeleteBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserHandlerTest.php b/tests/Unit/Bounce/Service/Handler/BlacklistUserHandlerTest.php similarity index 92% rename from tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/BlacklistUserHandlerTest.php index e25f54c8..153faa1c 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/BlacklistUserHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/BlacklistUserHandlerTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Handler\BlacklistUserHandler; +use PhpList\Core\Bounce\Service\Handler\BlacklistUserHandler; +use PhpList\Core\Bounce\Service\SubscriberBlacklistService; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\SubscriberBlacklistService; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php similarity index 81% rename from tests/Unit/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php index 34d707e5..9625d348 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/DecreaseCountConfirmUserAndDeleteBounceHandlerTest.php @@ -2,15 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\DecreaseCountConfirmUserAndDeleteBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\DecreaseCountConfirmUserAndDeleteBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; -use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; @@ -18,7 +17,6 @@ class DecreaseCountConfirmUserAndDeleteBounceHandlerTest extends TestCase { private SubscriberHistoryManager&MockObject $historyManager; - private SubscriberManager&MockObject $subscriberManager; private BounceManager&MockObject $bounceManager; private SubscriberRepository&MockObject $subscriberRepository; private DecreaseCountConfirmUserAndDeleteBounceHandler $handler; @@ -26,12 +24,10 @@ class DecreaseCountConfirmUserAndDeleteBounceHandlerTest extends TestCase protected function setUp(): void { $this->historyManager = $this->createMock(SubscriberHistoryManager::class); - $this->subscriberManager = $this->createMock(SubscriberManager::class); $this->bounceManager = $this->createMock(BounceManager::class); $this->subscriberRepository = $this->createMock(SubscriberRepository::class); $this->handler = new DecreaseCountConfirmUserAndDeleteBounceHandler( subscriberHistoryManager: $this->historyManager, - subscriberManager: $this->subscriberManager, bounceManager: $this->bounceManager, subscriberRepository: $this->subscriberRepository, translator: new Translator('en'), @@ -50,7 +46,7 @@ public function testHandleDecrementsMarksConfirmedAddsHistoryAndDeletesWhenNotCo $subscriber = $this->createMock(Subscriber::class); $bounce = $this->createMock(Bounce::class); - $this->subscriberManager->expects($this->once())->method('decrementBounceCount')->with($subscriber); + $this->subscriberRepository->expects($this->once())->method('decrementBounceCount')->with($subscriber); $this->subscriberRepository->expects($this->once())->method('markConfirmed')->with(11); $this->historyManager->expects($this->once())->method('addHistory')->with( $subscriber, @@ -73,7 +69,7 @@ public function testHandleOnlyDecrementsAndDeletesWhenAlreadyConfirmed(): void $subscriber = $this->createMock(Subscriber::class); $bounce = $this->createMock(Bounce::class); - $this->subscriberManager->expects($this->once())->method('decrementBounceCount')->with($subscriber); + $this->subscriberRepository->expects($this->once())->method('decrementBounceCount')->with($subscriber); $this->subscriberRepository->expects($this->never())->method('markConfirmed'); $this->historyManager->expects($this->never())->method('addHistory'); $this->bounceManager->expects($this->once())->method('delete')->with($bounce); @@ -91,7 +87,7 @@ public function testHandleDeletesBounceEvenWithoutSubscriber(): void { $bounce = $this->createMock(Bounce::class); - $this->subscriberManager->expects($this->never())->method('decrementBounceCount'); + $this->subscriberRepository->expects($this->never())->method('decrementBounceCount'); $this->subscriberRepository->expects($this->never())->method('markConfirmed'); $this->historyManager->expects($this->never())->method('addHistory'); $this->bounceManager->expects($this->once())->method('delete')->with($bounce); diff --git a/tests/Unit/Domain/Messaging/Service/Handler/DeleteBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/DeleteBounceHandlerTest.php similarity index 83% rename from tests/Unit/Domain/Messaging/Service/Handler/DeleteBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/DeleteBounceHandlerTest.php index 25028345..1455ab83 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/DeleteBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/DeleteBounceHandlerTest.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\DeleteBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\DeleteBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/DeleteUserAndBounceHandlerTest.php similarity index 91% rename from tests/Unit/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/DeleteUserAndBounceHandlerTest.php index 0d68b631..768efd0c 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/DeleteUserAndBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/DeleteUserAndBounceHandlerTest.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\DeleteUserAndBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\DeleteUserAndBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/DeleteUserHandlerTest.php b/tests/Unit/Bounce/Service/Handler/DeleteUserHandlerTest.php similarity index 94% rename from tests/Unit/Domain/Messaging/Service/Handler/DeleteUserHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/DeleteUserHandlerTest.php index 427f8146..af61b8d5 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/DeleteUserHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/DeleteUserHandlerTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Handler\DeleteUserHandler; +use PhpList\Core\Bounce\Service\Handler\DeleteUserHandler; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php b/tests/Unit/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php similarity index 93% rename from tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php index 6ddc4e3d..92b146fb 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/UnconfirmUserAndDeleteBounceHandlerTest.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; +use PhpList\Core\Bounce\Service\Handler\UnconfirmUserAndDeleteBounceHandler; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Handler\UnconfirmUserAndDeleteBounceHandler; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; diff --git a/tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserHandlerTest.php b/tests/Unit/Bounce/Service/Handler/UnconfirmUserHandlerTest.php similarity index 94% rename from tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserHandlerTest.php rename to tests/Unit/Bounce/Service/Handler/UnconfirmUserHandlerTest.php index fbbc265a..dcc0c0d8 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/UnconfirmUserHandlerTest.php +++ b/tests/Unit/Bounce/Service/Handler/UnconfirmUserHandlerTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Handler; +namespace PhpList\Core\Tests\Unit\Bounce\Service\Handler; -use PhpList\Core\Domain\Messaging\Service\Handler\UnconfirmUserHandler; +use PhpList\Core\Bounce\Service\Handler\UnconfirmUserHandler; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; diff --git a/tests/Unit/Domain/Messaging/Service/LockServiceTest.php b/tests/Unit/Bounce/Service/LockServiceTest.php similarity index 96% rename from tests/Unit/Domain/Messaging/Service/LockServiceTest.php rename to tests/Unit/Bounce/Service/LockServiceTest.php index 8851d7de..8577ef5f 100644 --- a/tests/Unit/Domain/Messaging/Service/LockServiceTest.php +++ b/tests/Unit/Bounce/Service/LockServiceTest.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; +namespace PhpList\Core\Tests\Unit\Bounce\Service; +use PhpList\Core\Bounce\Service\LockService; use PhpList\Core\Domain\Messaging\Model\SendProcess; use PhpList\Core\Domain\Messaging\Repository\SendProcessRepository; -use PhpList\Core\Domain\Messaging\Service\LockService; use PhpList\Core\Domain\Messaging\Service\Manager\SendProcessManager; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Domain/Messaging/Service/MessageParserTest.php b/tests/Unit/Bounce/Service/MessageParserTest.php similarity index 95% rename from tests/Unit/Domain/Messaging/Service/MessageParserTest.php rename to tests/Unit/Bounce/Service/MessageParserTest.php index 49b38615..35e60706 100644 --- a/tests/Unit/Domain/Messaging/Service/MessageParserTest.php +++ b/tests/Unit/Bounce/Service/MessageParserTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; +namespace PhpList\Core\Tests\Unit\Bounce\Service; -use PhpList\Core\Domain\Messaging\Service\MessageParser; +use PhpList\Core\Bounce\Service\MessageParser; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Domain/Messaging/Service/WebklexImapClientFactoryTest.php b/tests/Unit/Bounce/Service/WebklexImapClientFactoryTest.php similarity index 94% rename from tests/Unit/Domain/Messaging/Service/WebklexImapClientFactoryTest.php rename to tests/Unit/Bounce/Service/WebklexImapClientFactoryTest.php index e75766f5..25ad57dc 100644 --- a/tests/Unit/Domain/Messaging/Service/WebklexImapClientFactoryTest.php +++ b/tests/Unit/Bounce/Service/WebklexImapClientFactoryTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; +namespace PhpList\Core\Tests\Unit\Bounce\Service; -use PhpList\Core\Domain\Messaging\Service\WebklexImapClientFactory; +use PhpList\Core\Bounce\Service\WebklexImapClientFactory; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Webklex\PHPIMAP\Client; diff --git a/tests/Unit/Domain/Analytics/Service/LinkTrackServiceTest.php b/tests/Unit/Domain/Analytics/Service/LinkTrackServiceTest.php index c136ec51..c768b056 100644 --- a/tests/Unit/Domain/Analytics/Service/LinkTrackServiceTest.php +++ b/tests/Unit/Domain/Analytics/Service/LinkTrackServiceTest.php @@ -42,7 +42,7 @@ public function testExtractAndSaveLinksWithNoLinks(): void $message->method('getId')->willReturn($messageId); $message->method('getContent')->willReturn($messageContent); - $this->linkTrackRepository->expects(self::never())->method('save'); + $this->linkTrackRepository->expects(self::never())->method('persist'); $result = $this->subject->extractAndSaveLinks($message, $userId); @@ -63,7 +63,7 @@ public function testExtractAndSaveLinksWithLinks(): void $message->method('getContent')->willReturn($messageContent); $this->linkTrackRepository->expects(self::exactly(2)) - ->method('save') + ->method('persist') ->willReturnCallback(function (LinkTrack $linkTrack) use ($messageId, $userId) { self::assertSame($messageId, $linkTrack->getMessageId()); self::assertSame($userId, $linkTrack->getUserId()); @@ -92,7 +92,7 @@ public function testExtractAndSaveLinksWithFooter(): void $message->method('getContent')->willReturn($messageContent); $this->linkTrackRepository->expects(self::exactly(2)) - ->method('save') + ->method('persist') ->willReturnCallback(function (LinkTrack $linkTrack) use ($messageId, $userId) { self::assertSame($messageId, $linkTrack->getMessageId()); self::assertSame($userId, $linkTrack->getUserId()); @@ -120,7 +120,7 @@ public function testExtractAndSaveLinksWithDuplicateLinks(): void $message->method('getContent')->willReturn($messageContent); $this->linkTrackRepository->expects(self::once()) - ->method('save') + ->method('persist') ->willReturnCallback(function (LinkTrack $linkTrack) use ($messageId, $userId) { self::assertSame($messageId, $linkTrack->getMessageId()); self::assertSame($userId, $linkTrack->getUserId()); @@ -147,7 +147,7 @@ public function testExtractAndSaveLinksWithNullText(): void $message->method('getContent')->willReturn($messageContent); $this->linkTrackRepository->expects(self::once()) - ->method('save') + ->method('persist') ->willReturnCallback(function (LinkTrack $linkTrack) use ($messageId, $userId) { self::assertSame($messageId, $linkTrack->getMessageId()); self::assertSame($userId, $linkTrack->getUserId()); @@ -219,7 +219,7 @@ public function testExtractAndSaveLinksWithExistingLink(): void ->willReturn($existingLinkTrack); $this->linkTrackRepository->expects(self::never()) - ->method('save'); + ->method('persist'); $result = $this->subject->extractAndSaveLinks($message, $userId); diff --git a/tests/Unit/Domain/Configuration/Service/Manager/ConfigManagerTest.php b/tests/Unit/Domain/Configuration/Service/Manager/ConfigManagerTest.php index 3b14122b..fbe5276e 100644 --- a/tests/Unit/Domain/Configuration/Service/Manager/ConfigManagerTest.php +++ b/tests/Unit/Domain/Configuration/Service/Manager/ConfigManagerTest.php @@ -4,6 +4,7 @@ namespace PhpList\Core\Tests\Unit\Domain\Configuration\Service\Manager; +use PhpList\Core\Domain\Configuration\Exception\ConfigNotEditableException; use PhpList\Core\Domain\Configuration\Model\Config; use PhpList\Core\Domain\Configuration\Repository\ConfigRepository; use PhpList\Core\Domain\Configuration\Service\Manager\ConfigManager; @@ -61,30 +62,13 @@ public function testGetAllReturnsAllConfigsFromRepository(): void $this->assertSame('value2', $result[1]->getValue()); } - public function testUpdateSavesConfigToRepository(): void - { - $configRepository = $this->createMock(ConfigRepository::class); - $manager = new ConfigManager($configRepository); - - $config = new Config(); - $config->setKey('test_item'); - $config->setValue('test_value'); - $config->setEditable(true); - - $configRepository->expects($this->once()) - ->method('save') - ->with($config); - - $manager->update($config, 'new_value'); - } - public function testCreateSavesNewConfigToRepository(): void { $configRepository = $this->createMock(ConfigRepository::class); $manager = new ConfigManager($configRepository); $configRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (Config $config) { return $config->getKey() === 'test_key' && $config->getValue() === 'test_value' && @@ -119,10 +103,7 @@ public function testUpdateThrowsExceptionWhenConfigIsNotEditable(): void $config->setValue('test_value'); $config->setEditable(false); - $configRepository->expects($this->never()) - ->method('save'); - - $this->expectException(\PhpList\Core\Domain\Configuration\Exception\ConfigNotEditableException::class); + $this->expectException(ConfigNotEditableException::class); $this->expectExceptionMessage('Configuration item "test_item" is not editable.'); $manager->update($config, 'new_value'); diff --git a/tests/Unit/Domain/Identity/Command/CleanUpOldSessionTokensTest.php b/tests/Unit/Domain/Identity/Command/CleanUpOldSessionTokensTest.php index a358c25c..51a440d5 100644 --- a/tests/Unit/Domain/Identity/Command/CleanUpOldSessionTokensTest.php +++ b/tests/Unit/Domain/Identity/Command/CleanUpOldSessionTokensTest.php @@ -4,67 +4,69 @@ namespace PhpList\Core\Tests\Unit\Domain\Identity\Command; -use Exception; +use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Identity\Command\CleanUpOldSessionTokens; use PhpList\Core\Domain\Identity\Repository\AdministratorTokenRepository; -use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Tester\CommandTester; -class CleanUpOldSessionTokensTest extends TestCase +final class CleanUpOldSessionTokensTest extends TestCase { - private AdministratorTokenRepository&MockObject $tokenRepository; - private CommandTester $commandTester; - - protected function setUp(): void + public function testItRemovesAllExpiredTokensAndOutputsSuccess(): void { - $this->tokenRepository = $this->createMock(AdministratorTokenRepository::class); + $repo = $this->createMock(AdministratorTokenRepository::class); + $em = $this->createMock(EntityManagerInterface::class); - $command = new CleanUpOldSessionTokens($this->tokenRepository); + $token1 = (object) ['id' => 1]; + $token2 = (object) ['id' => 2]; + $expired = [$token1, $token2]; - $application = new Application(); - $application->add($command); + $repo->expects($this->once()) + ->method('getExpired') + ->willReturn($expired); - $this->commandTester = new CommandTester($command); - } + $removed = []; + $em->expects($this->exactly(\count($expired))) + ->method('remove') + ->willReturnCallback(function (object $o) use (&$removed) { + $removed[] = $o; + }); - public function testExecuteSuccessfully(): void - { - $this->tokenRepository->expects($this->once()) - ->method('removeExpired') - ->willReturn(5); + $em->expects($this->once()) + ->method('flush'); - $this->commandTester->execute([]); + $command = new CleanUpOldSessionTokens($repo, $em); + $tester = new CommandTester($command); - $output = $this->commandTester->getDisplay(); - $this->assertStringContainsString('Successfully removed 5 expired session token(s)', $output); - $this->assertEquals(0, $this->commandTester->getStatusCode()); - } + $exitCode = $tester->execute([]); - public function testExecuteWithNoExpiredTokens(): void - { - $this->tokenRepository->expects($this->once()) - ->method('removeExpired') - ->willReturn(0); + self::assertSame(Command::SUCCESS, $exitCode); - $this->commandTester->execute([]); + $display = $tester->getDisplay(); + self::assertStringContainsString('Successfully removed 2 expired session token(s).', $display); - $output = $this->commandTester->getDisplay(); - $this->assertStringContainsString('Successfully removed 0 expired session token(s)', $output); - $this->assertEquals(0, $this->commandTester->getStatusCode()); + self::assertEqualsCanonicalizing($expired, $removed); } - public function testExecuteWithException(): void + public function testItHandlesExceptionsAndOutputsFailure(): void { - $this->tokenRepository->expects($this->once()) - ->method('removeExpired') - ->willThrowException(new Exception('Test exception')); + $repo = $this->createMock(AdministratorTokenRepository::class); + $em = $this->createMock(EntityManagerInterface::class); + + $repo->expects($this->once()) + ->method('getExpired') + ->willThrowException(new \RuntimeException('boom')); + + $em->expects($this->never())->method('remove'); + $em->expects($this->never())->method('flush'); + + $command = new CleanUpOldSessionTokens($repo, $em); + $tester = new CommandTester($command); - $this->commandTester->execute([]); + $exitCode = $tester->execute([]); - $output = $this->commandTester->getDisplay(); - $this->assertStringContainsString('Error removing expired session tokens: Test exception', $output); - $this->assertEquals(1, $this->commandTester->getStatusCode()); + self::assertSame(Command::FAILURE, $exitCode); + self::assertStringContainsString('Error removing expired session tokens: boom', $tester->getDisplay()); } } diff --git a/tests/Unit/Domain/Identity/Service/AdminAttributeDefinitionManagerTest.php b/tests/Unit/Domain/Identity/Service/AdminAttributeDefinitionManagerTest.php index 1a4deef4..3c3356d7 100644 --- a/tests/Unit/Domain/Identity/Service/AdminAttributeDefinitionManagerTest.php +++ b/tests/Unit/Domain/Identity/Service/AdminAttributeDefinitionManagerTest.php @@ -49,7 +49,7 @@ public function testCreateCreatesNewAttributeDefinition(): void ->willReturn(null); $this->repository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (AdminAttributeDefinition $definition) use ($dto) { return $definition->getName() === $dto->name && $definition->getType() === $dto->type @@ -143,10 +143,6 @@ public function testUpdateUpdatesAttributeDefinition(): void ->with('new_table') ->willReturnSelf(); - $this->repository->expects($this->once()) - ->method('save') - ->with($attributeDefinition); - $result = $this->subject->update($attributeDefinition, $dto); $this->assertSame($attributeDefinition, $result); diff --git a/tests/Unit/Domain/Identity/Service/AdminAttributeManagerTest.php b/tests/Unit/Domain/Identity/Service/AdminAttributeManagerTest.php index 9c5cac8f..d0ea805c 100644 --- a/tests/Unit/Domain/Identity/Service/AdminAttributeManagerTest.php +++ b/tests/Unit/Domain/Identity/Service/AdminAttributeManagerTest.php @@ -41,7 +41,7 @@ public function testCreateOrUpdateCreatesNewAttributeIfNotExists(): void ->willReturn(null); $this->repository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (AdminAttributeValue $attribute) use ($value) { return $attribute->getAdministrator()->getId() === 1 && $attribute->getAttributeDefinition()->getId() === 2 @@ -72,7 +72,7 @@ public function testCreateOrUpdateUpdatesExistingAttribute(): void ->with(1, 2) ->willReturn($existingAttribute); - $this->repository->expects($this->once()) + $this->repository->expects($this->never()) ->method('save') ->with($this->callback(function (AdminAttributeValue $attribute) use ($newValue) { return $attribute->getValue() === $newValue; @@ -98,8 +98,7 @@ public function testCreateOrUpdateUsesDefaultValueIfValueIsNull(): void ->method('findOneByAdminIdAndAttributeId') ->willReturn(null); - $this->repository->expects($this->once()) - ->method('save'); + // will not throw AdminAttributeCreationException $result = $this->subject->createOrUpdate($admin, $definition); diff --git a/tests/Unit/Domain/Identity/Service/AdministratorManagerTest.php b/tests/Unit/Domain/Identity/Service/AdministratorManagerTest.php index 11c3f378..0b91fb8e 100644 --- a/tests/Unit/Domain/Identity/Service/AdministratorManagerTest.php +++ b/tests/Unit/Domain/Identity/Service/AdministratorManagerTest.php @@ -32,7 +32,6 @@ public function testCreateAdministrator(): void ->willReturn('hashed_pass'); $entityManager->expects($this->once())->method('persist'); - $entityManager->expects($this->once())->method('flush'); $manager = new AdministratorManager($entityManager, $hashGenerator); $admin = $manager->createAdministrator($dto); @@ -67,8 +66,6 @@ public function testUpdateAdministrator(): void ->with('newpass') ->willReturn('new_hash'); - $entityManager->expects($this->once())->method('flush'); - $manager = new AdministratorManager($entityManager, $hashGenerator); $manager->updateAdministrator($admin, $dto); @@ -86,7 +83,6 @@ public function testDeleteAdministrator(): void $admin = $this->createMock(Administrator::class); $entityManager->expects($this->once())->method('remove')->with($admin); - $entityManager->expects($this->once())->method('flush'); $manager = new AdministratorManager($entityManager, $hashGenerator); $manager->deleteAdministrator($admin); diff --git a/tests/Unit/Domain/Identity/Service/PasswordManagerTest.php b/tests/Unit/Domain/Identity/Service/PasswordManagerTest.php index 59ace13d..b9b53039 100644 --- a/tests/Unit/Domain/Identity/Service/PasswordManagerTest.php +++ b/tests/Unit/Domain/Identity/Service/PasswordManagerTest.php @@ -83,7 +83,7 @@ public function testGeneratePasswordResetTokenCleansUpExistingRequests(): void ->with($existingRequest); $this->passwordRequestRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(AdminPasswordRequest::class)); $this->messageBus->expects($this->once()) @@ -187,7 +187,7 @@ public function testUpdatePasswordWithTokenUpdatesPasswordAndRemovesToken(): voi ->willReturn($newPasswordHash); $this->administratorRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($administrator); $this->passwordRequestRepository->expects($this->once()) diff --git a/tests/Unit/Domain/Messaging/Command/ProcessQueueCommandTest.php b/tests/Unit/Domain/Messaging/Command/ProcessQueueCommandTest.php index 5cd84c5e..e4dc836e 100644 --- a/tests/Unit/Domain/Messaging/Command/ProcessQueueCommandTest.php +++ b/tests/Unit/Domain/Messaging/Command/ProcessQueueCommandTest.php @@ -4,26 +4,29 @@ namespace PhpList\Core\Tests\Unit\Domain\Messaging\Command; +use Doctrine\ORM\EntityManagerInterface; use Exception; use PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider; use PhpList\Core\Domain\Messaging\Command\ProcessQueueCommand; +use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Messaging\Service\MessageProcessingPreparator; -use PhpList\Core\Domain\Messaging\Service\Processor\CampaignProcessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockInterface; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Translation\Translator; class ProcessQueueCommandTest extends TestCase { private MessageRepository&MockObject $messageRepository; private MessageProcessingPreparator&MockObject $messageProcessingPreparator; - private CampaignProcessor&MockObject $campaignProcessor; + private MessageBusInterface&MockObject $messageBus; private LockInterface&MockObject $lock; private CommandTester $commandTester; private Translator&MockObject $translator; @@ -33,7 +36,7 @@ protected function setUp(): void $this->messageRepository = $this->createMock(MessageRepository::class); $lockFactory = $this->createMock(LockFactory::class); $this->messageProcessingPreparator = $this->createMock(MessageProcessingPreparator::class); - $this->campaignProcessor = $this->createMock(CampaignProcessor::class); + $this->messageBus = $this->createMock(MessageBusInterface::class); $this->lock = $this->createMock(LockInterface::class); $this->translator = $this->createMock(Translator::class); @@ -45,9 +48,10 @@ protected function setUp(): void messageRepository: $this->messageRepository, lockFactory: $lockFactory, messagePreparator: $this->messageProcessingPreparator, - campaignProcessor: $this->campaignProcessor, + messageBus: $this->messageBus, configProvider: $this->createMock(ConfigProvider::class), translator: $this->translator, + entityManager: $this->createMock(EntityManagerInterface::class), ); $application = new Application(); @@ -97,8 +101,8 @@ public function testExecuteWithNoCampaigns(): void ->with($this->anything(), $this->anything()) ->willReturn([]); - $this->campaignProcessor->expects($this->never()) - ->method('process'); + $this->messageBus->expects($this->never()) + ->method('dispatch'); $this->commandTester->execute([]); @@ -121,22 +125,29 @@ public function testExecuteWithCampaigns(): void ->method('ensureCampaignsHaveUuid'); $campaign = $this->createMock(Message::class); + $campaign->method('getId')->willReturn(1); $this->messageRepository->expects($this->once()) ->method('getByStatusAndEmbargo') ->with($this->anything(), $this->anything()) ->willReturn([$campaign]); - $this->campaignProcessor->expects($this->once()) - ->method('process') - ->with($campaign, $this->anything()); + $this->messageBus->expects($this->once()) + ->method('dispatch') + ->with( + $this->callback(function (CampaignProcessorMessage $message) use ($campaign) { + $this->assertEquals($campaign->getId(), $message->getMessageId()); + return true; + }), + $this->equalTo([]) + ) + ->willReturn(new Envelope(new CampaignProcessorMessage($campaign->getId()))); $this->commandTester->execute([]); $this->assertEquals(0, $this->commandTester->getStatusCode()); } - public function testExecuteWithMultipleCampaigns(): void { $this->lock->expects($this->once()) @@ -152,27 +163,37 @@ public function testExecuteWithMultipleCampaigns(): void $this->messageProcessingPreparator->expects($this->once()) ->method('ensureCampaignsHaveUuid'); - $campaign1 = $this->createMock(Message::class); - $campaign2 = $this->createMock(Message::class); + $cmp1 = $this->createMock(Message::class); + $cmp1->method('getId')->willReturn(1); + $cmp2 = $this->createMock(Message::class); + $cmp2->method('getId')->willReturn(2); $this->messageRepository->expects($this->once()) ->method('getByStatusAndEmbargo') ->with($this->anything(), $this->anything()) - ->willReturn([$campaign1, $campaign2]); - - $this->campaignProcessor->expects($this->exactly(2)) - ->method('process') - ->withConsecutive( - [$campaign1, $this->anything()], - [$campaign2, $this->anything()] - ); + ->willReturn([$cmp1, $cmp2]); + + $this->messageBus->expects($this->exactly(2)) + ->method('dispatch') + ->willReturnCallback(function (CampaignProcessorMessage $message, array $stamps) use ($cmp1, $cmp2) { + static $call = 0; + $call++; + if ($call === 1) { + $this->assertEquals($cmp1->getId(), $message->getMessageId()); + } else { + $this->assertEquals($cmp2->getId(), $message->getMessageId()); + } + $this->assertSame([], $stamps); + + return new Envelope(new CampaignProcessorMessage($message->getMessageId())); + }); $this->commandTester->execute([]); $this->assertEquals(0, $this->commandTester->getStatusCode()); } - public function testExecuteWithProcessorException(): void + public function testExecuteWithDispatcherException(): void { $this->lock->expects($this->once()) ->method('acquire') @@ -188,16 +209,23 @@ public function testExecuteWithProcessorException(): void ->method('ensureCampaignsHaveUuid'); $campaign = $this->createMock(Message::class); + $campaign->method('getId')->willReturn(1); $this->messageRepository->expects($this->once()) ->method('getByStatusAndEmbargo') ->with($this->anything(), $this->anything()) ->willReturn([$campaign]); - $this->campaignProcessor->expects($this->once()) - ->method('process') - ->with($campaign, $this->anything()) - ->willThrowException(new Exception('Test exception')); + $this->messageBus->expects($this->once()) + ->method('dispatch') + ->with( + $this->callback(function (CampaignProcessorMessage $message) use ($campaign) { + $this->assertEquals($campaign->getId(), $message->getMessageId()); + return true; + }), + $this->equalTo([]) + ) + ->willThrowException(new Exception()); $this->commandTester->execute([]); diff --git a/tests/Unit/Domain/Messaging/Service/Processor/CampaignProcessorTest.php b/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php similarity index 70% rename from tests/Unit/Domain/Messaging/Service/Processor/CampaignProcessorTest.php rename to tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php index f2f82752..e50d89fa 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/CampaignProcessorTest.php +++ b/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php @@ -2,18 +2,21 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Domain\Messaging\MessageHandler; use Doctrine\ORM\EntityManagerInterface; use Exception; +use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; +use PhpList\Core\Domain\Messaging\MessageHandler\CampaignProcessorMessageHandler; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Model\Message\MessageContent; use PhpList\Core\Domain\Messaging\Model\Message\MessageMetadata; +use PhpList\Core\Domain\Messaging\Model\Message\MessageStatus; +use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Messaging\Repository\UserMessageRepository; use PhpList\Core\Domain\Messaging\Service\Handler\RequeueHandler; use PhpList\Core\Domain\Messaging\Service\MaxProcessTimeLimiter; use PhpList\Core\Domain\Messaging\Service\MessageProcessingPreparator; -use PhpList\Core\Domain\Messaging\Service\Processor\CampaignProcessor; use PhpList\Core\Domain\Messaging\Service\RateLimitedCampaignMailer; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; @@ -21,19 +24,23 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Mime\Email; use Symfony\Component\Translation\Translator; +use Symfony\Contracts\Translation\TranslatorInterface; -class CampaignProcessorTest extends TestCase +class CampaignProcessorMessageHandlerTest extends TestCase { private RateLimitedCampaignMailer|MockObject $mailer; private EntityManagerInterface|MockObject $entityManager; private SubscriberProvider|MockObject $subscriberProvider; private MessageProcessingPreparator|MockObject $messagePreparator; private LoggerInterface|MockObject $logger; - private OutputInterface|MockObject $output; - private CampaignProcessor $campaignProcessor; + private CampaignProcessorMessageHandler $handler; + private MessageRepository|MockObject $messageRepository; + private UserMessageRepository|MockObject $userMessageRepository; + private MaxProcessTimeLimiter|MockObject $timeLimiter; + private RequeueHandler|MockObject $requeueHandler; + private TranslatorInterface|MockObject $translator; protected function setUp(): void { @@ -42,28 +49,58 @@ protected function setUp(): void $this->subscriberProvider = $this->createMock(SubscriberProvider::class); $this->messagePreparator = $this->createMock(MessageProcessingPreparator::class); $this->logger = $this->createMock(LoggerInterface::class); - $this->output = $this->createMock(OutputInterface::class); - $userMessageRepository = $this->createMock(UserMessageRepository::class); + $this->messageRepository = $this->createMock(MessageRepository::class); + $this->userMessageRepository = $this->createMock(UserMessageRepository::class); + $this->timeLimiter = $this->createMock(MaxProcessTimeLimiter::class); + $this->requeueHandler = $this->createMock(RequeueHandler::class); + $this->translator = $this->createMock(Translator::class); - $this->campaignProcessor = new CampaignProcessor( + $this->timeLimiter->method('start'); + $this->timeLimiter->method('shouldStop')->willReturn(false); + + $this->handler = new CampaignProcessorMessageHandler( mailer: $this->mailer, entityManager: $this->entityManager, subscriberProvider: $this->subscriberProvider, messagePreparator: $this->messagePreparator, logger: $this->logger, - userMessageRepository: $userMessageRepository, - timeLimiter: $this->createMock(MaxProcessTimeLimiter::class), - requeueHandler: $this->createMock(RequeueHandler::class), - translator: new Translator('en'), + userMessageRepository: $this->userMessageRepository, + timeLimiter: $this->timeLimiter, + requeueHandler: $this->requeueHandler, + translator: $this->translator, subscriberHistoryManager: $this->createMock(SubscriberHistoryManager::class), + messageRepository: $this->messageRepository, ); } - public function testProcessWithNoSubscribers(): void + public function testInvokeWhenCampaignNotFound(): void + { + $message = new CampaignProcessorMessage(999); + + $this->messageRepository->expects($this->once()) + ->method('findByIdAndStatus') + ->with(999, MessageStatus::Submitted) + ->willReturn(null); + + $this->translator->method('trans')->willReturnCallback(fn(string $msg) => $msg); + + $this->logger->expects($this->once()) + ->method('warning') + ->with('Campaign not found or not in submitted status', ['campaign_id' => 999]); + + ($this->handler)($message); + } + + public function testInvokeWithNoSubscribers(): void { $campaign = $this->createCampaignMock(); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); + $campaign->method('getId')->willReturn(1); + + $this->messageRepository->method('findByIdAndStatus') + ->with(1, MessageStatus::Submitted) + ->willReturn($campaign); $this->subscriberProvider->expects($this->once()) ->method('getSubscribersForMessage') @@ -79,14 +116,19 @@ public function testProcessWithNoSubscribers(): void $this->mailer->expects($this->never()) ->method('send'); - $this->campaignProcessor->process($campaign, $this->output); + ($this->handler)(new CampaignProcessorMessage(1)); } - public function testProcessWithInvalidSubscriberEmail(): void + public function testInvokeWithInvalidSubscriberEmail(): void { $campaign = $this->createCampaignMock(); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); + $campaign->method('getId')->willReturn(1); + + $this->messageRepository->method('findByIdAndStatus') + ->with(1, MessageStatus::Submitted) + ->willReturn($campaign); $subscriber = $this->createMock(Subscriber::class); $subscriber->method('getEmail')->willReturn('invalid-email'); @@ -109,14 +151,19 @@ public function testProcessWithInvalidSubscriberEmail(): void $this->mailer->expects($this->never()) ->method('send'); - $this->campaignProcessor->process($campaign, $this->output); + ($this->handler)(new CampaignProcessorMessage(1)); } - public function testProcessWithValidSubscriberEmail(): void + public function testInvokeWithValidSubscriberEmail(): void { $campaign = $this->createCampaignMock(); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); + $campaign->method('getId')->willReturn(1); + + $this->messageRepository->method('findByIdAndStatus') + ->with(1, MessageStatus::Submitted) + ->willReturn($campaign); $subscriber = $this->createMock(Subscriber::class); $subscriber->method('getEmail')->willReturn('test@example.com'); @@ -156,16 +203,20 @@ public function testProcessWithValidSubscriberEmail(): void $this->entityManager->expects($this->atLeastOnce()) ->method('flush'); - $this->campaignProcessor->process($campaign, $this->output); + ($this->handler)(new CampaignProcessorMessage(1)); } - public function testProcessWithMailerException(): void + public function testInvokeWithMailerException(): void { $campaign = $this->createCampaignMock(); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); $campaign->method('getId')->willReturn(123); + $this->messageRepository->method('findByIdAndStatus') + ->with(123, MessageStatus::Submitted) + ->willReturn($campaign); + $subscriber = $this->createMock(Subscriber::class); $subscriber->method('getEmail')->willReturn('test@example.com'); $subscriber->method('getId')->willReturn(1); @@ -192,24 +243,25 @@ public function testProcessWithMailerException(): void 'campaign_id' => 123, ]); - $this->output->expects($this->once()) - ->method('writeln') - ->with('Failed to send to: test@example.com'); - $metadata->expects($this->atLeastOnce()) ->method('setStatus'); $this->entityManager->expects($this->atLeastOnce()) ->method('flush'); - $this->campaignProcessor->process($campaign, $this->output); + ($this->handler)(new CampaignProcessorMessage(123)); } - public function testProcessWithMultipleSubscribers(): void + public function testInvokeWithMultipleSubscribers(): void { $campaign = $this->createCampaignMock(); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); + $campaign->method('getId')->willReturn(1); + + $this->messageRepository->method('findByIdAndStatus') + ->with(1, MessageStatus::Submitted) + ->willReturn($campaign); $subscriber1 = $this->createMock(Subscriber::class); $subscriber1->method('getEmail')->willReturn('test1@example.com'); @@ -241,49 +293,7 @@ public function testProcessWithMultipleSubscribers(): void $this->entityManager->expects($this->atLeastOnce()) ->method('flush'); - $this->campaignProcessor->process($campaign, $this->output); - } - - public function testProcessWithNullOutput(): void - { - $campaign = $this->createCampaignMock(); - $metadata = $this->createMock(MessageMetadata::class); - $campaign->method('getMetadata')->willReturn($metadata); - $campaign->method('getId')->willReturn(123); - - $subscriber = $this->createMock(Subscriber::class); - $subscriber->method('getEmail')->willReturn('test@example.com'); - $subscriber->method('getId')->willReturn(1); - - $this->subscriberProvider->expects($this->once()) - ->method('getSubscribersForMessage') - ->with($campaign) - ->willReturn([$subscriber]); - - $this->messagePreparator->expects($this->once()) - ->method('processMessageLinks') - ->with($campaign, 1) - ->willReturn($campaign); - - $exception = new Exception('Test exception'); - $this->mailer->expects($this->once()) - ->method('send') - ->willThrowException($exception); - - $this->logger->expects($this->once()) - ->method('error') - ->with('Test exception', [ - 'subscriber_id' => 1, - 'campaign_id' => 123, - ]); - - $metadata->expects($this->atLeastOnce()) - ->method('setStatus'); - - $this->entityManager->expects($this->atLeastOnce()) - ->method('flush'); - - $this->campaignProcessor->process($campaign, null); + ($this->handler)(new CampaignProcessorMessage(1)); } /** diff --git a/tests/Unit/Domain/Messaging/Service/Handler/RequeueHandlerTest.php b/tests/Unit/Domain/Messaging/Service/Handler/RequeueHandlerTest.php index 079d06a8..495f496e 100644 --- a/tests/Unit/Domain/Messaging/Service/Handler/RequeueHandlerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Handler/RequeueHandlerTest.php @@ -6,7 +6,6 @@ use DateInterval; use DateTime; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Model\Message\MessageContent; use PhpList\Core\Domain\Messaging\Model\Message\MessageFormat; @@ -24,13 +23,11 @@ class RequeueHandlerTest extends TestCase { private LoggerInterface&MockObject $logger; - private EntityManagerInterface&MockObject $em; private OutputInterface&MockObject $output; protected function setUp(): void { $this->logger = $this->createMock(LoggerInterface::class); - $this->em = $this->createMock(EntityManagerInterface::class); $this->output = $this->createMock(OutputInterface::class); } @@ -56,10 +53,9 @@ private function createMessage( public function testReturnsFalseWhenIntervalIsZeroOrNegative(): void { - $handler = new RequeueHandler($this->logger, $this->em, new Translator('en')); + $handler = new RequeueHandler($this->logger, new Translator('en')); $message = $this->createMessage(0, null, null); - $this->em->expects($this->never())->method('flush'); $this->output->expects($this->never())->method('writeln'); $this->logger->expects($this->never())->method('info'); @@ -71,11 +67,10 @@ public function testReturnsFalseWhenIntervalIsZeroOrNegative(): void public function testReturnsFalseWhenNowIsAfterRequeueUntil(): void { - $handler = new RequeueHandler($this->logger, $this->em, new Translator('en')); + $handler = new RequeueHandler($this->logger, new Translator('en')); $past = (new DateTime())->sub(new DateInterval('PT5M')); $message = $this->createMessage(5, $past, null); - $this->em->expects($this->never())->method('flush'); $this->logger->expects($this->never())->method('info'); $result = $handler->handle($message, $this->output); @@ -86,12 +81,11 @@ public function testReturnsFalseWhenNowIsAfterRequeueUntil(): void public function testRequeuesFromFutureEmbargoAndSetsSubmittedStatus(): void { - $handler = new RequeueHandler($this->logger, $this->em, new Translator('en')); + $handler = new RequeueHandler($this->logger, new Translator('en')); $embargo = (new DateTime())->add(new DateInterval('PT5M')); $interval = 10; $message = $this->createMessage($interval, null, $embargo); - $this->em->expects($this->once())->method('flush'); $this->output->expects($this->once())->method('writeln'); $this->logger->expects($this->once())->method('info'); @@ -108,11 +102,10 @@ public function testRequeuesFromFutureEmbargoAndSetsSubmittedStatus(): void public function testRequeuesFromNowWhenEmbargoIsNullOrPast(): void { - $handler = new RequeueHandler($this->logger, $this->em, new Translator('en')); + $handler = new RequeueHandler($this->logger, new Translator('en')); $interval = 3; $message = $this->createMessage($interval, null, null); - $this->em->expects($this->once())->method('flush'); $this->logger->expects($this->once())->method('info'); $before = new DateTime(); @@ -134,14 +127,13 @@ public function testRequeuesFromNowWhenEmbargoIsNullOrPast(): void public function testReturnsFalseWhenNextEmbargoExceedsUntil(): void { - $handler = new RequeueHandler($this->logger, $this->em, new Translator('en')); + $handler = new RequeueHandler($this->logger, new Translator('en')); $embargo = (new DateTime())->add(new DateInterval('PT1M')); $interval = 10; // next would be +10, which exceeds until $until = (clone $embargo)->add(new DateInterval('PT5M')); $message = $this->createMessage($interval, $until, $embargo); - $this->em->expects($this->never())->method('flush'); $this->logger->expects($this->never())->method('info'); $result = $handler->handle($message, $this->output); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/BounceManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/BounceManagerTest.php index 0dbde7ad..9de0df4d 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/BounceManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/BounceManagerTest.php @@ -6,11 +6,11 @@ use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; +use PhpList\Core\Bounce\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Model\Bounce; use PhpList\Core\Domain\Messaging\Model\UserMessageBounce; use PhpList\Core\Domain\Messaging\Repository\BounceRepository; use PhpList\Core\Domain\Messaging\Repository\UserMessageBounceRepository; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -49,7 +49,7 @@ public function testCreatePersistsAndReturnsBounce(): void $comment = 'created by test'; $this->repository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(Bounce::class)); $bounce = $this->manager->create( @@ -115,9 +115,8 @@ public function testGetByIdReturnsNullWhenNotFound(): void public function testUpdateChangesFieldsAndSaves(): void { $bounce = new Bounce(); - $this->repository->expects($this->once()) - ->method('save') - ->with($bounce); + $this->entityManager->expects($this->once()) + ->method('flush'); $updated = $this->manager->update($bounce, 'processed', 'done'); $this->assertSame($bounce, $updated); @@ -130,8 +129,6 @@ public function testLinkUserMessageBounceFlushesAndSetsFields(): void $bounce = $this->createMock(Bounce::class); $bounce->method('getId')->willReturn(77); - $this->entityManager->expects($this->once())->method('flush'); - $dt = new DateTimeImmutable('2024-05-01 12:34:56'); $umb = $this->manager->linkUserMessageBounce($bounce, $dt, 123, 456); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/BounceRegexManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/BounceRegexManagerTest.php index fd526a64..4ade0040 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/BounceRegexManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/BounceRegexManagerTest.php @@ -42,7 +42,7 @@ public function testCreateNewRegex(): void ->willReturn(null); $this->regexRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(BounceRegex::class)); $regex = $this->manager->createOrUpdateFromPattern( @@ -85,10 +85,6 @@ public function testUpdateExistingRegex(): void ->with($hash) ->willReturn($existing); - $this->regexRepository->expects($this->once()) - ->method('save') - ->with($existing); - $updated = $this->manager->createOrUpdateFromPattern( regex: $pattern, action: 'delete', @@ -134,9 +130,6 @@ public function testAssociateBounceIncrementsCountAndPersistsRelation(): void && $entity->getRegexId() === $regex->getId(); })); - $this->entityManager->expects($this->once()) - ->method('flush'); - $this->assertSame(0, $regex->getCount()); $this->manager->associateBounce($regex, $bounce); $this->assertSame(1, $regex->getCount()); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/ListMessageManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/ListMessageManagerTest.php index 2f1af5fe..26b6fee3 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/ListMessageManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/ListMessageManagerTest.php @@ -51,9 +51,6 @@ public function testAssociateMessageWithList(): void && $listMessage->getEntered() instanceof DateTime; })); - $this->entityManager->expects($this->once()) - ->method('flush'); - $result = $this->manager->associateMessageWithList($message, $subscriberList); $this->assertInstanceOf(ListMessage::class, $result); @@ -120,9 +117,6 @@ public function testAssociateMessageWithLists(): void && $listMessage->getEntered() instanceof DateTime; })); - $this->entityManager->expects($this->exactly(2)) - ->method('flush'); - $this->manager->associateMessageWithLists($message, [$subscriberList1, $subscriberList2]); } diff --git a/tests/Unit/Domain/Messaging/Service/Manager/MessageManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/MessageManagerTest.php index 94064485..ac41566f 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/MessageManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/MessageManagerTest.php @@ -66,7 +66,7 @@ public function testCreateMessageReturnsPersistedMessage(): void ->willReturn($expectedMessage); $messageRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($expectedMessage); $message = $manager->createMessage($request, $authUser); @@ -130,10 +130,6 @@ public function testUpdateMessageReturnsUpdatedMessage(): void ->with($updateRequest, $this->anything()) ->willReturn($existingMessage); - $messageRepository->expects($this->once()) - ->method('save') - ->with($existingMessage); - $message = $manager->updateMessage($updateRequest, $existingMessage, $authUser); $this->assertSame('Updated Subject', $message->getContent()->getSubject()); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/SendProcessManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/SendProcessManagerTest.php index e56f11ca..1f8c9276 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/SendProcessManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/SendProcessManagerTest.php @@ -29,7 +29,6 @@ protected function setUp(): void public function testCreatePersistsEntityAndSetsFields(): void { $this->em->expects($this->once())->method('persist')->with($this->isInstanceOf(SendProcess::class)); - $this->em->expects($this->once())->method('flush'); $sp = $this->manager->create('pageA', 'proc-1'); $this->assertInstanceOf(SendProcess::class, $sp); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/TemplateImageManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/TemplateImageManagerTest.php index 93907f02..932e0d8a 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/TemplateImageManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/TemplateImageManagerTest.php @@ -37,9 +37,6 @@ public function testCreateImagesFromImagePaths(): void ->method('persist') ->with($this->isInstanceOf(TemplateImage::class)); - $this->entityManager->expects($this->once()) - ->method('flush'); - $images = $this->manager->createImagesFromImagePaths(['image1.jpg', 'image2.png'], $template); $this->assertCount(2, $images); diff --git a/tests/Unit/Domain/Messaging/Service/Manager/TemplateManagerTest.php b/tests/Unit/Domain/Messaging/Service/Manager/TemplateManagerTest.php index d3748244..4f6544c2 100644 --- a/tests/Unit/Domain/Messaging/Service/Manager/TemplateManagerTest.php +++ b/tests/Unit/Domain/Messaging/Service/Manager/TemplateManagerTest.php @@ -4,7 +4,6 @@ namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Manager; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Messaging\Model\Dto\CreateTemplateDto; use PhpList\Core\Domain\Messaging\Model\Template; use PhpList\Core\Domain\Messaging\Repository\TemplateRepository; @@ -26,14 +25,12 @@ class TemplateManagerTest extends TestCase protected function setUp(): void { $this->templateRepository = $this->createMock(TemplateRepository::class); - $entityManager = $this->createMock(EntityManagerInterface::class); $this->templateImageManager = $this->createMock(TemplateImageManager::class); $this->templateLinkValidator = $this->createMock(TemplateLinkValidator::class); $this->templateImageValidator = $this->createMock(TemplateImageValidator::class); $this->manager = new TemplateManager( $this->templateRepository, - $entityManager, $this->templateImageManager, $this->templateLinkValidator, $this->templateImageValidator @@ -66,7 +63,7 @@ public function testCreateTemplateSuccessfully(): void ->with([], $this->anything()); $this->templateRepository->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(Template::class)); $this->templateImageManager->expects($this->once()) diff --git a/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php b/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php index 85066691..f2a29d49 100644 --- a/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php +++ b/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php @@ -4,7 +4,6 @@ namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service; -use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Analytics\Model\LinkTrack; use PhpList\Core\Domain\Analytics\Service\LinkTrackService; use PhpList\Core\Domain\Messaging\Model\Message\MessageContent; @@ -20,7 +19,6 @@ class MessageProcessingPreparatorTest extends TestCase { - private EntityManagerInterface&MockObject $entityManager; private SubscriberRepository&MockObject $subscriberRepository; private MessageRepository&MockObject $messageRepository; private LinkTrackService&MockObject $linkTrackService; @@ -29,14 +27,12 @@ class MessageProcessingPreparatorTest extends TestCase protected function setUp(): void { - $this->entityManager = $this->createMock(EntityManagerInterface::class); $this->subscriberRepository = $this->createMock(SubscriberRepository::class); $this->messageRepository = $this->createMock(MessageRepository::class); $this->linkTrackService = $this->createMock(LinkTrackService::class); $this->output = $this->createMock(OutputInterface::class); $this->preparator = new MessageProcessingPreparator( - entityManager: $this->entityManager, subscriberRepository: $this->subscriberRepository, messageRepository: $this->messageRepository, linkTrackService: $this->linkTrackService, @@ -53,9 +49,6 @@ public function testEnsureSubscribersHaveUuidWithNoSubscribers(): void $this->output->expects($this->never()) ->method('writeln'); - $this->entityManager->expects($this->never()) - ->method('flush'); - $this->preparator->ensureSubscribersHaveUuid($this->output); } @@ -82,9 +75,6 @@ public function testEnsureSubscribersHaveUuidWithSubscribers(): void ->method('setUniqueId') ->with($this->isType('string')); - $this->entityManager->expects($this->once()) - ->method('flush'); - $this->preparator->ensureSubscribersHaveUuid($this->output); } @@ -97,9 +87,6 @@ public function testEnsureCampaignsHaveUuidWithNoCampaigns(): void $this->output->expects($this->never()) ->method('writeln'); - $this->entityManager->expects($this->never()) - ->method('flush'); - $this->preparator->ensureCampaignsHaveUuid($this->output); } @@ -126,9 +113,6 @@ public function testEnsureCampaignsHaveUuidWithCampaigns(): void ->method('setUuid') ->with($this->isType('string')); - $this->entityManager->expects($this->once()) - ->method('flush'); - $this->preparator->ensureCampaignsHaveUuid($this->output); } diff --git a/tests/Unit/Domain/Subscription/Service/Manager/AttributeDefinitionManagerTest.php b/tests/Unit/Domain/Subscription/Service/Manager/AttributeDefinitionManagerTest.php index 7e7bcfb7..6a047051 100644 --- a/tests/Unit/Domain/Subscription/Service/Manager/AttributeDefinitionManagerTest.php +++ b/tests/Unit/Domain/Subscription/Service/Manager/AttributeDefinitionManagerTest.php @@ -39,7 +39,7 @@ public function testCreateAttributeDefinition(): void ->with('Country') ->willReturn(null); - $repository->expects($this->once())->method('save'); + $repository->expects($this->once())->method('persist'); $attribute = $manager->create($dto); @@ -110,8 +110,6 @@ public function testUpdateAttributeDefinition(): void ->with('New') ->willReturn(null); - $repository->expects($this->once())->method('save')->with($attribute); - $updated = $manager->update($attribute, $dto); $this->assertSame('New', $updated->getName()); diff --git a/tests/Unit/Domain/Subscription/Service/Manager/SubscribePageManagerTest.php b/tests/Unit/Domain/Subscription/Service/Manager/SubscribePageManagerTest.php index 6add5016..0c29242a 100644 --- a/tests/Unit/Domain/Subscription/Service/Manager/SubscribePageManagerTest.php +++ b/tests/Unit/Domain/Subscription/Service/Manager/SubscribePageManagerTest.php @@ -42,7 +42,7 @@ public function testCreatePageCreatesAndSaves(): void $owner = new Administrator(); $this->pageRepository ->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(SubscribePage::class)); $page = $this->manager->createPage('My Page', true, $owner); @@ -91,7 +91,7 @@ public function testUpdatePageUpdatesProvidedFieldsAndFlushes(): void ->setOwner($originalOwner); $this->entityManager - ->expects($this->once()) + ->expects($this->never()) ->method('flush'); $updated = $this->manager->updatePage($page, title: 'New Title', active: true, owner: $newOwner); @@ -111,7 +111,7 @@ public function testUpdatePageLeavesNullFieldsUntouched(): void ->setOwner($owner); $this->entityManager - ->expects($this->once()) + ->expects($this->never()) ->method('flush'); $updated = $this->manager->updatePage(page: $page, title: null, active: null, owner: null); @@ -121,14 +121,14 @@ public function testUpdatePageLeavesNullFieldsUntouched(): void $this->assertSame($owner, $updated->getOwner()); } - public function testSetActiveSetsFlagAndFlushes(): void + public function testSetActiveSetsFlagButNDoesotFlush(): void { $page = (new SubscribePage()) ->setTitle('Any') ->setActive(false); $this->entityManager - ->expects($this->once()) + ->expects($this->never()) ->method('flush'); $this->manager->setActive($page, true); @@ -194,10 +194,6 @@ public function testSetPageDataUpdatesExistingDataAndFlushes(): void ->expects($this->never()) ->method('persist'); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $result = $this->manager->setPageData($page, 'color', 'blue'); $this->assertSame($existing, $result); @@ -222,10 +218,6 @@ public function testSetPageDataCreatesNewWhenMissingAndPersistsAndFlushes(): voi ->method('persist') ->with($this->isInstanceOf(SubscribePageData::class)); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $result = $this->manager->setPageData($page, 'greeting', 'hello'); $this->assertInstanceOf(SubscribePageData::class, $result); diff --git a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberBlacklistManagerTest.php b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberBlacklistManagerTest.php index 25fdf5ca..16ca73bd 100644 --- a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberBlacklistManagerTest.php +++ b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberBlacklistManagerTest.php @@ -106,10 +106,6 @@ public function testAddEmailToBlacklistAddsEntryAndReason(): void [$this->isInstanceOf(UserBlacklistData::class)] ); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $this->manager->addEmailToBlacklist('new@blacklist.com', 'test reason'); } @@ -126,10 +122,6 @@ public function testAddEmailToBlacklistAddsEntryWithoutReason(): void ->method('persist') ->with($this->isInstanceOf(UserBlacklist::class)); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $this->manager->addEmailToBlacklist('noreason@blacklist.com'); } @@ -166,10 +158,6 @@ public function testRemoveEmailFromBlacklistRemovesAllRelatedData(): void $subscriber->expects($this->once())->method('setBlacklisted')->with(false); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $this->manager->removeEmailFromBlacklist('remove@me.com'); } diff --git a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberListManagerTest.php b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberListManagerTest.php index c913518f..cf4dbf9c 100644 --- a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberListManagerTest.php +++ b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberListManagerTest.php @@ -36,7 +36,7 @@ public function testCreateSubscriberList(): void $this->subscriberListRepository ->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->isInstanceOf(SubscriberList::class)); $result = $this->manager->createSubscriberList($request, $admin); diff --git a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberManagerTest.php b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberManagerTest.php index 4f11c393..aaff7298 100644 --- a/tests/Unit/Domain/Subscription/Service/Manager/SubscriberManagerTest.php +++ b/tests/Unit/Domain/Subscription/Service/Manager/SubscriberManagerTest.php @@ -40,7 +40,7 @@ public function testCreateSubscriberPersistsAndReturnsProperlyInitializedEntity( { $this->subscriberRepository ->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (Subscriber $sub): bool { return $sub->getEmail() === 'foo@bar.com' && $sub->isConfirmed() === true @@ -65,7 +65,7 @@ public function testCreateSubscriberPersists(): void { $this->subscriberRepository ->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (Subscriber $sub): bool { $sub->setUniqueId('test-unique-id-456'); return $sub->getEmail() === 'foo@bar.com' @@ -91,7 +91,7 @@ public function testCreateSubscriberWithConfirmation(): void $capturedSubscriber = null; $this->subscriberRepository ->expects($this->once()) - ->method('save') + ->method('persist') ->with($this->callback(function (Subscriber $subscriber) use (&$capturedSubscriber) { $capturedSubscriber = $subscriber; $subscriber->setUniqueId('test-unique-id-123'); @@ -111,7 +111,7 @@ public function testCreateSubscriberWithoutConfirmation(): void { $this->subscriberRepository ->expects($this->once()) - ->method('save'); + ->method('persist'); $dto = new CreateSubscriberDto(email: 'test@example.com', requestConfirmation: false, htmlEmail: true); $this->subscriberManager->createSubscriber($dto); @@ -133,10 +133,6 @@ public function testMarkAsConfirmedByUniqueIdConfirmsSubscriber(): void ->method('setConfirmed') ->with(true); - $this->entityManager - ->expects($this->once()) - ->method('flush'); - $result = $this->subscriberManager->markAsConfirmedByUniqueId($uniqueId); $this->assertSame($subscriber, $result); diff --git a/tests/Unit/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessorTest.php b/tests/Unit/Processor/AdvancedBounceRulesProcessorTest.php similarity index 96% rename from tests/Unit/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessorTest.php rename to tests/Unit/Processor/AdvancedBounceRulesProcessorTest.php index a4590052..7a57980d 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/AdvancedBounceRulesProcessorTest.php +++ b/tests/Unit/Processor/AdvancedBounceRulesProcessorTest.php @@ -2,15 +2,15 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Processor; +use PhpList\Core\Bounce\Service\BounceActionResolver; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Processor\AdvancedBounceRulesProcessor; use PhpList\Core\Domain\Messaging\Model\Bounce; use PhpList\Core\Domain\Messaging\Model\BounceRegex; use PhpList\Core\Domain\Messaging\Model\UserMessageBounce; -use PhpList\Core\Domain\Messaging\Service\BounceActionResolver; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Messaging\Service\Manager\BounceRuleManager; -use PhpList\Core\Domain\Messaging\Service\Processor\AdvancedBounceRulesProcessor; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Domain/Messaging/Service/Processor/BounceDataProcessorTest.php b/tests/Unit/Processor/BounceDataProcessorTest.php similarity index 96% rename from tests/Unit/Domain/Messaging/Service/Processor/BounceDataProcessorTest.php rename to tests/Unit/Processor/BounceDataProcessorTest.php index b7009cd9..d5d901c0 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/BounceDataProcessorTest.php +++ b/tests/Unit/Processor/BounceDataProcessorTest.php @@ -2,17 +2,18 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Processor; use DateTimeImmutable; +use Doctrine\ORM\EntityManagerInterface; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\Processor\BounceDataProcessor; use PhpList\Core\Domain\Messaging\Model\Bounce; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceDataProcessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; @@ -47,6 +48,7 @@ private function makeProcessor(): BounceDataProcessor logger: $this->logger, subscriberManager: $this->subscriberManager, subscriberHistoryManager: $this->historyManager, + entityManager: $this->createMock(EntityManagerInterface::class), ); } diff --git a/tests/Unit/Domain/Messaging/Service/Processor/MboxBounceProcessorTest.php b/tests/Unit/Processor/MboxBounceProcessorTest.php similarity index 92% rename from tests/Unit/Domain/Messaging/Service/Processor/MboxBounceProcessorTest.php rename to tests/Unit/Processor/MboxBounceProcessorTest.php index 9bf1c92f..a67235dd 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/MboxBounceProcessorTest.php +++ b/tests/Unit/Processor/MboxBounceProcessorTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Processor; -use PhpList\Core\Domain\Messaging\Service\BounceProcessingServiceInterface; -use PhpList\Core\Domain\Messaging\Service\Processor\MboxBounceProcessor; +use PhpList\Core\Bounce\Service\BounceProcessingServiceInterface; +use PhpList\Core\Bounce\Service\Processor\MboxBounceProcessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use RuntimeException; diff --git a/tests/Unit/Domain/Messaging/Service/Processor/PopBounceProcessorTest.php b/tests/Unit/Processor/PopBounceProcessorTest.php similarity index 91% rename from tests/Unit/Domain/Messaging/Service/Processor/PopBounceProcessorTest.php rename to tests/Unit/Processor/PopBounceProcessorTest.php index d0141386..d218edd0 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/PopBounceProcessorTest.php +++ b/tests/Unit/Processor/PopBounceProcessorTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Processor; -use PhpList\Core\Domain\Messaging\Service\BounceProcessingServiceInterface; -use PhpList\Core\Domain\Messaging\Service\Processor\PopBounceProcessor; +use PhpList\Core\Bounce\Service\BounceProcessingServiceInterface; +use PhpList\Core\Bounce\Service\Processor\PopBounceProcessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Input\InputInterface; diff --git a/tests/Unit/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessorTest.php b/tests/Unit/Processor/UnidentifiedBounceReprocessorTest.php similarity index 89% rename from tests/Unit/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessorTest.php rename to tests/Unit/Processor/UnidentifiedBounceReprocessorTest.php index ac1c9173..0e2d2254 100644 --- a/tests/Unit/Domain/Messaging/Service/Processor/UnidentifiedBounceReprocessorTest.php +++ b/tests/Unit/Processor/UnidentifiedBounceReprocessorTest.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Unit\Domain\Messaging\Service\Processor; +namespace PhpList\Core\Tests\Unit\Processor; use DateTimeImmutable; +use PhpList\Core\Bounce\Service\Manager\BounceManager; +use PhpList\Core\Bounce\Service\MessageParser; +use PhpList\Core\Bounce\Service\Processor\BounceDataProcessor; +use PhpList\Core\Bounce\Service\Processor\UnidentifiedBounceReprocessor; use PhpList\Core\Domain\Messaging\Model\Bounce; -use PhpList\Core\Domain\Messaging\Service\Manager\BounceManager; -use PhpList\Core\Domain\Messaging\Service\MessageParser; -use PhpList\Core\Domain\Messaging\Service\Processor\BounceDataProcessor; -use PhpList\Core\Domain\Messaging\Service\Processor\UnidentifiedBounceReprocessor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Style\SymfonyStyle;