From eaa26fc82b5f776725905f3cd51404b07e530c09 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Mon, 13 Oct 2025 11:06:45 +0400 Subject: [PATCH 01/10] Fix composer json --- composer.json | 16 ++++++++++++++-- src/Messaging/Controller/CampaignController.php | 15 +++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index ba5526c..4db23ce 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,12 @@ "role": "Maintainer" } ], + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/TatevikGr/rss-bundle.git" + } + ], "support": { "issues": "https://github.com/phpList/rest-api/issues", "forum": "https://discuss.phplist.org/", @@ -36,12 +42,13 @@ }, "require": { "php": "^8.1", - "phplist/core": "dev-dev", + "phplist/core": "dev-em-flush", "friendsofsymfony/rest-bundle": "*", "symfony/test-pack": "^1.0", "symfony/process": "^6.4", "zircote/swagger-php": "^4.11", - "ext-dom": "*" + "ext-dom": "*", + "tatevikgr/rss-feed": "dev-main as 0.1.0" }, "require-dev": { "phpunit/phpunit": "^10.0", @@ -123,5 +130,10 @@ } } } + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } } } diff --git a/src/Messaging/Controller/CampaignController.php b/src/Messaging/Controller/CampaignController.php index d897706..ed4d770 100644 --- a/src/Messaging/Controller/CampaignController.php +++ b/src/Messaging/Controller/CampaignController.php @@ -6,7 +6,6 @@ use OpenApi\Attributes as OA; use PhpList\Core\Domain\Messaging\Model\Message; -use PhpList\Core\Domain\Messaging\Service\Processor\CampaignProcessor; use PhpList\Core\Security\Authentication; use PhpList\RestBundle\Common\Controller\BaseController; use PhpList\RestBundle\Common\Validator\RequestValidator; @@ -17,7 +16,9 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Messenger\Stamp\TransportNamesStamp; /** * This controller provides REST API to manage campaigns. @@ -28,17 +29,17 @@ class CampaignController extends BaseController { private CampaignService $campaignService; - private CampaignProcessor $campaignProcessor; + private MessageBusInterface $messageBus; public function __construct( Authentication $authentication, RequestValidator $validator, CampaignService $campaignService, - CampaignProcessor $campaignProcessor, + MessageBusInterface $messageBus, ) { parent::__construct($authentication, $validator); $this->campaignService = $campaignService; - $this->campaignProcessor = $campaignProcessor; + $this->messageBus = $messageBus; } #[Route('', name: 'get_list', methods: ['GET'])] @@ -388,8 +389,10 @@ public function sendMessage( throw $this->createNotFoundException('Campaign not found.'); } - $this->campaignProcessor->process($message); - + $this->messageBus->dispatch( + new CampaignProcessorMessage($message->getId()), + [new TransportNamesStamp(['sync'])] + ); return $this->json($this->campaignService->getMessage($message), Response::HTTP_OK); } } From 6532db03fb37e845e03faf14313a2dfaf624ed19 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 14 Oct 2025 15:19:38 +0400 Subject: [PATCH 02/10] Add flush after delete --- .../Controller/AdminAttributeDefinitionController.php | 5 ++++- src/Identity/Controller/AdminAttributeValueController.php | 2 ++ src/Identity/Controller/SessionController.php | 4 ++++ src/Messaging/Controller/BounceRegexController.php | 3 +++ src/Messaging/Controller/CampaignController.php | 4 ++++ src/Messaging/Controller/TemplateController.php | 3 +++ src/Messaging/Service/CampaignService.php | 3 +++ src/Subscription/Controller/SubscribePageController.php | 3 +++ .../Controller/SubscriberAttributeDefinitionController.php | 5 ++++- .../Controller/SubscriberAttributeValueController.php | 6 +++++- src/Subscription/Controller/SubscriberController.php | 2 +- src/Subscription/Controller/SubscriberListController.php | 6 ++++++ src/Subscription/Service/SubscriberService.php | 5 +++-- tests/Unit/Subscription/Service/SubscriberServiceTest.php | 4 +++- 14 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/Identity/Controller/AdminAttributeDefinitionController.php b/src/Identity/Controller/AdminAttributeDefinitionController.php index 772a56d..c5678e4 100644 --- a/src/Identity/Controller/AdminAttributeDefinitionController.php +++ b/src/Identity/Controller/AdminAttributeDefinitionController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Identity\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\AdminAttributeDefinition; use PhpList\Core\Domain\Identity\Service\AdminAttributeDefinitionManager; @@ -32,7 +33,8 @@ public function __construct( RequestValidator $validator, AdminAttributeDefinitionManager $definitionManager, AdminAttributeDefinitionNormalizer $normalizer, - PaginatedDataProvider $paginatedDataProvider + PaginatedDataProvider $paginatedDataProvider, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->definitionManager = $definitionManager; @@ -211,6 +213,7 @@ public function delete( } $this->definitionManager->delete($attributeDefinition); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Identity/Controller/AdminAttributeValueController.php b/src/Identity/Controller/AdminAttributeValueController.php index 964bd83..573608b 100644 --- a/src/Identity/Controller/AdminAttributeValueController.php +++ b/src/Identity/Controller/AdminAttributeValueController.php @@ -198,6 +198,7 @@ public function delete( throw $this->createNotFoundException('Administrator attribute not found.'); } $this->attributeManager->delete($attribute); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } @@ -355,6 +356,7 @@ public function getAttributeDefinition( attributeDefinitionId: $definition->getId() ); $this->attributeManager->delete($attribute); + $this->entityManager->flush(); return $this->json( $this->normalizer->normalize($attribute), diff --git a/src/Identity/Controller/SessionController.php b/src/Identity/Controller/SessionController.php index 5f58811..66b49ce 100644 --- a/src/Identity/Controller/SessionController.php +++ b/src/Identity/Controller/SessionController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Identity\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\AdministratorToken; use PhpList\Core\Domain\Identity\Service\SessionManager; @@ -34,6 +35,7 @@ public function __construct( Authentication $authentication, RequestValidator $validator, SessionManager $sessionManager, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); @@ -96,6 +98,7 @@ public function createSession( loginName:$createSessionRequest->loginName, password: $createSessionRequest->password ); + $this->entityManager->flush(); $json = $normalizer->normalize($token, 'json'); @@ -163,6 +166,7 @@ public function deleteSession( } $this->sessionManager->deleteSession($token); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Messaging/Controller/BounceRegexController.php b/src/Messaging/Controller/BounceRegexController.php index 7f3f275..198b27e 100644 --- a/src/Messaging/Controller/BounceRegexController.php +++ b/src/Messaging/Controller/BounceRegexController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Messaging\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Messaging\Service\Manager\BounceRegexManager; use PhpList\Core\Security\Authentication; @@ -27,6 +28,7 @@ public function __construct( RequestValidator $validator, private readonly BounceRegexManager $manager, private readonly BounceRegexNormalizer $normalizer, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); } @@ -240,6 +242,7 @@ public function delete(Request $request, string $regexHash): JsonResponse throw $this->createNotFoundException('Bounce regex not found.'); } $this->manager->delete($entity); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Messaging/Controller/CampaignController.php b/src/Messaging/Controller/CampaignController.php index ed4d770..415423c 100644 --- a/src/Messaging/Controller/CampaignController.php +++ b/src/Messaging/Controller/CampaignController.php @@ -4,7 +4,9 @@ namespace PhpList\RestBundle\Messaging\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; +use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Security\Authentication; use PhpList\RestBundle\Common\Controller\BaseController; @@ -36,6 +38,7 @@ public function __construct( RequestValidator $validator, CampaignService $campaignService, MessageBusInterface $messageBus, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->campaignService = $campaignService; @@ -340,6 +343,7 @@ public function deleteMessage( $authUser = $this->requireAuthentication($request); $this->campaignService->deleteMessage($authUser, $message); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Messaging/Controller/TemplateController.php b/src/Messaging/Controller/TemplateController.php index b814c89..5186c2a 100644 --- a/src/Messaging/Controller/TemplateController.php +++ b/src/Messaging/Controller/TemplateController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Messaging\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Messaging\Model\Template; use PhpList\Core\Domain\Messaging\Service\Manager\TemplateManager; @@ -37,6 +38,7 @@ public function __construct( TemplateNormalizer $normalizer, TemplateManager $templateManager, PaginatedDataProvider $paginatedDataProvider, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->normalizer = $normalizer; @@ -318,6 +320,7 @@ public function delete( } $this->templateManager->delete($template); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Messaging/Service/CampaignService.php b/src/Messaging/Service/CampaignService.php index d2cd8c0..4bc9e3c 100644 --- a/src/Messaging/Service/CampaignService.php +++ b/src/Messaging/Service/CampaignService.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Messaging\Service; +use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Identity\Model\Administrator; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Messaging\Model\Filter\MessageFilter; @@ -23,6 +24,7 @@ public function __construct( private readonly MessageManager $messageManager, private readonly PaginatedDataProvider $paginatedProvider, private readonly MessageNormalizer $normalizer, + private readonly EntityManagerInterface $entityManager, ) { } @@ -86,5 +88,6 @@ public function deleteMessage(Administrator $administrator, Message $message = n } $this->messageManager->delete($message); + $this->entityManager->flush(); } } diff --git a/src/Subscription/Controller/SubscribePageController.php b/src/Subscription/Controller/SubscribePageController.php index 8f3878c..816bb78 100644 --- a/src/Subscription/Controller/SubscribePageController.php +++ b/src/Subscription/Controller/SubscribePageController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Subscription\Model\SubscribePage; @@ -28,6 +29,7 @@ public function __construct( RequestValidator $validator, private readonly SubscribePageManager $subscribePageManager, private readonly SubscribePageNormalizer $normalizer, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); } @@ -141,6 +143,7 @@ public function createPage(Request $request): JsonResponse $createRequest = $this->validator->validate($request, SubscribePageRequest::class); $page = $this->subscribePageManager->createPage($createRequest->title, $createRequest->active, $admin); + $this->entityManager->flush(); return $this->json($this->normalizer->normalize($page), Response::HTTP_CREATED); } diff --git a/src/Subscription/Controller/SubscriberAttributeDefinitionController.php b/src/Subscription/Controller/SubscriberAttributeDefinitionController.php index 6d7bad3..a6395f3 100644 --- a/src/Subscription/Controller/SubscriberAttributeDefinitionController.php +++ b/src/Subscription/Controller/SubscriberAttributeDefinitionController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeDefinition; use PhpList\Core\Domain\Subscription\Service\Manager\AttributeDefinitionManager; @@ -32,7 +33,8 @@ public function __construct( RequestValidator $validator, AttributeDefinitionManager $definitionManager, AttributeDefinitionNormalizer $normalizer, - PaginatedDataProvider $paginatedDataProvider + PaginatedDataProvider $paginatedDataProvider, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->definitionManager = $definitionManager; @@ -209,6 +211,7 @@ public function delete( } $this->definitionManager->delete($attributeDefinition); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } diff --git a/src/Subscription/Controller/SubscriberAttributeValueController.php b/src/Subscription/Controller/SubscriberAttributeValueController.php index 834b097..24b5420 100644 --- a/src/Subscription/Controller/SubscriberAttributeValueController.php +++ b/src/Subscription/Controller/SubscriberAttributeValueController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Subscription\Model\Filter\SubscriberAttributeValueFilter; use PhpList\Core\Domain\Subscription\Model\Subscriber; @@ -33,7 +34,8 @@ public function __construct( RequestValidator $validator, SubscriberAttributeManager $attributeManager, SubscriberAttributeValueNormalizer $normalizer, - PaginatedDataProvider $paginatedDataProvider + PaginatedDataProvider $paginatedDataProvider, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->attributeManager = $attributeManager; @@ -193,6 +195,7 @@ public function delete( throw $this->createNotFoundException('Subscriber attribute not found.'); } $this->attributeManager->delete($attribute); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } @@ -349,6 +352,7 @@ public function getAttributeDefinition( } $attribute = $this->attributeManager->getSubscriberAttribute($subscriber->getId(), $definition->getId()); $this->attributeManager->delete($attribute); + $this->entityManager->flush(); return $this->json( $this->normalizer->normalize($attribute), diff --git a/src/Subscription/Controller/SubscriberController.php b/src/Subscription/Controller/SubscriberController.php index f053dff..463261b 100644 --- a/src/Subscription/Controller/SubscriberController.php +++ b/src/Subscription/Controller/SubscriberController.php @@ -163,7 +163,7 @@ public function updateSubscriber( } /** @var UpdateSubscriberRequest $updateSubscriberRequest */ $updateSubscriberRequest = $this->validator->validate($request, UpdateSubscriberRequest::class); - $subscriberData = $this->subscriberService->updateSubscriber($updateSubscriberRequest); + $subscriberData = $this->subscriberService->updateSubscriber($updateSubscriberRequest, $admin); return $this->json($subscriberData, Response::HTTP_OK); } diff --git a/src/Subscription/Controller/SubscriberListController.php b/src/Subscription/Controller/SubscriberListController.php index a0ea079..304c343 100644 --- a/src/Subscription/Controller/SubscriberListController.php +++ b/src/Subscription/Controller/SubscriberListController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Subscription\Model\SubscriberList; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberListManager; @@ -32,6 +33,7 @@ class SubscriberListController extends BaseController private SubscriberListNormalizer $normalizer; private SubscriberListManager $subscriberListManager; private PaginatedDataProvider $paginatedDataProvider; + private EntityManagerInterface $entityManager; public function __construct( Authentication $authentication, @@ -39,11 +41,13 @@ public function __construct( SubscriberListNormalizer $normalizer, SubscriberListManager $subscriberListManager, PaginatedDataProvider $paginatedDataProvider, + EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->normalizer = $normalizer; $this->subscriberListManager = $subscriberListManager; $this->paginatedDataProvider = $paginatedDataProvider; + $this->entityManager = $entityManager; } #[Route('', name: 'get_list', methods: ['GET'])] @@ -223,6 +227,7 @@ public function deleteList( } $this->subscriberListManager->delete($list); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } @@ -273,6 +278,7 @@ public function createList(Request $request, SubscriberListNormalizer $normalize /** @var CreateSubscriberListRequest $subscriberListRequest */ $subscriberListRequest = $this->validator->validate($request, CreateSubscriberListRequest::class); $data = $this->subscriberListManager->createSubscriberList($subscriberListRequest->getDto(), $authUser); + $this->entityManager->flush(); return $this->json($normalizer->normalize($data), Response::HTTP_CREATED); } diff --git a/src/Subscription/Service/SubscriberService.php b/src/Subscription/Service/SubscriberService.php index 2ddce62..b3acd21 100644 --- a/src/Subscription/Service/SubscriberService.php +++ b/src/Subscription/Service/SubscriberService.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Service; +use PhpList\Core\Domain\Identity\Model\Administrator; use PhpList\Core\Domain\Subscription\Model\Subscriber; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PhpList\RestBundle\Subscription\Request\CreateSubscriberRequest; @@ -32,9 +33,9 @@ public function createSubscriber(CreateSubscriberRequest $subscriberRequest): ar return $this->subscriberNormalizer->normalize($subscriber, 'json'); } - public function updateSubscriber(UpdateSubscriberRequest $updateSubscriberRequest): array + public function updateSubscriber(UpdateSubscriberRequest $updateSubscriberRequest, Administrator $admin): array { - $subscriber = $this->subscriberManager->updateSubscriber($updateSubscriberRequest->getDto()); + $subscriber = $this->subscriberManager->updateSubscriber($updateSubscriberRequest->getDto(), $admin); return $this->subscriberNormalizer->normalize($subscriber, 'json'); } diff --git a/tests/Unit/Subscription/Service/SubscriberServiceTest.php b/tests/Unit/Subscription/Service/SubscriberServiceTest.php index ffc27dc..a37d177 100644 --- a/tests/Unit/Subscription/Service/SubscriberServiceTest.php +++ b/tests/Unit/Subscription/Service/SubscriberServiceTest.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Tests\Unit\Subscription\Service; +use PhpList\Core\Domain\Identity\Model\Administrator; use PhpList\Core\Domain\Subscription\Model\Dto\CreateSubscriberDto; use PhpList\Core\Domain\Subscription\Model\Dto\UpdateSubscriberDto; use PhpList\Core\Domain\Subscription\Model\Subscriber; @@ -70,6 +71,7 @@ public function testUpdateSubscriberReturnsNormalizedSubscriber(): void $updateSubscriberRequest = $this->createMock(UpdateSubscriberRequest::class); $subscriber = $this->createMock(Subscriber::class); $expectedResult = ['id' => 1, 'email' => 'updated@example.com']; + $admin = $this->createMock(Administrator::class); $updateSubscriberRequest->expects($this->once()) ->method('getDto') @@ -85,7 +87,7 @@ public function testUpdateSubscriberReturnsNormalizedSubscriber(): void ->with($this->identicalTo($subscriber), 'json') ->willReturn($expectedResult); - $result = $this->subscriberService->updateSubscriber($updateSubscriberRequest); + $result = $this->subscriberService->updateSubscriber($updateSubscriberRequest, $admin); $this->assertSame($expectedResult, $result); } From 6c451ca2fdab16911a0ac88e677b0e3a5594bca4 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 10:31:07 +0400 Subject: [PATCH 03/10] Fix: test --- config/services/messenger_handlers.yml | 5 +++++ src/Messaging/Controller/CampaignController.php | 9 +++------ tests/Unit/Messaging/Service/CampaignServiceTest.php | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 config/services/messenger_handlers.yml diff --git a/config/services/messenger_handlers.yml b/config/services/messenger_handlers.yml new file mode 100644 index 0000000..9073d52 --- /dev/null +++ b/config/services/messenger_handlers.yml @@ -0,0 +1,5 @@ +services: + PhpList\Core\Domain\Messaging\MessageHandler\CampaignProcessorMessageHandler: + autowire: true + autoconfigure: true + public: false diff --git a/src/Messaging/Controller/CampaignController.php b/src/Messaging/Controller/CampaignController.php index 415423c..305d525 100644 --- a/src/Messaging/Controller/CampaignController.php +++ b/src/Messaging/Controller/CampaignController.php @@ -6,7 +6,7 @@ use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; -use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; +use PhpList\Core\Domain\Messaging\Message\SyncCampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Security\Authentication; use PhpList\RestBundle\Common\Controller\BaseController; @@ -20,7 +20,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; -use Symfony\Component\Messenger\Stamp\TransportNamesStamp; /** * This controller provides REST API to manage campaigns. @@ -393,10 +392,8 @@ public function sendMessage( throw $this->createNotFoundException('Campaign not found.'); } - $this->messageBus->dispatch( - new CampaignProcessorMessage($message->getId()), - [new TransportNamesStamp(['sync'])] - ); + $this->messageBus->dispatch(new SyncCampaignProcessorMessage($message->getId())); + return $this->json($this->campaignService->getMessage($message), Response::HTTP_OK); } } diff --git a/tests/Unit/Messaging/Service/CampaignServiceTest.php b/tests/Unit/Messaging/Service/CampaignServiceTest.php index 0a3d2e4..e328fe9 100644 --- a/tests/Unit/Messaging/Service/CampaignServiceTest.php +++ b/tests/Unit/Messaging/Service/CampaignServiceTest.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Tests\Unit\Messaging\Service; +use Doctrine\ORM\EntityManagerInterface; use PhpList\Core\Domain\Identity\Model\Administrator; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Identity\Model\Privileges; @@ -37,9 +38,10 @@ protected function setUp(): void $this->normalizer = $this->createMock(MessageNormalizer::class); $this->campaignService = new CampaignService( - $this->messageManager, - $this->paginatedProvider, - $this->normalizer + messageManager: $this->messageManager, + paginatedProvider: $this->paginatedProvider, + normalizer: $this->normalizer, + entityManager: $this->createMock(EntityManagerInterface::class), ); } From 8f4c66056b78785cb4248dfd89befbe4a9da8368 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 11:05:09 +0400 Subject: [PATCH 04/10] SubscriberBlacklistManager --- src/Subscription/Controller/BlacklistController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Subscription/Controller/BlacklistController.php b/src/Subscription/Controller/BlacklistController.php index f76b094..9b4e958 100644 --- a/src/Subscription/Controller/BlacklistController.php +++ b/src/Subscription/Controller/BlacklistController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberBlacklistManager; @@ -31,6 +32,7 @@ public function __construct( RequestValidator $validator, SubscriberBlacklistManager $blacklistManager, UserBlacklistNormalizer $normalizer, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->authentication = $authentication; @@ -156,6 +158,7 @@ public function addEmailToBlacklist(Request $request): JsonResponse email: $definitionRequest->email, reasonData: $definitionRequest->reason ); + $this->entityManager->flush(); $json = $this->normalizer->normalize($userBlacklisted, 'json'); return $this->json($json, Response::HTTP_CREATED); @@ -209,6 +212,7 @@ public function removeEmailFromBlacklist(Request $request, string $email): JsonR } $this->blacklistManager->removeEmailFromBlacklist($email); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } From 82fade73f09286ebb79cbccf6ca8abeb44531cc6 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 11:12:12 +0400 Subject: [PATCH 05/10] listMessageManager --- src/Messaging/Controller/ListMessageController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Messaging/Controller/ListMessageController.php b/src/Messaging/Controller/ListMessageController.php index 0ee3eb9..f67c8fa 100644 --- a/src/Messaging/Controller/ListMessageController.php +++ b/src/Messaging/Controller/ListMessageController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Messaging\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Service\Manager\ListMessageManager; @@ -37,7 +38,8 @@ public function __construct( ListMessageManager $listMessageManager, ListMessageNormalizer $listMessageNormalizer, SubscriberListNormalizer $subscriberListNormalizer, - MessageNormalizer $messageNormalizer + MessageNormalizer $messageNormalizer, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->listMessageManager = $listMessageManager; @@ -262,6 +264,7 @@ public function associateMessageWithList( } $listMessage = $this->listMessageManager->associateMessageWithList($message, $subscriberList); + $this->entityManager->flush(); return $this->json( data: $this->listMessageNormalizer->normalize($listMessage), From 9f5e9290ea6579cc9411fe10e4cd7b9f8f9a4e4d Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 11:25:45 +0400 Subject: [PATCH 06/10] AdminController flush --- src/Identity/Controller/AdministratorController.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Identity/Controller/AdministratorController.php b/src/Identity/Controller/AdministratorController.php index 77e9288..365cf12 100644 --- a/src/Identity/Controller/AdministratorController.php +++ b/src/Identity/Controller/AdministratorController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Identity\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\Administrator; use PhpList\Core\Domain\Identity\Service\AdministratorManager; @@ -35,7 +36,8 @@ public function __construct( RequestValidator $validator, AdministratorManager $administratorManager, AdministratorNormalizer $normalizer, - PaginatedDataProvider $paginatedProvider + PaginatedDataProvider $paginatedProvider, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->administratorManager = $administratorManager; @@ -149,6 +151,7 @@ public function createAdministrator( $createRequest = $validator->validate($request, CreateAdministratorRequest::class); $administrator = $this->administratorManager->createAdministrator($createRequest->getDto()); + $this->entityManager->flush(); $json = $normalizer->normalize($administrator, 'json'); return $this->json($json, Response::HTTP_CREATED); @@ -255,6 +258,7 @@ public function updateAdministrator( /** @var UpdateAdministratorRequest $updateRequest */ $updateRequest = $this->validator->validate($request, UpdateAdministratorRequest::class); $this->administratorManager->updateAdministrator($administrator, $updateRequest->getDto()); + $this->entityManager->flush(); return $this->json($this->normalizer->normalize($administrator), Response::HTTP_OK); } @@ -303,6 +307,7 @@ public function deleteAdministrator( throw $this->createNotFoundException('Administrator not found.'); } $this->administratorManager->deleteAdministrator($administrator); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } From 0c600e1b627dc024a4547955f7f5c6ac0edd88d9 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 11:34:00 +0400 Subject: [PATCH 07/10] TemplateController flush --- src/Messaging/Controller/TemplateController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Messaging/Controller/TemplateController.php b/src/Messaging/Controller/TemplateController.php index 5186c2a..bc24a02 100644 --- a/src/Messaging/Controller/TemplateController.php +++ b/src/Messaging/Controller/TemplateController.php @@ -262,9 +262,11 @@ public function createTemplates(Request $request): JsonResponse /** @var CreateTemplateRequest $createTemplateRequest */ $createTemplateRequest = $this->validator->validate($request, CreateTemplateRequest::class); + $template = $this->templateManager->create($createTemplateRequest->getDto()); + $this->entityManager->flush(); return $this->json( - $this->normalizer->normalize($this->templateManager->create($createTemplateRequest->getDto())), + $this->normalizer->normalize($template), Response::HTTP_CREATED ); } From 8ec3673e81ce2b892f2d82c3c7ff592dca44cf27 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Tue, 21 Oct 2025 11:35:55 +0400 Subject: [PATCH 08/10] SubscribePageController flush --- src/Subscription/Controller/SubscribePageController.php | 1 + src/Subscription/Controller/SubscriberController.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/Subscription/Controller/SubscribePageController.php b/src/Subscription/Controller/SubscribePageController.php index 816bb78..38117c8 100644 --- a/src/Subscription/Controller/SubscribePageController.php +++ b/src/Subscription/Controller/SubscribePageController.php @@ -426,6 +426,7 @@ public function setPageData( $createRequest = $this->validator->validate($request, SubscribePageDataRequest::class); $item = $this->subscribePageManager->setPageData($page, $createRequest->name, $createRequest->value); + $this->entityManager->flush(); return $this->json([ 'id' => $item->getId(), diff --git a/src/Subscription/Controller/SubscriberController.php b/src/Subscription/Controller/SubscriberController.php index 463261b..b9fb017 100644 --- a/src/Subscription/Controller/SubscriberController.php +++ b/src/Subscription/Controller/SubscriberController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Subscription\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Subscription\Model\Subscriber; @@ -34,6 +35,7 @@ public function __construct( Authentication $authentication, RequestValidator $validator, SubscriberService $subscriberService, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->authentication = $authentication; @@ -439,6 +441,7 @@ public function resetBounceCount( } $subscriberData = $this->subscriberService->resetSubscriberBounceCount($subscriber); + $this->entityManager->flush(); return $this->json($subscriberData, Response::HTTP_OK); } @@ -485,6 +488,7 @@ public function setSubscriberAsConfirmed(Request $request): Response } $subscriber = $this->subscriberService->confirmSubscriber($uniqueId); + $this->entityManager->flush(); if (!$subscriber) { return new Response('

Subscriber isn\'t found or already confirmed.

', 404); From a8e925c4b8563049ea37235dded9949c5c6b72fc Mon Sep 17 00:00:00 2001 From: Tatevik Date: Wed, 22 Oct 2025 13:04:16 +0400 Subject: [PATCH 09/10] save --- .../AdminAttributeDefinitionController.php | 3 +++ .../Controller/PasswordResetController.php | 5 +++++ src/Messaging/Controller/BounceRegexController.php | 1 + src/Messaging/Controller/CampaignController.php | 14 ++++++-------- .../SubscriberAttributeDefinitionController.php | 2 ++ .../Controller/SubscriberController.php | 3 +++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Identity/Controller/AdminAttributeDefinitionController.php b/src/Identity/Controller/AdminAttributeDefinitionController.php index c5678e4..ff4c853 100644 --- a/src/Identity/Controller/AdminAttributeDefinitionController.php +++ b/src/Identity/Controller/AdminAttributeDefinitionController.php @@ -91,6 +91,8 @@ public function create(Request $request): JsonResponse $definitionRequest = $this->validator->validate($request, CreateAttributeDefinitionRequest::class); $attributeDefinition = $this->definitionManager->create($definitionRequest->getDto()); + $this->entityManager->flush(); + $json = $this->normalizer->normalize($attributeDefinition, 'json'); return $this->json($json, Response::HTTP_CREATED); @@ -158,6 +160,7 @@ public function update( attributeDefinition: $attributeDefinition, attributeDefinitionDto: $definitionRequest->getDto(), ); + $this->entityManager->flush(); $json = $this->normalizer->normalize($attributeDefinition, 'json'); return $this->json($json, Response::HTTP_OK); diff --git a/src/Identity/Controller/PasswordResetController.php b/src/Identity/Controller/PasswordResetController.php index de5d3d6..a3527b0 100644 --- a/src/Identity/Controller/PasswordResetController.php +++ b/src/Identity/Controller/PasswordResetController.php @@ -4,6 +4,7 @@ namespace PhpList\RestBundle\Identity\Controller; +use Doctrine\ORM\EntityManagerInterface; use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Service\PasswordManager; use PhpList\Core\Security\Authentication; @@ -29,6 +30,7 @@ public function __construct( Authentication $authentication, RequestValidator $validator, PasswordManager $passwordManager, + private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); @@ -74,6 +76,7 @@ public function requestPasswordReset(Request $request): JsonResponse $resetRequest = $this->validator->validate($request, RequestPasswordResetRequest::class); $this->passwordManager->generatePasswordResetToken($resetRequest->email); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } @@ -117,6 +120,7 @@ public function validateToken(Request $request): JsonResponse $validateRequest = $this->validator->validate($request, ValidateTokenRequest::class); $administrator = $this->passwordManager->validatePasswordResetToken($validateRequest->token); + $this->entityManager->flush(); return $this->json([ 'valid' => $administrator !== null]); } @@ -169,6 +173,7 @@ public function resetPassword(Request $request): JsonResponse $resetRequest->token, $resetRequest->newPassword ); + $this->entityManager->flush(); if ($success) { return $this->json([ 'message' => 'Password updated successfully']); diff --git a/src/Messaging/Controller/BounceRegexController.php b/src/Messaging/Controller/BounceRegexController.php index 198b27e..c9e9a1c 100644 --- a/src/Messaging/Controller/BounceRegexController.php +++ b/src/Messaging/Controller/BounceRegexController.php @@ -190,6 +190,7 @@ public function createOrUpdate(Request $request): JsonResponse comment: $dto->comment, status: $dto->status ); + $this->entityManager->flush(); return $this->json($this->normalizer->normalize($entity), Response::HTTP_CREATED); } diff --git a/src/Messaging/Controller/CampaignController.php b/src/Messaging/Controller/CampaignController.php index 305d525..b1b8e80 100644 --- a/src/Messaging/Controller/CampaignController.php +++ b/src/Messaging/Controller/CampaignController.php @@ -214,11 +214,10 @@ public function createMessage(Request $request): JsonResponse /** @var CreateMessageRequest $createMessageRequest */ $createMessageRequest = $this->validator->validate($request, CreateMessageRequest::class); + $message = $this->campaignService->createMessage($createMessageRequest, $authUser); + $this->entityManager->flush(); - return $this->json( - $this->campaignService->createMessage($createMessageRequest, $authUser), - Response::HTTP_CREATED - ); + return $this->json(data: $message, status: Response::HTTP_CREATED); } #[Route('/{messageId}', name: 'update', requirements: ['messageId' => '\d+'], methods: ['PUT'])] @@ -287,11 +286,10 @@ public function updateMessage( /** @var UpdateMessageRequest $updateMessageRequest */ $updateMessageRequest = $this->validator->validate($request, UpdateMessageRequest::class); + $message = $this->campaignService->updateMessage($updateMessageRequest, $authUser, $message); + $this->entityManager->flush(); - return $this->json( - $this->campaignService->updateMessage($updateMessageRequest, $authUser, $message), - Response::HTTP_OK - ); + return $this->json(data:$message, status: Response::HTTP_OK); } #[Route('/{messageId}', name: 'delete', requirements: ['messageId' => '\d+'], methods: ['DELETE'])] diff --git a/src/Subscription/Controller/SubscriberAttributeDefinitionController.php b/src/Subscription/Controller/SubscriberAttributeDefinitionController.php index a6395f3..e096552 100644 --- a/src/Subscription/Controller/SubscriberAttributeDefinitionController.php +++ b/src/Subscription/Controller/SubscriberAttributeDefinitionController.php @@ -89,6 +89,7 @@ public function create(Request $request): JsonResponse $definitionRequest = $this->validator->validate($request, CreateAttributeDefinitionRequest::class); $attributeDefinition = $this->definitionManager->create($definitionRequest->getDto()); + $this->entityManager->flush(); $json = $this->normalizer->normalize($attributeDefinition, 'json'); return $this->json($json, Response::HTTP_CREATED); @@ -156,6 +157,7 @@ public function update( attributeDefinition: $attributeDefinition, attributeDefinitionDto: $definitionRequest->getDto(), ); + $this->entityManager->flush(); $json = $this->normalizer->normalize($attributeDefinition, 'json'); return $this->json($json, Response::HTTP_OK); diff --git a/src/Subscription/Controller/SubscriberController.php b/src/Subscription/Controller/SubscriberController.php index b9fb017..d0bdc8c 100644 --- a/src/Subscription/Controller/SubscriberController.php +++ b/src/Subscription/Controller/SubscriberController.php @@ -96,6 +96,7 @@ public function createSubscriber(Request $request): JsonResponse /** @var CreateSubscriberRequest $subscriberRequest */ $subscriberRequest = $this->validator->validate($request, CreateSubscriberRequest::class); $subscriberData = $this->subscriberService->createSubscriber($subscriberRequest); + $this->entityManager->flush(); return $this->json($subscriberData, Response::HTTP_CREATED); } @@ -166,6 +167,7 @@ public function updateSubscriber( /** @var UpdateSubscriberRequest $updateSubscriberRequest */ $updateSubscriberRequest = $this->validator->validate($request, UpdateSubscriberRequest::class); $subscriberData = $this->subscriberService->updateSubscriber($updateSubscriberRequest, $admin); + $this->entityManager->flush(); return $this->json($subscriberData, Response::HTTP_OK); } @@ -373,6 +375,7 @@ public function deleteSubscriber( throw $this->createNotFoundException('Subscriber not found.'); } $this->subscriberService->deleteSubscriber($subscriber); + $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); } From c70fbfc07dc1f2747a0b60a7152ef25ecb848611 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Wed, 22 Oct 2025 13:40:13 +0400 Subject: [PATCH 10/10] fix test --- composer.json | 2 +- .../Controller/SubscriberController.php | 36 ++-- .../Service/SubscriberService.php | 76 -------- .../Controller/SubscriberControllerTest.php | 2 + .../Service/SubscriberServiceTest.php | 176 ------------------ 5 files changed, 24 insertions(+), 268 deletions(-) delete mode 100644 src/Subscription/Service/SubscriberService.php delete mode 100644 tests/Unit/Subscription/Service/SubscriberServiceTest.php diff --git a/composer.json b/composer.json index 4db23ce..99e5fca 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ }, "require": { "php": "^8.1", - "phplist/core": "dev-em-flush", + "phplist/core": "dev-dev", "friendsofsymfony/rest-bundle": "*", "symfony/test-pack": "^1.0", "symfony/process": "^6.4", diff --git a/src/Subscription/Controller/SubscriberController.php b/src/Subscription/Controller/SubscriberController.php index d0bdc8c..e144e20 100644 --- a/src/Subscription/Controller/SubscriberController.php +++ b/src/Subscription/Controller/SubscriberController.php @@ -8,16 +8,19 @@ use OpenApi\Attributes as OA; use PhpList\Core\Domain\Identity\Model\PrivilegeFlag; use PhpList\Core\Domain\Subscription\Model\Subscriber; +use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager; use PhpList\Core\Security\Authentication; use PhpList\RestBundle\Common\Controller\BaseController; use PhpList\RestBundle\Common\Validator\RequestValidator; use PhpList\RestBundle\Subscription\Request\CreateSubscriberRequest; use PhpList\RestBundle\Subscription\Request\UpdateSubscriberRequest; -use PhpList\RestBundle\Subscription\Service\SubscriberService; +use PhpList\RestBundle\Subscription\Serializer\SubscriberNormalizer; +use PhpList\RestBundle\Subscription\Service\SubscriberHistoryService; use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Attribute\Route; /** @@ -29,17 +32,16 @@ #[Route('/subscribers', name: 'subscriber_')] class SubscriberController extends BaseController { - private SubscriberService $subscriberService; - public function __construct( Authentication $authentication, RequestValidator $validator, - SubscriberService $subscriberService, + private readonly SubscriberManager $subscriberManager, + private readonly SubscriberNormalizer $subscriberNormalizer, + private readonly SubscriberHistoryService $subscriberHistoryService, private readonly EntityManagerInterface $entityManager, ) { parent::__construct($authentication, $validator); $this->authentication = $authentication; - $this->subscriberService = $subscriberService; } #[Route('', name: 'create', methods: ['POST'])] @@ -95,8 +97,9 @@ public function createSubscriber(Request $request): JsonResponse /** @var CreateSubscriberRequest $subscriberRequest */ $subscriberRequest = $this->validator->validate($request, CreateSubscriberRequest::class); - $subscriberData = $this->subscriberService->createSubscriber($subscriberRequest); + $subscriber = $this->subscriberManager->createSubscriber($subscriberRequest->getDto()); $this->entityManager->flush(); + $subscriberData = $this->subscriberNormalizer->normalize($subscriber, 'json'); return $this->json($subscriberData, Response::HTTP_CREATED); } @@ -166,8 +169,9 @@ public function updateSubscriber( } /** @var UpdateSubscriberRequest $updateSubscriberRequest */ $updateSubscriberRequest = $this->validator->validate($request, UpdateSubscriberRequest::class); - $subscriberData = $this->subscriberService->updateSubscriber($updateSubscriberRequest, $admin); + $subscriber = $this->subscriberManager->updateSubscriber($updateSubscriberRequest->getDto(), $admin); $this->entityManager->flush(); + $subscriberData = $this->subscriberNormalizer->normalize($subscriber, 'json'); return $this->json($subscriberData, Response::HTTP_OK); } @@ -217,7 +221,8 @@ public function getSubscriber(Request $request, int $subscriberId): JsonResponse { $this->requireAuthentication($request); - $subscriberData = $this->subscriberService->getSubscriber($subscriberId); + $subscriber = $this->subscriberManager->getSubscriberById($subscriberId); + $subscriberData = $this->subscriberNormalizer->normalize($subscriber); return $this->json($subscriberData, Response::HTTP_OK); } @@ -313,7 +318,7 @@ public function getSubscriberHistory( ): JsonResponse { $this->requireAuthentication($request); - $historyData = $this->subscriberService->getSubscriberHistory($request, $subscriber); + $historyData = $this->subscriberHistoryService->getSubscriberHistory($request, $subscriber); return $this->json( data: $historyData, @@ -374,7 +379,7 @@ public function deleteSubscriber( if (!$subscriber) { throw $this->createNotFoundException('Subscriber not found.'); } - $this->subscriberService->deleteSubscriber($subscriber); + $this->subscriberManager->deleteSubscriber($subscriber); $this->entityManager->flush(); return $this->json(null, Response::HTTP_NO_CONTENT); @@ -443,8 +448,9 @@ public function resetBounceCount( throw $this->createNotFoundException('Subscriber not found.'); } - $subscriberData = $this->subscriberService->resetSubscriberBounceCount($subscriber); + $subscriber = $this->subscriberManager->resetBounceCount($subscriber); $this->entityManager->flush(); + $subscriberData = $this->subscriberNormalizer->normalize($subscriber, 'json'); return $this->json($subscriberData, Response::HTTP_OK); } @@ -490,10 +496,10 @@ public function setSubscriberAsConfirmed(Request $request): Response return new Response('

Missing confirmation code.

', 400); } - $subscriber = $this->subscriberService->confirmSubscriber($uniqueId); - $this->entityManager->flush(); - - if (!$subscriber) { + try { + $this->subscriberManager->markAsConfirmedByUniqueId($uniqueId); + $this->entityManager->flush(); + } catch (NotFoundHttpException) { return new Response('

Subscriber isn\'t found or already confirmed.

', 404); } diff --git a/src/Subscription/Service/SubscriberService.php b/src/Subscription/Service/SubscriberService.php deleted file mode 100644 index b3acd21..0000000 --- a/src/Subscription/Service/SubscriberService.php +++ /dev/null @@ -1,76 +0,0 @@ - - */ -class SubscriberService -{ - public function __construct( - private readonly SubscriberManager $subscriberManager, - private readonly SubscriberNormalizer $subscriberNormalizer, - private readonly SubscriberHistoryService $subscriberHistoryService, - ) { - } - - public function createSubscriber(CreateSubscriberRequest $subscriberRequest): array - { - $subscriber = $this->subscriberManager->createSubscriber($subscriberRequest->getDto()); - return $this->subscriberNormalizer->normalize($subscriber, 'json'); - } - - public function updateSubscriber(UpdateSubscriberRequest $updateSubscriberRequest, Administrator $admin): array - { - $subscriber = $this->subscriberManager->updateSubscriber($updateSubscriberRequest->getDto(), $admin); - return $this->subscriberNormalizer->normalize($subscriber, 'json'); - } - - public function resetSubscriberBounceCount(Subscriber $subscriber): array - { - $subscriber = $this->subscriberManager->resetBounceCount($subscriber); - return $this->subscriberNormalizer->normalize($subscriber, 'json'); - } - - public function getSubscriber(int $subscriberId): array - { - $subscriber = $this->subscriberManager->getSubscriberById($subscriberId); - return $this->subscriberNormalizer->normalize($subscriber); - } - - public function getSubscriberHistory(Request $request, ?Subscriber $subscriber): array - { - return $this->subscriberHistoryService->getSubscriberHistory($request, $subscriber); - } - - public function deleteSubscriber(Subscriber $subscriber): void - { - $this->subscriberManager->deleteSubscriber($subscriber); - } - - public function confirmSubscriber(string $uniqueId): ?Subscriber - { - if (!$uniqueId) { - return null; - } - - try { - return $this->subscriberManager->markAsConfirmedByUniqueId($uniqueId); - } catch (NotFoundHttpException) { - return null; - } - } -} diff --git a/tests/Integration/Subscription/Controller/SubscriberControllerTest.php b/tests/Integration/Subscription/Controller/SubscriberControllerTest.php index 3ffb4dd..93cf93d 100644 --- a/tests/Integration/Subscription/Controller/SubscriberControllerTest.php +++ b/tests/Integration/Subscription/Controller/SubscriberControllerTest.php @@ -72,6 +72,8 @@ public function testPostSubscribersWithValidSessionKeyAndMinimalValidDataReturns self::assertMatchesRegularExpression('/^[0-9a-f]{32}$/', $responseContent['unique_id']); } + + public function testPostSubscribersWithValidSessionKeyAndValidDataCreatesSubscriber() { $email = 'subscriber@example.com'; diff --git a/tests/Unit/Subscription/Service/SubscriberServiceTest.php b/tests/Unit/Subscription/Service/SubscriberServiceTest.php deleted file mode 100644 index a37d177..0000000 --- a/tests/Unit/Subscription/Service/SubscriberServiceTest.php +++ /dev/null @@ -1,176 +0,0 @@ -subscriberManager = $this->createMock(SubscriberManager::class); - $this->subscriberNormalizer = $this->createMock(SubscriberNormalizer::class); - $this->subscriberHistoryService = $this->createMock(SubscriberHistoryService::class); - - $this->subscriberService = new SubscriberService( - $this->subscriberManager, - $this->subscriberNormalizer, - $this->subscriberHistoryService - ); - } - - public function testCreateSubscriberReturnsNormalizedSubscriber(): void - { - $subscriberDto = $this->createMock(CreateSubscriberDto::class); - $createSubscriberRequest = $this->createMock(CreateSubscriberRequest::class); - $subscriber = $this->createMock(Subscriber::class); - $expectedResult = ['id' => 1, 'email' => 'test@example.com']; - - $createSubscriberRequest->expects($this->once()) - ->method('getDto') - ->willReturn($subscriberDto); - - $this->subscriberManager->expects($this->once()) - ->method('createSubscriber') - ->with($this->identicalTo($subscriberDto)) - ->willReturn($subscriber); - - $this->subscriberNormalizer->expects($this->once()) - ->method('normalize') - ->with($this->identicalTo($subscriber), 'json') - ->willReturn($expectedResult); - - $result = $this->subscriberService->createSubscriber($createSubscriberRequest); - - $this->assertSame($expectedResult, $result); - } - - public function testUpdateSubscriberReturnsNormalizedSubscriber(): void - { - $subscriberDto = $this->createMock(UpdateSubscriberDto::class); - $updateSubscriberRequest = $this->createMock(UpdateSubscriberRequest::class); - $subscriber = $this->createMock(Subscriber::class); - $expectedResult = ['id' => 1, 'email' => 'updated@example.com']; - $admin = $this->createMock(Administrator::class); - - $updateSubscriberRequest->expects($this->once()) - ->method('getDto') - ->willReturn($subscriberDto); - - $this->subscriberManager->expects($this->once()) - ->method('updateSubscriber') - ->with($this->identicalTo($subscriberDto)) - ->willReturn($subscriber); - - $this->subscriberNormalizer->expects($this->once()) - ->method('normalize') - ->with($this->identicalTo($subscriber), 'json') - ->willReturn($expectedResult); - - $result = $this->subscriberService->updateSubscriber($updateSubscriberRequest, $admin); - - $this->assertSame($expectedResult, $result); - } - - public function testGetSubscriberReturnsNormalizedSubscriber(): void - { - $subscriberId = 1; - $subscriber = $this->createMock(Subscriber::class); - $expectedResult = ['id' => 1, 'email' => 'test@example.com']; - - $this->subscriberManager->expects($this->once()) - ->method('getSubscriberById') - ->with($subscriberId) - ->willReturn($subscriber); - - $this->subscriberNormalizer->expects($this->once()) - ->method('normalize') - ->with($this->identicalTo($subscriber)) - ->willReturn($expectedResult); - - $result = $this->subscriberService->getSubscriber($subscriberId); - - $this->assertSame($expectedResult, $result); - } - - public function testGetSubscriberHistoryDelegatesToHistoryService(): void - { - $request = new Request(); - $subscriber = $this->createMock(Subscriber::class); - $expectedResult = ['items' => [], 'pagination' => []]; - - $this->subscriberHistoryService->expects($this->once()) - ->method('getSubscriberHistory') - ->with($this->identicalTo($request), $this->identicalTo($subscriber)) - ->willReturn($expectedResult); - - $result = $this->subscriberService->getSubscriberHistory($request, $subscriber); - - $this->assertSame($expectedResult, $result); - } - - public function testDeleteSubscriberCallsManagerDelete(): void - { - $subscriber = $this->createMock(Subscriber::class); - - $this->subscriberManager->expects($this->once()) - ->method('deleteSubscriber') - ->with($this->identicalTo($subscriber)); - - $this->subscriberService->deleteSubscriber($subscriber); - } - - public function testConfirmSubscriberWithEmptyUniqueIdReturnsNull(): void - { - $this->assertNull($this->subscriberService->confirmSubscriber('')); - } - - public function testConfirmSubscriberWithValidUniqueIdReturnsSubscriber(): void - { - $uniqueId = 'valid-unique-id'; - $subscriber = $this->createMock(Subscriber::class); - - $this->subscriberManager->expects($this->once()) - ->method('markAsConfirmedByUniqueId') - ->with($uniqueId) - ->willReturn($subscriber); - - $result = $this->subscriberService->confirmSubscriber($uniqueId); - - $this->assertSame($subscriber, $result); - } - - public function testConfirmSubscriberWithInvalidUniqueIdReturnsNull(): void - { - $uniqueId = 'invalid-unique-id'; - - $this->subscriberManager->expects($this->once()) - ->method('markAsConfirmedByUniqueId') - ->with($uniqueId) - ->willThrowException(new NotFoundHttpException()); - - $result = $this->subscriberService->confirmSubscriber($uniqueId); - - $this->assertNull($result); - } -}