From 38af2e06d2001be59f7e2b713e55626c4b46fa40 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 11:51:12 +0300 Subject: [PATCH 01/21] Remove parents for AggregateRootInterface --- Model/Aggregate/AggregateRootInterface.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Model/Aggregate/AggregateRootInterface.php b/Model/Aggregate/AggregateRootInterface.php index 08000bc..0889242 100644 --- a/Model/Aggregate/AggregateRootInterface.php +++ b/Model/Aggregate/AggregateRootInterface.php @@ -12,12 +12,9 @@ namespace StfalconStudio\ApiBundle\Model\Aggregate; -use StfalconStudio\ApiBundle\Model\Timestampable\TimestampableInterface; -use StfalconStudio\ApiBundle\Model\UUID\UuidInterface; - /** * AggregateRootInterface. */ -interface AggregateRootInterface extends TimestampableInterface, UuidInterface +interface AggregateRootInterface { } From 7bdaf38b3d57dd551e01475ce21f3a5e05569a58 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 12:26:21 +0300 Subject: [PATCH 02/21] Refactoring --- Model/{ => ORM}/Aggregate/AggregatePartInterface.php | 2 +- Model/{ => ORM}/Aggregate/AggregateRootInterface.php | 7 +++++-- Model/{ => ORM}/Credentials/CredentialsInterface.php | 2 +- Model/{ => ORM}/Credentials/CredentialsTrait.php | 2 +- Model/{ => ORM}/Timestampable/TimestampableInterface.php | 2 +- Model/{ => ORM}/Timestampable/TimestampableTrait.php | 2 +- Model/{ => ORM}/UUID/UuidInterface.php | 2 +- Model/{ => ORM}/UUID/UuidTrait.php | 2 +- Resources/config/orm.php | 4 ++++ Resources/config/services.php | 3 --- .../ORM/Aggregate/AggregatePartListenerTest.php | 4 ++-- 11 files changed, 18 insertions(+), 14 deletions(-) rename Model/{ => ORM}/Aggregate/AggregatePartInterface.php (88%) rename Model/{ => ORM}/Aggregate/AggregateRootInterface.php (52%) rename Model/{ => ORM}/Credentials/CredentialsInterface.php (91%) rename Model/{ => ORM}/Credentials/CredentialsTrait.php (94%) rename Model/{ => ORM}/Timestampable/TimestampableInterface.php (93%) rename Model/{ => ORM}/Timestampable/TimestampableTrait.php (96%) rename Model/{ => ORM}/UUID/UuidInterface.php (88%) rename Model/{ => ORM}/UUID/UuidTrait.php (89%) diff --git a/Model/Aggregate/AggregatePartInterface.php b/Model/ORM/Aggregate/AggregatePartInterface.php similarity index 88% rename from Model/Aggregate/AggregatePartInterface.php rename to Model/ORM/Aggregate/AggregatePartInterface.php index c367aca..a14b8a8 100644 --- a/Model/Aggregate/AggregatePartInterface.php +++ b/Model/ORM/Aggregate/AggregatePartInterface.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Aggregate; +namespace StfalconStudio\ApiBundle\Model\ORM\Aggregate; /** * AggregatePartInterface. diff --git a/Model/Aggregate/AggregateRootInterface.php b/Model/ORM/Aggregate/AggregateRootInterface.php similarity index 52% rename from Model/Aggregate/AggregateRootInterface.php rename to Model/ORM/Aggregate/AggregateRootInterface.php index 0889242..f8ec3b1 100644 --- a/Model/Aggregate/AggregateRootInterface.php +++ b/Model/ORM/Aggregate/AggregateRootInterface.php @@ -10,11 +10,14 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Aggregate; +namespace StfalconStudio\ApiBundle\Model\ORM\Aggregate; + +use StfalconStudio\ApiBundle\Model\ORM\Timestampable\TimestampableInterface; +use StfalconStudio\ApiBundle\Model\ORM\UUID\UuidInterface; /** * AggregateRootInterface. */ -interface AggregateRootInterface +interface AggregateRootInterface extends TimestampableInterface, UuidInterface { } diff --git a/Model/Credentials/CredentialsInterface.php b/Model/ORM/Credentials/CredentialsInterface.php similarity index 91% rename from Model/Credentials/CredentialsInterface.php rename to Model/ORM/Credentials/CredentialsInterface.php index 5acb58b..7e3eedf 100644 --- a/Model/Credentials/CredentialsInterface.php +++ b/Model/ORM/Credentials/CredentialsInterface.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Credentials; +namespace StfalconStudio\ApiBundle\Model\ORM\Credentials; /** * CredentialsInterface. diff --git a/Model/Credentials/CredentialsTrait.php b/Model/ORM/Credentials/CredentialsTrait.php similarity index 94% rename from Model/Credentials/CredentialsTrait.php rename to Model/ORM/Credentials/CredentialsTrait.php index df78aa4..fd721f8 100644 --- a/Model/Credentials/CredentialsTrait.php +++ b/Model/ORM/Credentials/CredentialsTrait.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Credentials; +namespace StfalconStudio\ApiBundle\Model\ORM\Credentials; use Doctrine\ORM\Mapping as ORM; diff --git a/Model/Timestampable/TimestampableInterface.php b/Model/ORM/Timestampable/TimestampableInterface.php similarity index 93% rename from Model/Timestampable/TimestampableInterface.php rename to Model/ORM/Timestampable/TimestampableInterface.php index cf97877..608350f 100644 --- a/Model/Timestampable/TimestampableInterface.php +++ b/Model/ORM/Timestampable/TimestampableInterface.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Timestampable; +namespace StfalconStudio\ApiBundle\Model\ORM\Timestampable; /** * TimestampableInterface. diff --git a/Model/Timestampable/TimestampableTrait.php b/Model/ORM/Timestampable/TimestampableTrait.php similarity index 96% rename from Model/Timestampable/TimestampableTrait.php rename to Model/ORM/Timestampable/TimestampableTrait.php index 593b622..dcee13d 100644 --- a/Model/Timestampable/TimestampableTrait.php +++ b/Model/ORM/Timestampable/TimestampableTrait.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\Timestampable; +namespace StfalconStudio\ApiBundle\Model\ORM\Timestampable; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; diff --git a/Model/UUID/UuidInterface.php b/Model/ORM/UUID/UuidInterface.php similarity index 88% rename from Model/UUID/UuidInterface.php rename to Model/ORM/UUID/UuidInterface.php index d06346d..5033551 100644 --- a/Model/UUID/UuidInterface.php +++ b/Model/ORM/UUID/UuidInterface.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\UUID; +namespace StfalconStudio\ApiBundle\Model\ORM\UUID; /** * UuidInterface. diff --git a/Model/UUID/UuidTrait.php b/Model/ORM/UUID/UuidTrait.php similarity index 89% rename from Model/UUID/UuidTrait.php rename to Model/ORM/UUID/UuidTrait.php index 3c079d0..0bb6c5d 100644 --- a/Model/UUID/UuidTrait.php +++ b/Model/ORM/UUID/UuidTrait.php @@ -10,7 +10,7 @@ declare(strict_types=1); -namespace StfalconStudio\ApiBundle\Model\UUID; +namespace StfalconStudio\ApiBundle\Model\ORM\UUID; /** * UuidTrait. diff --git a/Resources/config/orm.php b/Resources/config/orm.php index d798661..25932c0 100644 --- a/Resources/config/orm.php +++ b/Resources/config/orm.php @@ -10,6 +10,7 @@ declare(strict_types=1); +use StfalconStudio\ApiBundle\EventListener\ORM\Aggregate\AggregatePartListener; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return static function (ContainerConfigurator $containerConfigurator): void { @@ -23,4 +24,7 @@ $services->load('StfalconStudio\ApiBundle\Service\Repository\\', __DIR__.'/../../Service/Repository'); $services->load('StfalconStudio\ApiBundle\Service\DependentEntity\\', __DIR__.'/../../Service/DependentEntity'); + $services->load('StfalconStudio\ApiBundle\EventListener\ORM\\', __DIR__.'/../../EventListener/ORM'); + + $services->set(AggregatePartListener::class, AggregatePartListener::class)->tag('doctrine.event_listener', ['event' => 'onFlush']); }; diff --git a/Resources/config/services.php b/Resources/config/services.php index 1b48674..a9dcb23 100644 --- a/Resources/config/services.php +++ b/Resources/config/services.php @@ -13,7 +13,6 @@ use Fresh\DateTime\DateTimeHelper; use JsonSchema\Validator; use Predis\Client; -use StfalconStudio\ApiBundle\EventListener\ORM\Aggregate\AggregatePartListener; use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Reference; @@ -35,9 +34,7 @@ $services->load('StfalconStudio\ApiBundle\\', __DIR__.'/../../{Asset,Request,Serializer,Service,Util,Validator}/'); $services->load('StfalconStudio\ApiBundle\EventListener\Console\\', __DIR__.'/../../EventListener/Console'); $services->load('StfalconStudio\ApiBundle\EventListener\Kernel\\', __DIR__.'/../../EventListener/Kernel'); - $services->load('StfalconStudio\ApiBundle\EventListener\ORM\\', __DIR__.'/../../EventListener/ORM'); - $services->set(AggregatePartListener::class, AggregatePartListener::class)->tag('doctrine.event_listener', ['event' => 'onFlush']); $services->set(Client::class, Client::class); $services->set(Validator::class, Validator::class); $services->set(DateTimeHelper::class, DateTimeHelper::class); diff --git a/Tests/EventListener/ORM/Aggregate/AggregatePartListenerTest.php b/Tests/EventListener/ORM/Aggregate/AggregatePartListenerTest.php index 27b2358..a5cc5ca 100644 --- a/Tests/EventListener/ORM/Aggregate/AggregatePartListenerTest.php +++ b/Tests/EventListener/ORM/Aggregate/AggregatePartListenerTest.php @@ -20,8 +20,8 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use StfalconStudio\ApiBundle\EventListener\ORM\Aggregate\AggregatePartListener; -use StfalconStudio\ApiBundle\Model\Aggregate\AggregatePartInterface; -use StfalconStudio\ApiBundle\Model\Aggregate\AggregateRootInterface; +use StfalconStudio\ApiBundle\Model\ORM\Aggregate\AggregatePartInterface; +use StfalconStudio\ApiBundle\Model\ORM\Aggregate\AggregateRootInterface; final class AggregatePartListenerTest extends TestCase { From 064fbc6e599128933a168d38d9a424a37f02db29 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 12:48:02 +0300 Subject: [PATCH 03/21] Add classes for ODM --- DependencyInjection/StfalconApiExtension.php | 4 + .../ODM/Aggregate/AggregatePartListener.php | 75 ++++++++++ Model/Credentials/CredentialsInterface.php | 31 +++++ .../ODM/Aggregate/AggregatePartInterface.php | 24 ++++ .../ODM/Aggregate/AggregateRootInterface.php | 23 ++++ .../ODM/Credentials/CredentialsInterface.php | 22 +++ Model/ODM/Credentials/CredentialsTrait.php | 44 ++++++ .../Timestampable/TimestampableInterface.php | 44 ++++++ .../ODM/Timestampable/TimestampableTrait.php | 70 ++++++++++ Model/ODM/UUID/UuidInterface.php | 24 ++++ Model/ODM/UUID/UuidTrait.php | 27 ++++ .../ORM/Credentials/CredentialsInterface.php | 15 +- Resources/config/odm.php | 28 ++++ .../Aggregate/AggregatePartListenerTest.php | 128 ++++++++++++++++++ 14 files changed, 547 insertions(+), 12 deletions(-) create mode 100644 EventListener/ODM/Aggregate/AggregatePartListener.php create mode 100644 Model/Credentials/CredentialsInterface.php create mode 100644 Model/ODM/Aggregate/AggregatePartInterface.php create mode 100644 Model/ODM/Aggregate/AggregateRootInterface.php create mode 100644 Model/ODM/Credentials/CredentialsInterface.php create mode 100644 Model/ODM/Credentials/CredentialsTrait.php create mode 100644 Model/ODM/Timestampable/TimestampableInterface.php create mode 100644 Model/ODM/Timestampable/TimestampableTrait.php create mode 100644 Model/ODM/UUID/UuidInterface.php create mode 100644 Model/ODM/UUID/UuidTrait.php create mode 100644 Resources/config/odm.php create mode 100644 Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php diff --git a/DependencyInjection/StfalconApiExtension.php b/DependencyInjection/StfalconApiExtension.php index add6521..1ff78a2 100644 --- a/DependencyInjection/StfalconApiExtension.php +++ b/DependencyInjection/StfalconApiExtension.php @@ -12,6 +12,7 @@ namespace StfalconStudio\ApiBundle\DependencyInjection; +use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ORM\EntityManagerInterface; use StfalconStudio\ApiBundle\Security\JwtBlackListService; use StfalconStudio\ApiBundle\Service\Exception\ResponseProcessor\CustomAppExceptionResponseProcessorInterface; @@ -49,6 +50,9 @@ public function load(array $configs, ContainerBuilder $container): void if (\interface_exists(EntityManagerInterface::class)) { $loader->load('orm.php'); } + if (\interface_exists(DocumentManager::class)) { + $loader->load('odm.php'); + } $container->setParameter('stfalcon_api.api_host', $config['api_host']); $container->setParameter('stfalcon_api.json_schema_dir', $config['json_schema_dir']); diff --git a/EventListener/ODM/Aggregate/AggregatePartListener.php b/EventListener/ODM/Aggregate/AggregatePartListener.php new file mode 100644 index 0000000..4fa04ce --- /dev/null +++ b/EventListener/ODM/Aggregate/AggregatePartListener.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\EventListener\ODM\Aggregate; + +use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs; +use Fresh\DateTime\DateTimeHelper; +use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregatePartInterface; +use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregateRootInterface; + +/** + * AggregatePartListener. + */ +final class AggregatePartListener +{ + /** @var array */ + private array $aggregateRoots = []; + + /** + * @param DateTimeHelper $dateTimeHelper + */ + public function __construct(private readonly DateTimeHelper $dateTimeHelper) + { + } + + /** + * @param OnFlushEventArgs $eventArgs + */ + public function onFlush(OnFlushEventArgs $eventArgs): void + { + $em = $eventArgs->getDocumentManager(); + $uow = $em->getUnitOfWork(); + + foreach ($uow->getScheduledDocumentUpdates() as $entity) { + $this->processEntity($entity); + } + foreach ($uow->getScheduledDocumentInsertions() as $entity) { + $this->processEntity($entity); + } + foreach ($uow->getScheduledDocumentDeletions() as $entity) { + $this->processEntity($entity); + } + + foreach ($this->aggregateRoots as $aggregateRoot) { + $aggregateRoot->setUpdatedAt($this->dateTimeHelper->getCurrentDatetime()); + $uow->recomputeSingleDocumentChangeSet($em->getClassMetadata(\get_class($aggregateRoot)), $aggregateRoot); + } + + $this->aggregateRoots = []; + } + + /** + * @param object $entity + */ + private function processEntity(object $entity): void + { + if ($entity instanceof AggregatePartInterface) { + $aggregateRoot = $entity->getAggregateRoot(); + + if (!\in_array($aggregateRoot, $this->aggregateRoots, true)) { + $this->aggregateRoots[$aggregateRoot->getId()] = $aggregateRoot; + $this->processEntity($aggregateRoot); // Bubble aggregate root to the top root + } + } + } +} diff --git a/Model/Credentials/CredentialsInterface.php b/Model/Credentials/CredentialsInterface.php new file mode 100644 index 0000000..5acb58b --- /dev/null +++ b/Model/Credentials/CredentialsInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\Credentials; + +/** + * CredentialsInterface. + */ +interface CredentialsInterface +{ + /** + * @param \DateTimeInterface|null $credentialsLastChangedAt + * + * @return self + */ + public function setCredentialsLastChangedAt(?\DateTimeInterface $credentialsLastChangedAt): self; + + /** + * @return \DateTimeInterface|null + */ + public function getCredentialsLastChangedAt(): ?\DateTimeInterface; +} diff --git a/Model/ODM/Aggregate/AggregatePartInterface.php b/Model/ODM/Aggregate/AggregatePartInterface.php new file mode 100644 index 0000000..7453a36 --- /dev/null +++ b/Model/ODM/Aggregate/AggregatePartInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Aggregate; + +/** + * AggregatePartInterface. + */ +interface AggregatePartInterface +{ + /** + * @return AggregateRootInterface + */ + public function getAggregateRoot(): AggregateRootInterface; +} diff --git a/Model/ODM/Aggregate/AggregateRootInterface.php b/Model/ODM/Aggregate/AggregateRootInterface.php new file mode 100644 index 0000000..d843fc6 --- /dev/null +++ b/Model/ODM/Aggregate/AggregateRootInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Aggregate; + +use StfalconStudio\ApiBundle\Model\ODM\Timestampable\TimestampableInterface; +use StfalconStudio\ApiBundle\Model\ODM\UUID\UuidInterface; + +/** + * AggregateRootInterface. + */ +interface AggregateRootInterface extends TimestampableInterface, UuidInterface +{ +} diff --git a/Model/ODM/Credentials/CredentialsInterface.php b/Model/ODM/Credentials/CredentialsInterface.php new file mode 100644 index 0000000..f8e50af --- /dev/null +++ b/Model/ODM/Credentials/CredentialsInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Credentials; + +use StfalconStudio\ApiBundle\Model\Credentials\CredentialsInterface as BaseCredentialsInterface; + +/** + * CredentialsInterface. + */ +interface CredentialsInterface extends BaseCredentialsInterface +{ +} diff --git a/Model/ODM/Credentials/CredentialsTrait.php b/Model/ODM/Credentials/CredentialsTrait.php new file mode 100644 index 0000000..76fd5f3 --- /dev/null +++ b/Model/ODM/Credentials/CredentialsTrait.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Credentials; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; + +/** + * CredentialsTrait. + */ +trait CredentialsTrait +{ + #[MongoDB\Field(type: 'date', nullable: true)] + protected ?\DateTimeInterface $credentialsLastChangedAt = null; + + /** + * @param \DateTimeInterface|null $credentialsLastChangedAt + * + * @return self + */ + public function setCredentialsLastChangedAt(?\DateTimeInterface $credentialsLastChangedAt): self + { + $this->credentialsLastChangedAt = $credentialsLastChangedAt; + + return $this; + } + + /** + * @return \DateTimeInterface|null + */ + public function getCredentialsLastChangedAt(): ?\DateTimeInterface + { + return $this->credentialsLastChangedAt; + } +} diff --git a/Model/ODM/Timestampable/TimestampableInterface.php b/Model/ODM/Timestampable/TimestampableInterface.php new file mode 100644 index 0000000..45e763f --- /dev/null +++ b/Model/ODM/Timestampable/TimestampableInterface.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Timestampable; + +/** + * TimestampableInterface. + */ +interface TimestampableInterface +{ + /** + * @param \DateTimeImmutable|null $createdAt + */ + public function setCreatedAt(\DateTimeInterface $createdAt = null): void; + + /** + * @return \DateTimeInterface|null + */ + public function getCreatedAt(): ?\DateTimeInterface; + + /** + * @param \DateTimeInterface|null $createdAt + */ + public function setUpdatedAt(\DateTimeInterface $createdAt = null): void; + + /** + * @return \DateTimeInterface|null + */ + public function getUpdatedAt(): ?\DateTimeInterface; + + /** + * Init timestampable fields. + */ + public function initTimestampableFields(): void; +} diff --git a/Model/ODM/Timestampable/TimestampableTrait.php b/Model/ODM/Timestampable/TimestampableTrait.php new file mode 100644 index 0000000..72f9979 --- /dev/null +++ b/Model/ODM/Timestampable/TimestampableTrait.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\Timestampable; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use Gedmo\Mapping\Annotation as Gedmo; + +/** + * TimestampableTrait. + */ +trait TimestampableTrait +{ + #[MongoDB\Field(type: 'date_immutable')] + protected \DateTimeInterface|null $createdAt = null; + + #[MongoDB\Field(type: 'date')] + #[Gedmo\Timestampable(on: 'update')] + protected \DateTimeInterface|null $updatedAt = null; + + /** + * @param \DateTimeImmutable|null $createdAt + */ + public function setCreatedAt(\DateTimeInterface $createdAt = null): void + { + $this->createdAt = $createdAt; + } + + /** + * @return \DateTimeImmutable + */ + public function getCreatedAt(): \DateTimeInterface + { + return $this->createdAt; + } + + /** + * @param \DateTimeInterface|null $updatedAt + */ + public function setUpdatedAt(\DateTimeInterface $updatedAt = null): void + { + $this->updatedAt = $updatedAt; + } + + /** + * @return \DateTimeInterface + */ + public function getUpdatedAt(): \DateTimeInterface + { + return $this->updatedAt; + } + + /** + * Init timestampable fields. + */ + public function initTimestampableFields(): void + { + $this->createdAt = new \DateTimeImmutable('now'); + $this->updatedAt = new \DateTime('now'); + } +} diff --git a/Model/ODM/UUID/UuidInterface.php b/Model/ODM/UUID/UuidInterface.php new file mode 100644 index 0000000..0ca60c5 --- /dev/null +++ b/Model/ODM/UUID/UuidInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\UUID; + +/** + * UuidInterface. + */ +interface UuidInterface +{ + /** + * @return string + */ + public function getId(): string; +} diff --git a/Model/ODM/UUID/UuidTrait.php b/Model/ODM/UUID/UuidTrait.php new file mode 100644 index 0000000..a17b2eb --- /dev/null +++ b/Model/ODM/UUID/UuidTrait.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\ODM\UUID; + +/** + * UuidTrait. + */ +trait UuidTrait +{ + /** + * @return string + */ + public function getId(): string + { + return (string) $this->id; + } +} diff --git a/Model/ORM/Credentials/CredentialsInterface.php b/Model/ORM/Credentials/CredentialsInterface.php index 7e3eedf..4743f62 100644 --- a/Model/ORM/Credentials/CredentialsInterface.php +++ b/Model/ORM/Credentials/CredentialsInterface.php @@ -12,20 +12,11 @@ namespace StfalconStudio\ApiBundle\Model\ORM\Credentials; +use StfalconStudio\ApiBundle\Model\Credentials\CredentialsInterface as BaseCredentialsInterface; + /** * CredentialsInterface. */ -interface CredentialsInterface +interface CredentialsInterface extends BaseCredentialsInterface { - /** - * @param \DateTimeInterface|null $credentialsLastChangedAt - * - * @return self - */ - public function setCredentialsLastChangedAt(?\DateTimeInterface $credentialsLastChangedAt): self; - - /** - * @return \DateTimeInterface|null - */ - public function getCredentialsLastChangedAt(): ?\DateTimeInterface; } diff --git a/Resources/config/odm.php b/Resources/config/odm.php new file mode 100644 index 0000000..18e05fd --- /dev/null +++ b/Resources/config/odm.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +use StfalconStudio\ApiBundle\EventListener\ODM\Aggregate\AggregatePartListener; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + +return static function (ContainerConfigurator $containerConfigurator): void { + $services = $containerConfigurator->services(); + + $services + ->defaults() + ->autowire() + ->autoconfigure() + ; + + $services->load('StfalconStudio\ApiBundle\EventListener\ORM\\', __DIR__.'/../../EventListener/ORM'); + + $services->set(AggregatePartListener::class, AggregatePartListener::class)->tag('doctrine.event_listener', ['event' => 'onFlush']); +}; diff --git a/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php b/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php new file mode 100644 index 0000000..55ba2ce --- /dev/null +++ b/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Tests\EventListener\ODM\Aggregate; + +use Doctrine\ODM\EntityManager; +use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\UnitOfWork; +use Fresh\DateTime\DateTimeHelper; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use StfalconStudio\ApiBundle\EventListener\ORM\Aggregate\AggregatePartListener; +use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregatePartInterface; +use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregateRootInterface; + +final class AggregatePartListenerTest extends TestCase +{ + private DateTimeHelper|MockObject $dateTimeHelper; + private AggregatePartListener $listener; + + protected function setUp(): void + { + $this->dateTimeHelper = $this->createMock(DateTimeHelper::class); + $this->listener = new AggregatePartListener($this->dateTimeHelper); + } + + protected function tearDown(): void + { + unset( + $this->dateTimeHelper, + $this->listener, + ); + } + + public function testOnFlush(): void + { + $eventArgs = $this->createMock(OnFlushEventArgs::class); + + $em = $this->createMock(EntityManager::class); + $eventArgs + ->expects(self::once()) + ->method('getEntityManager') + ->willReturn($em) + ; + + $uow = $this->createMock(UnitOfWork::class); + $em + ->expects(self::once()) + ->method('getUnitOfWork') + ->willReturn($uow) + ; + + $updatedEntity = new \stdClass(); + $insertedEntity = $this->createMock(AggregatePartInterface::class); + $deletedEntity = new \stdClass(); + + $uow + ->expects(self::once()) + ->method('getScheduledEntityUpdates') + ->willReturn([$updatedEntity]) + ; + + $uow + ->expects(self::once()) + ->method('getScheduledEntityInsertions') + ->willReturn([$insertedEntity]) + ; + + $uow + ->expects(self::once()) + ->method('getScheduledEntityDeletions') + ->willReturn([$deletedEntity]) + ; + + $insertedEntityAggregatedRoot = $this->createMock(AggregateRootInterface::class); + $insertedEntity + ->expects(self::once()) + ->method('getAggregateRoot') + ->willReturn($insertedEntityAggregatedRoot) + ; + + $insertedEntityAggregatedRootId = '123'; + $insertedEntityAggregatedRoot + ->expects(self::once()) + ->method('getId') + ->willReturn($insertedEntityAggregatedRootId) + ; + + $now = new \DateTime(); + $this->dateTimeHelper + ->expects(self::once()) + ->method('getCurrentDatetime') + ->willReturn($now) + ; + + $insertedEntityAggregatedRoot + ->expects(self::once()) + ->method('setUpdatedAt') + ->with($now) + ; + + $classMetadata = $this->createMock(ClassMetadata::class); + $uow + ->expects(self::once()) + ->method('recomputeSingleEntityChangeSet') + ->with($classMetadata, $insertedEntityAggregatedRoot) + ; + + $em + ->expects(self::once()) + ->method('getClassMetadata') + ->with(\get_class($insertedEntityAggregatedRoot)) + ->willReturn($classMetadata) + ; + + $this->listener->onFlush($eventArgs); + } +} From 043463f191faed38a9cd6e322d1d1f0a0e1e7a3c Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 12:54:10 +0300 Subject: [PATCH 04/21] Fix services --- Resources/config/services.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Resources/config/services.php b/Resources/config/services.php index a9dcb23..f0c1e16 100644 --- a/Resources/config/services.php +++ b/Resources/config/services.php @@ -31,7 +31,8 @@ ->bind('$symfonyConstraintViolationListNormalizer', new Reference('serializer.normalizer.constraint_violation_list')) ; - $services->load('StfalconStudio\ApiBundle\\', __DIR__.'/../../{Asset,Request,Serializer,Service,Util,Validator}/'); + $services->load('StfalconStudio\ApiBundle\\', __DIR__.'/../../{Asset,Request,Serializer,Util,Validator}/'); + $services->load('StfalconStudio\ApiBundle\Service\\', __DIR__.'/../../{AttributeProcessor,DependentEntity,Exception}/'); $services->load('StfalconStudio\ApiBundle\EventListener\Console\\', __DIR__.'/../../EventListener/Console'); $services->load('StfalconStudio\ApiBundle\EventListener\Kernel\\', __DIR__.'/../../EventListener/Kernel'); From 838946505a221157d4ef9e79799bc7a779687bd0 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 13:09:12 +0300 Subject: [PATCH 05/21] Refactoring --- Resources/config/services.php | 7 ++++++- Tests/Model/Timestampable/DummyTimestampableEntity.php | 2 +- Tests/Model/UUID/DummyUuidEntity.php | 2 +- Tests/Serializer/CircularReferenceHandlerTest.php | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Resources/config/services.php b/Resources/config/services.php index f0c1e16..4b86cd3 100644 --- a/Resources/config/services.php +++ b/Resources/config/services.php @@ -10,9 +10,11 @@ declare(strict_types=1); +use Doctrine\ORM\EntityManagerInterface; use Fresh\DateTime\DateTimeHelper; use JsonSchema\Validator; use Predis\Client; +use StfalconStudio\ApiBundle\Validator\Constraints\Entity\EntityExistsValidator; use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Reference; @@ -32,9 +34,12 @@ ; $services->load('StfalconStudio\ApiBundle\\', __DIR__.'/../../{Asset,Request,Serializer,Util,Validator}/'); - $services->load('StfalconStudio\ApiBundle\Service\\', __DIR__.'/../../{AttributeProcessor,DependentEntity,Exception}/'); + $services->load('StfalconStudio\ApiBundle\Service\\', __DIR__.'/../../Service/{AttributeProcessor,DependentEntity,Exception}/'); $services->load('StfalconStudio\ApiBundle\EventListener\Console\\', __DIR__.'/../../EventListener/Console'); $services->load('StfalconStudio\ApiBundle\EventListener\Kernel\\', __DIR__.'/../../EventListener/Kernel'); + if (!\interface_exists(EntityManagerInterface::class)) { + $services->remove(EntityExistsValidator::class); + } $services->set(Client::class, Client::class); $services->set(Validator::class, Validator::class); diff --git a/Tests/Model/Timestampable/DummyTimestampableEntity.php b/Tests/Model/Timestampable/DummyTimestampableEntity.php index 2607281..663c1fa 100644 --- a/Tests/Model/Timestampable/DummyTimestampableEntity.php +++ b/Tests/Model/Timestampable/DummyTimestampableEntity.php @@ -12,7 +12,7 @@ namespace StfalconStudio\ApiBundle\Tests\Model\Timestampable; -use StfalconStudio\ApiBundle\Model\Timestampable\TimestampableTrait; +use StfalconStudio\ApiBundle\Model\ORM\Timestampable\TimestampableTrait; class DummyTimestampableEntity { diff --git a/Tests/Model/UUID/DummyUuidEntity.php b/Tests/Model/UUID/DummyUuidEntity.php index a6fc466..d80477d 100644 --- a/Tests/Model/UUID/DummyUuidEntity.php +++ b/Tests/Model/UUID/DummyUuidEntity.php @@ -4,7 +4,7 @@ namespace StfalconStudio\ApiBundle\Tests\Model\UUID; -use StfalconStudio\ApiBundle\Model\UUID\UuidTrait; +use StfalconStudio\ApiBundle\Model\ORM\UUID\UuidTrait; use Symfony\Component\Uid\Uuid; class DummyUuidEntity diff --git a/Tests/Serializer/CircularReferenceHandlerTest.php b/Tests/Serializer/CircularReferenceHandlerTest.php index 147dc08..9d72652 100644 --- a/Tests/Serializer/CircularReferenceHandlerTest.php +++ b/Tests/Serializer/CircularReferenceHandlerTest.php @@ -13,7 +13,7 @@ namespace StfalconStudio\ApiBundle\Tests\Serializer; use PHPUnit\Framework\TestCase; -use StfalconStudio\ApiBundle\Model\UUID\UuidInterface; +use StfalconStudio\ApiBundle\Model\ORM\UUID\UuidInterface; use StfalconStudio\ApiBundle\Serializer\CircularReferenceHandler; final class CircularReferenceHandlerTest extends TestCase From 4354cb5aa9314855a74ba118cc1f4099898370b6 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 13:25:22 +0300 Subject: [PATCH 06/21] Refactoring --- .../ORM/Aggregate/AggregatePartListener.php | 4 +- .../Aggregate/AggregatePartListenerTest.php | 128 ------------------ 2 files changed, 2 insertions(+), 130 deletions(-) delete mode 100644 Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php diff --git a/EventListener/ORM/Aggregate/AggregatePartListener.php b/EventListener/ORM/Aggregate/AggregatePartListener.php index 75af834..6ad995f 100644 --- a/EventListener/ORM/Aggregate/AggregatePartListener.php +++ b/EventListener/ORM/Aggregate/AggregatePartListener.php @@ -14,8 +14,8 @@ use Doctrine\ORM\Event\OnFlushEventArgs; use Fresh\DateTime\DateTimeHelper; -use StfalconStudio\ApiBundle\Model\Aggregate\AggregatePartInterface; -use StfalconStudio\ApiBundle\Model\Aggregate\AggregateRootInterface; +use StfalconStudio\ApiBundle\Model\ORM\Aggregate\AggregatePartInterface; +use StfalconStudio\ApiBundle\Model\ORM\Aggregate\AggregateRootInterface; /** * AggregatePartListener. diff --git a/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php b/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php deleted file mode 100644 index 55ba2ce..0000000 --- a/Tests/EventListener/ODM/Aggregate/AggregatePartListenerTest.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace StfalconStudio\ApiBundle\Tests\EventListener\ODM\Aggregate; - -use Doctrine\ODM\EntityManager; -use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs; -use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\UnitOfWork; -use Fresh\DateTime\DateTimeHelper; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use StfalconStudio\ApiBundle\EventListener\ORM\Aggregate\AggregatePartListener; -use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregatePartInterface; -use StfalconStudio\ApiBundle\Model\ODM\Aggregate\AggregateRootInterface; - -final class AggregatePartListenerTest extends TestCase -{ - private DateTimeHelper|MockObject $dateTimeHelper; - private AggregatePartListener $listener; - - protected function setUp(): void - { - $this->dateTimeHelper = $this->createMock(DateTimeHelper::class); - $this->listener = new AggregatePartListener($this->dateTimeHelper); - } - - protected function tearDown(): void - { - unset( - $this->dateTimeHelper, - $this->listener, - ); - } - - public function testOnFlush(): void - { - $eventArgs = $this->createMock(OnFlushEventArgs::class); - - $em = $this->createMock(EntityManager::class); - $eventArgs - ->expects(self::once()) - ->method('getEntityManager') - ->willReturn($em) - ; - - $uow = $this->createMock(UnitOfWork::class); - $em - ->expects(self::once()) - ->method('getUnitOfWork') - ->willReturn($uow) - ; - - $updatedEntity = new \stdClass(); - $insertedEntity = $this->createMock(AggregatePartInterface::class); - $deletedEntity = new \stdClass(); - - $uow - ->expects(self::once()) - ->method('getScheduledEntityUpdates') - ->willReturn([$updatedEntity]) - ; - - $uow - ->expects(self::once()) - ->method('getScheduledEntityInsertions') - ->willReturn([$insertedEntity]) - ; - - $uow - ->expects(self::once()) - ->method('getScheduledEntityDeletions') - ->willReturn([$deletedEntity]) - ; - - $insertedEntityAggregatedRoot = $this->createMock(AggregateRootInterface::class); - $insertedEntity - ->expects(self::once()) - ->method('getAggregateRoot') - ->willReturn($insertedEntityAggregatedRoot) - ; - - $insertedEntityAggregatedRootId = '123'; - $insertedEntityAggregatedRoot - ->expects(self::once()) - ->method('getId') - ->willReturn($insertedEntityAggregatedRootId) - ; - - $now = new \DateTime(); - $this->dateTimeHelper - ->expects(self::once()) - ->method('getCurrentDatetime') - ->willReturn($now) - ; - - $insertedEntityAggregatedRoot - ->expects(self::once()) - ->method('setUpdatedAt') - ->with($now) - ; - - $classMetadata = $this->createMock(ClassMetadata::class); - $uow - ->expects(self::once()) - ->method('recomputeSingleEntityChangeSet') - ->with($classMetadata, $insertedEntityAggregatedRoot) - ; - - $em - ->expects(self::once()) - ->method('getClassMetadata') - ->with(\get_class($insertedEntityAggregatedRoot)) - ->willReturn($classMetadata) - ; - - $this->listener->onFlush($eventArgs); - } -} From 21deeac6132ce942a3fbbe9bb9b24efa34b81d80 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 13:32:57 +0300 Subject: [PATCH 07/21] Update --- Model/ODM/UUID/UuidInterface.php | 8 +++----- Model/ORM/UUID/UuidInterface.php | 8 +++----- Model/UUID/UuidInterface.php | 24 ++++++++++++++++++++++ Tests/EventListener/Security/DummyUser.php | 2 +- 4 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 Model/UUID/UuidInterface.php diff --git a/Model/ODM/UUID/UuidInterface.php b/Model/ODM/UUID/UuidInterface.php index 0ca60c5..52bc76f 100644 --- a/Model/ODM/UUID/UuidInterface.php +++ b/Model/ODM/UUID/UuidInterface.php @@ -12,13 +12,11 @@ namespace StfalconStudio\ApiBundle\Model\ODM\UUID; +use StfalconStudio\ApiBundle\Model\UUID\UuidInterface as BaseUuidInterface; + /** * UuidInterface. */ -interface UuidInterface +interface UuidInterface extends BaseUuidInterface { - /** - * @return string - */ - public function getId(): string; } diff --git a/Model/ORM/UUID/UuidInterface.php b/Model/ORM/UUID/UuidInterface.php index 5033551..3d86af6 100644 --- a/Model/ORM/UUID/UuidInterface.php +++ b/Model/ORM/UUID/UuidInterface.php @@ -12,13 +12,11 @@ namespace StfalconStudio\ApiBundle\Model\ORM\UUID; +use StfalconStudio\ApiBundle\Model\UUID\UuidInterface as BaseUuidInterface; + /** * UuidInterface. */ -interface UuidInterface +interface UuidInterface extends BaseUuidInterface { - /** - * @return string - */ - public function getId(): string; } diff --git a/Model/UUID/UuidInterface.php b/Model/UUID/UuidInterface.php new file mode 100644 index 0000000..d06346d --- /dev/null +++ b/Model/UUID/UuidInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Model\UUID; + +/** + * UuidInterface. + */ +interface UuidInterface +{ + /** + * @return string + */ + public function getId(): string; +} diff --git a/Tests/EventListener/Security/DummyUser.php b/Tests/EventListener/Security/DummyUser.php index 2d9f585..f5f8183 100644 --- a/Tests/EventListener/Security/DummyUser.php +++ b/Tests/EventListener/Security/DummyUser.php @@ -13,7 +13,7 @@ namespace StfalconStudio\ApiBundle\Tests\EventListener\Security; use StfalconStudio\ApiBundle\Model\Credentials\CredentialsInterface; -use StfalconStudio\ApiBundle\Model\Credentials\CredentialsTrait; +use StfalconStudio\ApiBundle\Model\ORM\Credentials\CredentialsTrait; use Symfony\Component\Security\Core\User\UserInterface; class DummyUser implements UserInterface, CredentialsInterface From 4ebca397a21737a9d7b9a876f9939ea67f475d5d Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 14:06:26 +0300 Subject: [PATCH 08/21] Fix test --- Tests/Model/Credentials/DummyCredentialsEntity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Model/Credentials/DummyCredentialsEntity.php b/Tests/Model/Credentials/DummyCredentialsEntity.php index 0a15184..1e3f213 100644 --- a/Tests/Model/Credentials/DummyCredentialsEntity.php +++ b/Tests/Model/Credentials/DummyCredentialsEntity.php @@ -12,8 +12,8 @@ namespace StfalconStudio\ApiBundle\Tests\Model\Credentials; -use StfalconStudio\ApiBundle\Model\Credentials\CredentialsInterface; -use StfalconStudio\ApiBundle\Model\Credentials\CredentialsTrait; +use StfalconStudio\ApiBundle\Model\ORM\Credentials\CredentialsInterface; +use StfalconStudio\ApiBundle\Model\ORM\Credentials\CredentialsTrait; class DummyCredentialsEntity implements CredentialsInterface { From d592f80b74af06a696643b33cbdc3d64a7876649 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 21 Sep 2023 14:06:26 +0300 Subject: [PATCH 09/21] Fix test --- Error/BaseErrorNames.php | 3 ++ .../Kernel/ApiExceptionFormatterListener.php | 9 ++++ Model/UUID/UuidInterface.php | 4 +- Resources/translations/messages.ar.xlf | 4 ++ Resources/translations/messages.en.xlf | 4 ++ Resources/translations/messages.fr.xlf | 4 ++ Resources/translations/messages.ru.xlf | 4 ++ Resources/translations/messages.uk.xlf | 4 ++ .../ApiExceptionFormatterListenerTest.php | 50 +++++++++++++++++++ Tests/Security/DummyUser.php | 4 +- 10 files changed, 86 insertions(+), 4 deletions(-) diff --git a/Error/BaseErrorNames.php b/Error/BaseErrorNames.php index a2af827..4e261fc 100644 --- a/Error/BaseErrorNames.php +++ b/Error/BaseErrorNames.php @@ -41,6 +41,9 @@ class BaseErrorNames // 405 public final const METHOD_NOT_ALLOWED = 'method_not_allowed'; + // 406 + public final const NOT_ACCEPTABLE = 'not_acceptable'; + // 409 public final const CONFLICT_TARGET_RESOURCE_UPDATE = 'conflict_target_resource_update'; diff --git a/EventListener/Kernel/ApiExceptionFormatterListener.php b/EventListener/Kernel/ApiExceptionFormatterListener.php index ee17e04..b3b7f1f 100644 --- a/EventListener/Kernel/ApiExceptionFormatterListener.php +++ b/EventListener/Kernel/ApiExceptionFormatterListener.php @@ -26,6 +26,7 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Security\Core\Exception\AccessDeniedException; @@ -95,6 +96,11 @@ public function __invoke(ExceptionEvent $event): void $statusCode = Response::HTTP_METHOD_NOT_ALLOWED; $errorName = BaseErrorNames::METHOD_NOT_ALLOWED; break; + case $e instanceof NotAcceptableHttpException: + $message = 'not_acceptable_exception_message'; + $statusCode = Response::HTTP_NOT_ACCEPTABLE; + $errorName = BaseErrorNames::NOT_ACCEPTABLE; + break; case $e instanceof NotFoundHttpException: $message = $e->getMessage(); $statusCode = $e->getStatusCode(); @@ -124,6 +130,9 @@ public function __invoke(ExceptionEvent $event): void case Response::HTTP_FORBIDDEN: $errorName = BaseErrorNames::ACCESS_DENIED; break; + case Response::HTTP_NOT_ACCEPTABLE: + $errorName = BaseErrorNames::NOT_ACCEPTABLE; + break; case Response::HTTP_INTERNAL_SERVER_ERROR: $errorName = BaseErrorNames::INTERNAL_SERVER_ERROR; diff --git a/Model/UUID/UuidInterface.php b/Model/UUID/UuidInterface.php index d06346d..46d0973 100644 --- a/Model/UUID/UuidInterface.php +++ b/Model/UUID/UuidInterface.php @@ -18,7 +18,7 @@ interface UuidInterface { /** - * @return string + * @return string|null */ - public function getId(): string; + public function getId(): ?string; } diff --git a/Resources/translations/messages.ar.xlf b/Resources/translations/messages.ar.xlf index 9b971cf..544e096 100644 --- a/Resources/translations/messages.ar.xlf +++ b/Resources/translations/messages.ar.xlf @@ -50,6 +50,10 @@ internal_server_error_exception_message خطأ في الخادم الداخلي. + + not_acceptable_exception_message + غير مقبول + diff --git a/Resources/translations/messages.en.xlf b/Resources/translations/messages.en.xlf index 597ee92..db0e1e7 100644 --- a/Resources/translations/messages.en.xlf +++ b/Resources/translations/messages.en.xlf @@ -50,6 +50,10 @@ internal_server_error_exception_message Internal Server Error. + + not_acceptable_exception_message + Not Acceptable. + diff --git a/Resources/translations/messages.fr.xlf b/Resources/translations/messages.fr.xlf index e33584a..24e3c8b 100644 --- a/Resources/translations/messages.fr.xlf +++ b/Resources/translations/messages.fr.xlf @@ -50,6 +50,10 @@ internal_server_error_exception_message Erreur Interne Serveur. + + not_acceptable_exception_message + Pas acceptable. + diff --git a/Resources/translations/messages.ru.xlf b/Resources/translations/messages.ru.xlf index a6b6917..1a85f1d 100644 --- a/Resources/translations/messages.ru.xlf +++ b/Resources/translations/messages.ru.xlf @@ -50,6 +50,10 @@ internal_server_error_exception_message Внутренняя ошибка сервера. + + not_acceptable_exception_message + Недопустимый запрос. + diff --git a/Resources/translations/messages.uk.xlf b/Resources/translations/messages.uk.xlf index df113c5..98ed513 100644 --- a/Resources/translations/messages.uk.xlf +++ b/Resources/translations/messages.uk.xlf @@ -50,6 +50,10 @@ internal_server_error_exception_message Внутрішня помилка сервера. + + not_acceptable_exception_message + Не прийнятний запит. + diff --git a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php index 1167b3b..32c3c96 100644 --- a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php +++ b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php @@ -639,6 +639,56 @@ public function testOnKernelExceptionMethodNotAllowedHttpException(): void self::assertInstanceOf(MethodNotAllowedHttpException::class, $exceptionEvent->getThrowable()); } + public function testOnKernelExceptionNotAcceptableHttpException(): void + { + $exceptionMessage = 'not_acceptable_exception_message'; + $httpException = new MethodNotAllowedHttpException(['POST'], $exceptionMessage); + + $exceptionEvent = new ExceptionEvent( + $this->kernel, + $this->request, + HttpKernelInterface::MAIN_REQUEST, + $httpException + ); + + $this->request + ->expects(self::once()) + ->method('getHost') + ->willReturn(self::API_HOST) + ; + + $this->translator + ->expects(self::once()) + ->method('trans') + ->with($exceptionMessage) + ->willReturn($exceptionMessage) + ; + + $message = 'Not Acceptable.'; + $this->serializer + ->expects(self::once()) + ->method('serialize') + ->willReturn(sprintf('{"error":"not_acceptable", "error_description":"%s"}', $message)) + ; + + $this->exceptionResponseProcessor + ->expects(self::never()) + ->method('processResponseForException') + ; + + $json = '{"error":"not_acceptable", "error_description":"Not Acceptable."}'; + $this->exceptionResponseFactory + ->expects(self::once()) + ->method('createJsonResponse') + ->with($json, Response::HTTP_METHOD_NOT_ALLOWED) + ->willReturn($this->response) + ; + + $this->exceptionFormatterListener->__invoke($exceptionEvent); + + self::assertInstanceOf(MethodNotAllowedHttpException::class, $exceptionEvent->getThrowable()); + } + public function testOnKernelExceptionDummyHttpException(): void { $exceptionMessage = 'exception_message'; diff --git a/Tests/Security/DummyUser.php b/Tests/Security/DummyUser.php index a9b72ae..fa35dbc 100644 --- a/Tests/Security/DummyUser.php +++ b/Tests/Security/DummyUser.php @@ -12,8 +12,8 @@ namespace StfalconStudio\ApiBundle\Tests\Security; -use StfalconStudio\ApiBundle\Model\Credentials\CredentialsInterface; -use StfalconStudio\ApiBundle\Model\Credentials\CredentialsTrait; +use StfalconStudio\ApiBundle\Model\ORM\Credentials\CredentialsInterface; +use StfalconStudio\ApiBundle\Model\ORM\Credentials\CredentialsTrait; use Symfony\Component\Security\Core\User\UserInterface; class DummyUser implements UserInterface, CredentialsInterface From 0421cd92898d6669f0b4005d1184ba70a4a4eee9 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 10 Oct 2023 13:29:35 +0300 Subject: [PATCH 10/21] Fix test --- .../EventListener/Kernel/ApiExceptionFormatterListenerTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php index 32c3c96..af9f475 100644 --- a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php +++ b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php @@ -28,6 +28,7 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -642,7 +643,7 @@ public function testOnKernelExceptionMethodNotAllowedHttpException(): void public function testOnKernelExceptionNotAcceptableHttpException(): void { $exceptionMessage = 'not_acceptable_exception_message'; - $httpException = new MethodNotAllowedHttpException(['POST'], $exceptionMessage); + $httpException = new NotAcceptableHttpException($exceptionMessage); $exceptionEvent = new ExceptionEvent( $this->kernel, From b6725f07368230d0e5b0a396e91c3c45f42c0c7e Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 10 Oct 2023 13:29:35 +0300 Subject: [PATCH 11/21] Fix test --- .../EventListener/Kernel/ApiExceptionFormatterListenerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php index af9f475..563d803 100644 --- a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php +++ b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php @@ -681,7 +681,7 @@ public function testOnKernelExceptionNotAcceptableHttpException(): void $this->exceptionResponseFactory ->expects(self::once()) ->method('createJsonResponse') - ->with($json, Response::HTTP_METHOD_NOT_ALLOWED) + ->with($json, Response::HTTP_NOT_ACCEPTABLE) ->willReturn($this->response) ; From 8ad0f2bab8e45fe9b8e70a4a11a295eacd0109b4 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 10 Oct 2023 15:36:34 +0300 Subject: [PATCH 12/21] Fix test --- .../EventListener/Kernel/ApiExceptionFormatterListenerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php index 563d803..acb7de4 100644 --- a/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php +++ b/Tests/EventListener/Kernel/ApiExceptionFormatterListenerTest.php @@ -687,7 +687,7 @@ public function testOnKernelExceptionNotAcceptableHttpException(): void $this->exceptionFormatterListener->__invoke($exceptionEvent); - self::assertInstanceOf(MethodNotAllowedHttpException::class, $exceptionEvent->getThrowable()); + self::assertInstanceOf(NotAcceptableHttpException::class, $exceptionEvent->getThrowable()); } public function testOnKernelExceptionDummyHttpException(): void From c641ffcc14b94f39a91e59e0c45722496db1b1d1 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 4 Apr 2024 13:20:02 +0300 Subject: [PATCH 13/21] Update translations --- EventListener/JWT/JwtSubscriber.php | 19 +++----- Resources/translations/messages.de.xlf | 59 ++++++++++++++++++++++++ Resources/translations/messages.fr.xlf | 2 +- Resources/translations/validators.de.xlf | 11 +++++ Resources/translations/validators.fr.xlf | 2 +- 5 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 Resources/translations/messages.de.xlf create mode 100644 Resources/translations/validators.de.xlf diff --git a/EventListener/JWT/JwtSubscriber.php b/EventListener/JWT/JwtSubscriber.php index abaf837..dd78719 100644 --- a/EventListener/JWT/JwtSubscriber.php +++ b/EventListener/JWT/JwtSubscriber.php @@ -56,19 +56,12 @@ public static function getSubscribedEvents(): iterable */ public function onAuthenticationFailureResponse(AuthenticationFailureEvent $event): void { - switch (true) { - case $event instanceof JWTInvalidEvent: - $message = 'invalid_jwt_token_message'; - break; - case $event instanceof JWTNotFoundEvent: - $message = 'not_found_jwt_token_message'; - break; - case $event instanceof JWTExpiredEvent: - $message = 'expired_jwt_token_message'; - break; - default: - $message = 'unauthorised_user_message'; - } + $message = match (true) { + $event instanceof JWTInvalidEvent => 'invalid_jwt_token_message', + $event instanceof JWTNotFoundEvent => 'not_found_jwt_token_message', + $event instanceof JWTExpiredEvent => 'expired_jwt_token_message', + default => 'unauthorised_user_message', + }; $data = [ 'error' => BaseErrorNames::UNAUTHORISED_USER, diff --git a/Resources/translations/messages.de.xlf b/Resources/translations/messages.de.xlf new file mode 100644 index 0000000..448def1 --- /dev/null +++ b/Resources/translations/messages.de.xlf @@ -0,0 +1,59 @@ + + + + + + unauthorised_user_message + Schlechte Anmeldedaten. Bitte überprüfen Sie, ob Ihr Login/Passwort richtig eingestellt ist. + + + invalid_jwt_token_message + Schlechte Anmeldedaten. Versuchen Sie erneut, sich anzumelden. + + + not_found_jwt_token_message + Schlechte Anmeldedaten. Versuchen Sie erneut, sich anzumelden. + + + expired_jwt_token_message + Schlechte Anmeldedaten. Versuchen Sie erneut, sich anzumelden. + + + invalid_refresh_token_exception_message + Schlechte Anmeldedaten. Versuchen Sie erneut, sich anzumelden. + + + optimistic_lock_exception_message + Die Ressource wurde aktualisiert. Bitte holen Sie sich die aktuellen Daten. + + + access_denied_exception_message + Zugriff abgelehnt. + + + method_not_allowed_exception_message + Nicht zulässige HTTP-Methode. + + + resource_not_found_exception_message + Ressource nicht gefunden. + + + invalid_json_schema_exception_message + Ihre Anfrage entspricht nicht dem angegebenen JSON-Schema. + + + invalid_entity_exception_message + Die Entität erfüllt die Validierungsregeln nicht. + + + internal_server_error_exception_message + Internal Server Error. + + + not_acceptable_exception_message + Inakzeptabel. + + + + diff --git a/Resources/translations/messages.fr.xlf b/Resources/translations/messages.fr.xlf index 24e3c8b..9075f45 100644 --- a/Resources/translations/messages.fr.xlf +++ b/Resources/translations/messages.fr.xlf @@ -1,6 +1,6 @@ - + unauthorised_user_message diff --git a/Resources/translations/validators.de.xlf b/Resources/translations/validators.de.xlf new file mode 100644 index 0000000..5f56ae9 --- /dev/null +++ b/Resources/translations/validators.de.xlf @@ -0,0 +1,11 @@ + + + + + + password_does_not_meet_special_requirements + Passwort entspricht nicht der Anforderungen. Es muss einen Kleinbuchstaben, einen Großbuchstaben und eine Ziffer enthalten. + + + + diff --git a/Resources/translations/validators.fr.xlf b/Resources/translations/validators.fr.xlf index 55be2af..0ddd2c9 100644 --- a/Resources/translations/validators.fr.xlf +++ b/Resources/translations/validators.fr.xlf @@ -1,6 +1,6 @@ - + password_does_not_meet_special_requirements From 4e155ba129a4f4a55e7ae8b2d135ee905560dd81 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Fri, 12 Apr 2024 10:25:18 +0300 Subject: [PATCH 14/21] Refactoring --- Asset/DatetimeVersionStrategy.php | 5 +++-- Event/User/AbstractUserEvent.php | 5 +++-- EventListener/JWT/JwtSubscriber.php | 5 +++-- EventListener/JWT/TokenBlackListSubscriber.php | 5 +++-- EventListener/Kernel/ApiExceptionFormatterListener.php | 8 ++++++-- EventListener/ODM/Aggregate/AggregatePartListener.php | 5 +++-- EventListener/ORM/Aggregate/AggregatePartListener.php | 5 +++-- EventListener/Security/CheckVerifiedUserSubscriber.php | 5 +++-- Request/DtoExtractor.php | 6 ++++-- Security/JwtBlackListService.php | 8 ++++++-- Security/JwtTokenHelper.php | 5 +++-- .../Normalizer/ConstraintViolationListNormalizer.php | 5 +++-- Serializer/Serializer.php | 2 +- .../AttributeProcessor/JsonSchemaAttributeProcessor.php | 7 +++++-- Service/DependentEntity/DependentEntityService.php | 5 +++-- .../ResponseProcessor/ExceptionResponseProcessor.php | 5 +++-- Validator/Constraints/Entity/EntityExistsValidator.php | 5 +++-- .../Password/PasswordMeetSpecialRequirementsValidator.php | 5 +++-- Validator/JsonSchemaValidator.php | 6 ++++-- 19 files changed, 65 insertions(+), 37 deletions(-) diff --git a/Asset/DatetimeVersionStrategy.php b/Asset/DatetimeVersionStrategy.php index c986e39..2cec8e1 100644 --- a/Asset/DatetimeVersionStrategy.php +++ b/Asset/DatetimeVersionStrategy.php @@ -27,8 +27,9 @@ class DatetimeVersionStrategy implements VersionStrategyInterface /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct(DateTimeHelper $dateTimeHelper) - { + public function __construct( + private readonly DateTimeHelper $dateTimeHelper, + ) { $this->version = $dateTimeHelper->getCurrentDatetimeImmutable()->format('YmdHis'); } diff --git a/Event/User/AbstractUserEvent.php b/Event/User/AbstractUserEvent.php index c782738..d447eff 100644 --- a/Event/User/AbstractUserEvent.php +++ b/Event/User/AbstractUserEvent.php @@ -23,8 +23,9 @@ abstract class AbstractUserEvent extends Event /** * @param UserInterface $user */ - public function __construct(private readonly UserInterface $user) - { + public function __construct( + private readonly UserInterface $user, + ) { } /** diff --git a/EventListener/JWT/JwtSubscriber.php b/EventListener/JWT/JwtSubscriber.php index dd78719..a98c352 100644 --- a/EventListener/JWT/JwtSubscriber.php +++ b/EventListener/JWT/JwtSubscriber.php @@ -32,8 +32,9 @@ final class JwtSubscriber implements EventSubscriberInterface /** * @param TranslatorInterface $translator */ - public function __construct(private readonly TranslatorInterface $translator) - { + public function __construct( + private readonly TranslatorInterface $translator, + ) { } /** diff --git a/EventListener/JWT/TokenBlackListSubscriber.php b/EventListener/JWT/TokenBlackListSubscriber.php index e9ed6e8..1f3b252 100644 --- a/EventListener/JWT/TokenBlackListSubscriber.php +++ b/EventListener/JWT/TokenBlackListSubscriber.php @@ -25,8 +25,9 @@ final class TokenBlackListSubscriber implements EventSubscriberInterface /** * @param JwtBlackListService $tokenBlackListService */ - public function __construct(private readonly JwtBlackListService $tokenBlackListService) - { + public function __construct( + private readonly JwtBlackListService $tokenBlackListService, + ) { } /** diff --git a/EventListener/Kernel/ApiExceptionFormatterListener.php b/EventListener/Kernel/ApiExceptionFormatterListener.php index 04d02e1..6a13d02 100644 --- a/EventListener/Kernel/ApiExceptionFormatterListener.php +++ b/EventListener/Kernel/ApiExceptionFormatterListener.php @@ -47,8 +47,12 @@ final class ApiExceptionFormatterListener implements EventSubscriberInterface * @param ExceptionResponseProcessorInterface $exceptionResponseProcessor * @param ExceptionResponseFactory $exceptionResponseFactory */ - public function __construct(private readonly string $apiHost, private readonly string $environment, private readonly ExceptionResponseProcessorInterface $exceptionResponseProcessor, private readonly ExceptionResponseFactory $exceptionResponseFactory) - { + public function __construct( + private readonly string $apiHost, + private readonly string $environment, + private readonly ExceptionResponseProcessorInterface $exceptionResponseProcessor, + private readonly ExceptionResponseFactory $exceptionResponseFactory, + ) { } /** diff --git a/EventListener/ODM/Aggregate/AggregatePartListener.php b/EventListener/ODM/Aggregate/AggregatePartListener.php index 4fa04ce..2ef413e 100644 --- a/EventListener/ODM/Aggregate/AggregatePartListener.php +++ b/EventListener/ODM/Aggregate/AggregatePartListener.php @@ -28,8 +28,9 @@ final class AggregatePartListener /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct(private readonly DateTimeHelper $dateTimeHelper) - { + public function __construct( + private readonly DateTimeHelper $dateTimeHelper, + ) { } /** diff --git a/EventListener/ORM/Aggregate/AggregatePartListener.php b/EventListener/ORM/Aggregate/AggregatePartListener.php index df58e1a..f29ce2c 100644 --- a/EventListener/ORM/Aggregate/AggregatePartListener.php +++ b/EventListener/ORM/Aggregate/AggregatePartListener.php @@ -28,8 +28,9 @@ final class AggregatePartListener /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct(private readonly DateTimeHelper $dateTimeHelper) - { + public function __construct( + private readonly DateTimeHelper $dateTimeHelper, + ) { } /** diff --git a/EventListener/Security/CheckVerifiedUserSubscriber.php b/EventListener/Security/CheckVerifiedUserSubscriber.php index f6f2bd3..134def9 100644 --- a/EventListener/Security/CheckVerifiedUserSubscriber.php +++ b/EventListener/Security/CheckVerifiedUserSubscriber.php @@ -26,8 +26,9 @@ final class CheckVerifiedUserSubscriber implements EventSubscriberInterface /** * @param JwtBlackListService $tokenBlackListService */ - public function __construct(private readonly JwtBlackListService $tokenBlackListService) - { + public function __construct( + private readonly JwtBlackListService $tokenBlackListService, + ) { } /** diff --git a/Request/DtoExtractor.php b/Request/DtoExtractor.php index 0e8a1fd..adb7052 100644 --- a/Request/DtoExtractor.php +++ b/Request/DtoExtractor.php @@ -29,8 +29,10 @@ class DtoExtractor * @param DtoAttributeProcessor $dtoAttributeProcessor * @param SerializerInterface $serializer */ - public function __construct(private readonly DtoAttributeProcessor $dtoAttributeProcessor, private readonly SerializerInterface $serializer) - { + public function __construct( + private readonly DtoAttributeProcessor $dtoAttributeProcessor, + private readonly SerializerInterface $serializer, + ) { } /** diff --git a/Security/JwtBlackListService.php b/Security/JwtBlackListService.php index f477b67..41f58ef 100644 --- a/Security/JwtBlackListService.php +++ b/Security/JwtBlackListService.php @@ -33,8 +33,12 @@ class JwtBlackListService * @param JwtCacheHelper $jwtCacheHelper * @param DateTimeHelper $dateTimeHelper */ - public function __construct(private readonly JWSProviderInterface $jwsProvider, private readonly JwtTokenHelper $jwtTokenHelper, private readonly JwtCacheHelper $jwtCacheHelper, private readonly DateTimeHelper $dateTimeHelper) - { + public function __construct( + private readonly JWSProviderInterface $jwsProvider, + private readonly JwtTokenHelper $jwtTokenHelper, + private readonly JwtCacheHelper $jwtCacheHelper, + private readonly DateTimeHelper $dateTimeHelper, + ) { } /** diff --git a/Security/JwtTokenHelper.php b/Security/JwtTokenHelper.php index a07e942..b3d0e6d 100644 --- a/Security/JwtTokenHelper.php +++ b/Security/JwtTokenHelper.php @@ -25,8 +25,9 @@ class JwtTokenHelper /** * @param TokenStorageInterface $tokenStorage */ - public function __construct(private readonly TokenStorageInterface $tokenStorage) - { + public function __construct( + private readonly TokenStorageInterface $tokenStorage, + ) { } /** diff --git a/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/Serializer/Normalizer/ConstraintViolationListNormalizer.php index f67583a..e38c33c 100644 --- a/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -23,8 +23,9 @@ class ConstraintViolationListNormalizer implements NormalizerInterface /** * @param NormalizerInterface $symfonyConstraintViolationListNormalizer */ - public function __construct(private readonly NormalizerInterface $symfonyConstraintViolationListNormalizer) - { + public function __construct( + private readonly NormalizerInterface $symfonyConstraintViolationListNormalizer, + ) { } /** diff --git a/Serializer/Serializer.php b/Serializer/Serializer.php index b149d08..22754f2 100644 --- a/Serializer/Serializer.php +++ b/Serializer/Serializer.php @@ -42,7 +42,7 @@ public function serialize(object|array $object, string $serializationGroup, arra $context, [ 'group' => $serializationGroup, - 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE, + 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES, ] ); diff --git a/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php b/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php index 212e8d1..cf28658 100644 --- a/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php +++ b/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php @@ -32,8 +32,11 @@ class JsonSchemaAttributeProcessor * @param FileReader $fileReader * @param string $jsonSchemaDir */ - public function __construct(private readonly DtoAttributeProcessor $dtoAttributeProcessor, private readonly FileReader $fileReader, private readonly string $jsonSchemaDir) - { + public function __construct( + private readonly DtoAttributeProcessor $dtoAttributeProcessor, + private readonly FileReader $fileReader, + private readonly string $jsonSchemaDir, + ) { } /** diff --git a/Service/DependentEntity/DependentEntityService.php b/Service/DependentEntity/DependentEntityService.php index ec9a402..e819a6c 100644 --- a/Service/DependentEntity/DependentEntityService.php +++ b/Service/DependentEntity/DependentEntityService.php @@ -28,8 +28,9 @@ class DependentEntityService /** * @param RepositoryService $repositoryService */ - public function __construct(private readonly RepositoryService $repositoryService) - { + public function __construct( + private readonly RepositoryService $repositoryService, + ) { } /** diff --git a/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php b/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php index fed453a..fa8d97a 100644 --- a/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php +++ b/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php @@ -22,8 +22,9 @@ class ExceptionResponseProcessor implements ExceptionResponseProcessorInterface /** * @param iterable|CustomAppExceptionResponseProcessorInterface[] $errorResponseProcessors */ - public function __construct(private readonly iterable $errorResponseProcessors) - { + public function __construct( + private readonly iterable $errorResponseProcessors, + ) { } /** diff --git a/Validator/Constraints/Entity/EntityExistsValidator.php b/Validator/Constraints/Entity/EntityExistsValidator.php index 698d109..11b883b 100644 --- a/Validator/Constraints/Entity/EntityExistsValidator.php +++ b/Validator/Constraints/Entity/EntityExistsValidator.php @@ -25,8 +25,9 @@ class EntityExistsValidator extends ConstraintValidator /** * @param RepositoryService $repositoryService */ - public function __construct(private readonly RepositoryService $repositoryService) - { + public function __construct( + private readonly RepositoryService $repositoryService, + ) { } /** diff --git a/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php b/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php index b26d2cd..48f127d 100644 --- a/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php +++ b/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php @@ -25,8 +25,9 @@ class PasswordMeetSpecialRequirementsValidator extends ConstraintValidator /** * @param PasswordRequirementsValidator $passwordRequirementsValidator */ - public function __construct(private readonly PasswordRequirementsValidator $passwordRequirementsValidator) - { + public function __construct( + private readonly PasswordRequirementsValidator $passwordRequirementsValidator, + ) { } /** diff --git a/Validator/JsonSchemaValidator.php b/Validator/JsonSchemaValidator.php index 7c1766a..4f23aa3 100644 --- a/Validator/JsonSchemaValidator.php +++ b/Validator/JsonSchemaValidator.php @@ -34,8 +34,10 @@ class JsonSchemaValidator * @param Validator $validator * @param JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor */ - public function __construct(private readonly Validator $validator, private readonly JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor) - { + public function __construct( + private readonly Validator $validator, + private readonly JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor, + ) { } /** From 0e5a88cc16fc6025ae13fb9c705817e4d39fb81e Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Fri, 12 Apr 2024 10:28:41 +0300 Subject: [PATCH 15/21] Update serializer --- Serializer/Serializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Serializer/Serializer.php b/Serializer/Serializer.php index 22754f2..b149d08 100644 --- a/Serializer/Serializer.php +++ b/Serializer/Serializer.php @@ -42,7 +42,7 @@ public function serialize(object|array $object, string $serializationGroup, arra $context, [ 'group' => $serializationGroup, - 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES, + 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE, ] ); From b138c271a6f1658e0c3c90307d37932a98b9d447 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Fri, 12 Apr 2024 10:32:47 +0300 Subject: [PATCH 16/21] Revert "Update serializer" This reverts commit 0e5a88cc16fc6025ae13fb9c705817e4d39fb81e. --- Serializer/Serializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Serializer/Serializer.php b/Serializer/Serializer.php index b149d08..22754f2 100644 --- a/Serializer/Serializer.php +++ b/Serializer/Serializer.php @@ -42,7 +42,7 @@ public function serialize(object|array $object, string $serializationGroup, arra $context, [ 'group' => $serializationGroup, - 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE, + 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES, ] ); From 2709e87034b5189af1c2607b4a3b7281f17e672e Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Fri, 12 Apr 2024 10:32:47 +0300 Subject: [PATCH 17/21] Revert "Refactoring" This reverts commit 4e155ba129a4f4a55e7ae8b2d135ee905560dd81. --- Asset/DatetimeVersionStrategy.php | 5 ++--- Event/User/AbstractUserEvent.php | 5 ++--- EventListener/JWT/JwtSubscriber.php | 5 ++--- EventListener/JWT/TokenBlackListSubscriber.php | 5 ++--- EventListener/Kernel/ApiExceptionFormatterListener.php | 8 ++------ EventListener/ODM/Aggregate/AggregatePartListener.php | 5 ++--- EventListener/ORM/Aggregate/AggregatePartListener.php | 5 ++--- EventListener/Security/CheckVerifiedUserSubscriber.php | 5 ++--- Request/DtoExtractor.php | 6 ++---- Security/JwtBlackListService.php | 8 ++------ Security/JwtTokenHelper.php | 5 ++--- .../Normalizer/ConstraintViolationListNormalizer.php | 5 ++--- Serializer/Serializer.php | 2 +- .../AttributeProcessor/JsonSchemaAttributeProcessor.php | 7 ++----- Service/DependentEntity/DependentEntityService.php | 5 ++--- .../ResponseProcessor/ExceptionResponseProcessor.php | 5 ++--- Validator/Constraints/Entity/EntityExistsValidator.php | 5 ++--- .../Password/PasswordMeetSpecialRequirementsValidator.php | 5 ++--- Validator/JsonSchemaValidator.php | 6 ++---- 19 files changed, 37 insertions(+), 65 deletions(-) diff --git a/Asset/DatetimeVersionStrategy.php b/Asset/DatetimeVersionStrategy.php index 2cec8e1..c986e39 100644 --- a/Asset/DatetimeVersionStrategy.php +++ b/Asset/DatetimeVersionStrategy.php @@ -27,9 +27,8 @@ class DatetimeVersionStrategy implements VersionStrategyInterface /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct( - private readonly DateTimeHelper $dateTimeHelper, - ) { + public function __construct(DateTimeHelper $dateTimeHelper) + { $this->version = $dateTimeHelper->getCurrentDatetimeImmutable()->format('YmdHis'); } diff --git a/Event/User/AbstractUserEvent.php b/Event/User/AbstractUserEvent.php index d447eff..c782738 100644 --- a/Event/User/AbstractUserEvent.php +++ b/Event/User/AbstractUserEvent.php @@ -23,9 +23,8 @@ abstract class AbstractUserEvent extends Event /** * @param UserInterface $user */ - public function __construct( - private readonly UserInterface $user, - ) { + public function __construct(private readonly UserInterface $user) + { } /** diff --git a/EventListener/JWT/JwtSubscriber.php b/EventListener/JWT/JwtSubscriber.php index a98c352..dd78719 100644 --- a/EventListener/JWT/JwtSubscriber.php +++ b/EventListener/JWT/JwtSubscriber.php @@ -32,9 +32,8 @@ final class JwtSubscriber implements EventSubscriberInterface /** * @param TranslatorInterface $translator */ - public function __construct( - private readonly TranslatorInterface $translator, - ) { + public function __construct(private readonly TranslatorInterface $translator) + { } /** diff --git a/EventListener/JWT/TokenBlackListSubscriber.php b/EventListener/JWT/TokenBlackListSubscriber.php index 1f3b252..e9ed6e8 100644 --- a/EventListener/JWT/TokenBlackListSubscriber.php +++ b/EventListener/JWT/TokenBlackListSubscriber.php @@ -25,9 +25,8 @@ final class TokenBlackListSubscriber implements EventSubscriberInterface /** * @param JwtBlackListService $tokenBlackListService */ - public function __construct( - private readonly JwtBlackListService $tokenBlackListService, - ) { + public function __construct(private readonly JwtBlackListService $tokenBlackListService) + { } /** diff --git a/EventListener/Kernel/ApiExceptionFormatterListener.php b/EventListener/Kernel/ApiExceptionFormatterListener.php index 6a13d02..04d02e1 100644 --- a/EventListener/Kernel/ApiExceptionFormatterListener.php +++ b/EventListener/Kernel/ApiExceptionFormatterListener.php @@ -47,12 +47,8 @@ final class ApiExceptionFormatterListener implements EventSubscriberInterface * @param ExceptionResponseProcessorInterface $exceptionResponseProcessor * @param ExceptionResponseFactory $exceptionResponseFactory */ - public function __construct( - private readonly string $apiHost, - private readonly string $environment, - private readonly ExceptionResponseProcessorInterface $exceptionResponseProcessor, - private readonly ExceptionResponseFactory $exceptionResponseFactory, - ) { + public function __construct(private readonly string $apiHost, private readonly string $environment, private readonly ExceptionResponseProcessorInterface $exceptionResponseProcessor, private readonly ExceptionResponseFactory $exceptionResponseFactory) + { } /** diff --git a/EventListener/ODM/Aggregate/AggregatePartListener.php b/EventListener/ODM/Aggregate/AggregatePartListener.php index 2ef413e..4fa04ce 100644 --- a/EventListener/ODM/Aggregate/AggregatePartListener.php +++ b/EventListener/ODM/Aggregate/AggregatePartListener.php @@ -28,9 +28,8 @@ final class AggregatePartListener /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct( - private readonly DateTimeHelper $dateTimeHelper, - ) { + public function __construct(private readonly DateTimeHelper $dateTimeHelper) + { } /** diff --git a/EventListener/ORM/Aggregate/AggregatePartListener.php b/EventListener/ORM/Aggregate/AggregatePartListener.php index f29ce2c..df58e1a 100644 --- a/EventListener/ORM/Aggregate/AggregatePartListener.php +++ b/EventListener/ORM/Aggregate/AggregatePartListener.php @@ -28,9 +28,8 @@ final class AggregatePartListener /** * @param DateTimeHelper $dateTimeHelper */ - public function __construct( - private readonly DateTimeHelper $dateTimeHelper, - ) { + public function __construct(private readonly DateTimeHelper $dateTimeHelper) + { } /** diff --git a/EventListener/Security/CheckVerifiedUserSubscriber.php b/EventListener/Security/CheckVerifiedUserSubscriber.php index 134def9..f6f2bd3 100644 --- a/EventListener/Security/CheckVerifiedUserSubscriber.php +++ b/EventListener/Security/CheckVerifiedUserSubscriber.php @@ -26,9 +26,8 @@ final class CheckVerifiedUserSubscriber implements EventSubscriberInterface /** * @param JwtBlackListService $tokenBlackListService */ - public function __construct( - private readonly JwtBlackListService $tokenBlackListService, - ) { + public function __construct(private readonly JwtBlackListService $tokenBlackListService) + { } /** diff --git a/Request/DtoExtractor.php b/Request/DtoExtractor.php index adb7052..0e8a1fd 100644 --- a/Request/DtoExtractor.php +++ b/Request/DtoExtractor.php @@ -29,10 +29,8 @@ class DtoExtractor * @param DtoAttributeProcessor $dtoAttributeProcessor * @param SerializerInterface $serializer */ - public function __construct( - private readonly DtoAttributeProcessor $dtoAttributeProcessor, - private readonly SerializerInterface $serializer, - ) { + public function __construct(private readonly DtoAttributeProcessor $dtoAttributeProcessor, private readonly SerializerInterface $serializer) + { } /** diff --git a/Security/JwtBlackListService.php b/Security/JwtBlackListService.php index 41f58ef..f477b67 100644 --- a/Security/JwtBlackListService.php +++ b/Security/JwtBlackListService.php @@ -33,12 +33,8 @@ class JwtBlackListService * @param JwtCacheHelper $jwtCacheHelper * @param DateTimeHelper $dateTimeHelper */ - public function __construct( - private readonly JWSProviderInterface $jwsProvider, - private readonly JwtTokenHelper $jwtTokenHelper, - private readonly JwtCacheHelper $jwtCacheHelper, - private readonly DateTimeHelper $dateTimeHelper, - ) { + public function __construct(private readonly JWSProviderInterface $jwsProvider, private readonly JwtTokenHelper $jwtTokenHelper, private readonly JwtCacheHelper $jwtCacheHelper, private readonly DateTimeHelper $dateTimeHelper) + { } /** diff --git a/Security/JwtTokenHelper.php b/Security/JwtTokenHelper.php index b3d0e6d..a07e942 100644 --- a/Security/JwtTokenHelper.php +++ b/Security/JwtTokenHelper.php @@ -25,9 +25,8 @@ class JwtTokenHelper /** * @param TokenStorageInterface $tokenStorage */ - public function __construct( - private readonly TokenStorageInterface $tokenStorage, - ) { + public function __construct(private readonly TokenStorageInterface $tokenStorage) + { } /** diff --git a/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/Serializer/Normalizer/ConstraintViolationListNormalizer.php index e38c33c..f67583a 100644 --- a/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -23,9 +23,8 @@ class ConstraintViolationListNormalizer implements NormalizerInterface /** * @param NormalizerInterface $symfonyConstraintViolationListNormalizer */ - public function __construct( - private readonly NormalizerInterface $symfonyConstraintViolationListNormalizer, - ) { + public function __construct(private readonly NormalizerInterface $symfonyConstraintViolationListNormalizer) + { } /** diff --git a/Serializer/Serializer.php b/Serializer/Serializer.php index 22754f2..b149d08 100644 --- a/Serializer/Serializer.php +++ b/Serializer/Serializer.php @@ -42,7 +42,7 @@ public function serialize(object|array $object, string $serializationGroup, arra $context, [ 'group' => $serializationGroup, - 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES, + 'json_encode_options' => \JSON_UNESCAPED_SLASHES | \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE, ] ); diff --git a/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php b/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php index cf28658..212e8d1 100644 --- a/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php +++ b/Service/AttributeProcessor/JsonSchemaAttributeProcessor.php @@ -32,11 +32,8 @@ class JsonSchemaAttributeProcessor * @param FileReader $fileReader * @param string $jsonSchemaDir */ - public function __construct( - private readonly DtoAttributeProcessor $dtoAttributeProcessor, - private readonly FileReader $fileReader, - private readonly string $jsonSchemaDir, - ) { + public function __construct(private readonly DtoAttributeProcessor $dtoAttributeProcessor, private readonly FileReader $fileReader, private readonly string $jsonSchemaDir) + { } /** diff --git a/Service/DependentEntity/DependentEntityService.php b/Service/DependentEntity/DependentEntityService.php index e819a6c..ec9a402 100644 --- a/Service/DependentEntity/DependentEntityService.php +++ b/Service/DependentEntity/DependentEntityService.php @@ -28,9 +28,8 @@ class DependentEntityService /** * @param RepositoryService $repositoryService */ - public function __construct( - private readonly RepositoryService $repositoryService, - ) { + public function __construct(private readonly RepositoryService $repositoryService) + { } /** diff --git a/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php b/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php index fa8d97a..fed453a 100644 --- a/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php +++ b/Service/Exception/ResponseProcessor/ExceptionResponseProcessor.php @@ -22,9 +22,8 @@ class ExceptionResponseProcessor implements ExceptionResponseProcessorInterface /** * @param iterable|CustomAppExceptionResponseProcessorInterface[] $errorResponseProcessors */ - public function __construct( - private readonly iterable $errorResponseProcessors, - ) { + public function __construct(private readonly iterable $errorResponseProcessors) + { } /** diff --git a/Validator/Constraints/Entity/EntityExistsValidator.php b/Validator/Constraints/Entity/EntityExistsValidator.php index 11b883b..698d109 100644 --- a/Validator/Constraints/Entity/EntityExistsValidator.php +++ b/Validator/Constraints/Entity/EntityExistsValidator.php @@ -25,9 +25,8 @@ class EntityExistsValidator extends ConstraintValidator /** * @param RepositoryService $repositoryService */ - public function __construct( - private readonly RepositoryService $repositoryService, - ) { + public function __construct(private readonly RepositoryService $repositoryService) + { } /** diff --git a/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php b/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php index 48f127d..b26d2cd 100644 --- a/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php +++ b/Validator/Constraints/Password/PasswordMeetSpecialRequirementsValidator.php @@ -25,9 +25,8 @@ class PasswordMeetSpecialRequirementsValidator extends ConstraintValidator /** * @param PasswordRequirementsValidator $passwordRequirementsValidator */ - public function __construct( - private readonly PasswordRequirementsValidator $passwordRequirementsValidator, - ) { + public function __construct(private readonly PasswordRequirementsValidator $passwordRequirementsValidator) + { } /** diff --git a/Validator/JsonSchemaValidator.php b/Validator/JsonSchemaValidator.php index 4f23aa3..7c1766a 100644 --- a/Validator/JsonSchemaValidator.php +++ b/Validator/JsonSchemaValidator.php @@ -34,10 +34,8 @@ class JsonSchemaValidator * @param Validator $validator * @param JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor */ - public function __construct( - private readonly Validator $validator, - private readonly JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor, - ) { + public function __construct(private readonly Validator $validator, private readonly JsonSchemaAttributeProcessor $jsonSchemaAttributeProcessor) + { } /** From d2a03d16a74615b4e9904046d247eab9c1b1741c Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 30 Apr 2024 16:48:29 +0300 Subject: [PATCH 18/21] Update ci.yaml --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4d50e6a..12cec7c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -149,6 +149,8 @@ jobs: - name: 'Upload to Codecov' uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: files: ./coverage.xml fail_ci_if_error: true From ed7884b93e0061556c57f606db2431ce75d627d7 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 30 Apr 2024 16:59:39 +0300 Subject: [PATCH 19/21] Update ci.yaml --- .github/workflows/ci.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 12cec7c..67d5b14 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -149,9 +149,8 @@ jobs: - name: 'Upload to Codecov' uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: + token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml fail_ci_if_error: true flags: unittests From b0001164e42ae25e2c6c64b6a3fb3b52f9f20160 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 30 Apr 2024 17:01:00 +0300 Subject: [PATCH 20/21] Improve error normalizer (#59) (#60) --- .github/workflows/ci.yaml | 2 ++ .../ConstraintViolationListNormalizer.php | 16 ++++++++++++++ .../ConstraintViolationListNormalizerTest.php | 21 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 67d5b14..04189db 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -149,6 +149,8 @@ jobs: - name: 'Upload to Codecov' uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml diff --git a/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/Serializer/Normalizer/ConstraintViolationListNormalizer.php index f67583a..dd0072b 100644 --- a/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -63,6 +63,8 @@ public function normalize(mixed $object, string $format = null, array $context = { $result = $this->symfonyConstraintViolationListNormalizer->normalize($object, $format, $context); + $this->removeInternalViolationFields($result); + if (\is_array($result) && \array_key_exists('detail', $result) && $result['detail']) { $messages = explode("\n", $result['detail']); @@ -79,4 +81,18 @@ public function normalize(mixed $object, string $format = null, array $context = return $result; } + + /** + * @param array $data + */ + private function removeInternalViolationFields(array &$data): void + { + if (isset($data['violations'])) { + foreach ($data['violations'] as &$violation) { + unset($violation['template'], $violation['parameters']); + $this->removeInternalViolationFields($violation); + } + unset($violation); + } + } } diff --git a/Tests/Serializer/Normalizer/ConstraintViolationListNormalizerTest.php b/Tests/Serializer/Normalizer/ConstraintViolationListNormalizerTest.php index 1c79fc5..f34c77c 100644 --- a/Tests/Serializer/Normalizer/ConstraintViolationListNormalizerTest.php +++ b/Tests/Serializer/Normalizer/ConstraintViolationListNormalizerTest.php @@ -49,13 +49,32 @@ public function testNormalize(string $originDetail, string $resultDetail): void ->expects(self::once()) ->method('normalize') ->with($object, $format, $context) - ->willReturn(['detail' => $originDetail]) + ->willReturn([ + 'detail' => $originDetail, + 'violations' => [ + [ + 'propertyPath' => 'test', + 'title' => 'test', + 'type' => 'test', + 'template' => 'test', + 'parameters' => 'test', + ] + ] + ]) ; $result = (array) $this->normalizer->normalize($object, $format, $context); self::assertArrayHasKey('detail', $result); self::assertSame($resultDetail, $result['detail']); + self::assertSame( + [ + 'propertyPath' => 'test', + 'title' => 'test', + 'type' => 'test', + ], + $result['violations'][0], + ); } public static function dataProviderForTestNormalize(): iterable From 28ba32b0e45b3079ec270625f8100ac082b7ba8f Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Tue, 30 Apr 2024 17:01:23 +0300 Subject: [PATCH 21/21] Update ci.yaml --- .github/workflows/ci.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 04189db..67d5b14 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -149,8 +149,6 @@ jobs: - name: 'Upload to Codecov' uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml