diff --git a/src/Matiux/DDDStarterPack/Aggregate/Domain/BasicEntityId.php b/src/Matiux/DDDStarterPack/Aggregate/Domain/BasicEntityId.php index d2df9c2..945cc41 100644 --- a/src/Matiux/DDDStarterPack/Aggregate/Domain/BasicEntityId.php +++ b/src/Matiux/DDDStarterPack/Aggregate/Domain/BasicEntityId.php @@ -4,55 +4,18 @@ namespace DDDStarterPack\Aggregate\Domain; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Uuid; - -class BasicEntityId implements EntityId +/** + * @template T + * @implements EntityId + */ +abstract class BasicEntityId implements EntityId { - public const UUID_PATTERN = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; - - final protected function __construct( - private null|int|string $id - ) { - } - - public function __toString(): string - { - return !$this->id ? '' : (string) $this->id; - } - /** - * @throws Exception - * - * @return static + * @param T $id */ - public static function create(): static - { - return new static(Uuid::uuid4()->toString()); - } - - public static function createFrom(int|string $id): static - { - if (!$id) { - throw new InvalidArgumentException(sprintf('Invalid ID: %s', $id)); - } - - return new static($id); - } - - public static function createNUll(): static - { - return new static(null); - } - - public static function isValidUuid(string $uuid): bool - { - if (1 === preg_match(self::UUID_PATTERN, $uuid)) { - return true; - } - - return false; + final protected function __construct( + protected $id + ) { } public function equals(EntityId $entityId): bool @@ -60,13 +23,11 @@ public function equals(EntityId $entityId): bool return $this->id() === $entityId->id(); } - public function id(): null|int|string + /** + * @return T + */ + public function id() { return $this->id; } - - public function isNull(): bool - { - return is_null($this->id); - } } diff --git a/src/Matiux/DDDStarterPack/Aggregate/Domain/EntityId.php b/src/Matiux/DDDStarterPack/Aggregate/Domain/EntityId.php index 9a41a60..227895e 100644 --- a/src/Matiux/DDDStarterPack/Aggregate/Domain/EntityId.php +++ b/src/Matiux/DDDStarterPack/Aggregate/Domain/EntityId.php @@ -4,17 +4,26 @@ namespace DDDStarterPack\Aggregate\Domain; +/** + * @template I of mixed + */ interface EntityId { - public function __toString(): string; - public static function create(): static; - public static function createFrom(int|string $id): static; - - public static function createNull(): static; - - public function id(): null|int|string; + /** + * @template T of I + * + * @param T $id + * + * @return static + */ + public static function createFrom($id): static; + + /** + * @return I + */ + public function id(); public function equals(EntityId $entityId): bool; } diff --git a/src/Matiux/DDDStarterPack/Aggregate/Domain/UuidEntityId.php b/src/Matiux/DDDStarterPack/Aggregate/Domain/UuidEntityId.php new file mode 100644 index 0000000..a9b266b --- /dev/null +++ b/src/Matiux/DDDStarterPack/Aggregate/Domain/UuidEntityId.php @@ -0,0 +1,55 @@ + + */ +class UuidEntityId extends BasicEntityId +{ + public const UUID_PATTERN = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; + + public function __toString(): string + { + return !$this->id ? '' : $this->id; + } + + /** + * @throws Exception + * + * @return static + */ + public static function create(): static + { + return new static(Uuid::uuid4()->toString()); + } + + /** + * @param string $id + * + * @return static + */ + public static function createFrom($id): static + { + if (!$id || !self::isValidUuid($id)) { + throw new InvalidArgumentException(sprintf('Invalid ID: %s', $id)); + } + + return new static($id); + } + + public static function isValidUuid(string $uuid): bool + { + if (1 === preg_match(self::UUID_PATTERN, $uuid)) { + return true; + } + + return false; + } +} diff --git a/src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityId.php b/src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineUuidEntityId.php similarity index 70% rename from src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityId.php rename to src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineUuidEntityId.php index dc6fcbd..7868213 100644 --- a/src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityId.php +++ b/src/Matiux/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineUuidEntityId.php @@ -4,16 +4,16 @@ namespace DDDStarterPack\Aggregate\Infrastructure\Doctrine; -use DDDStarterPack\Aggregate\Domain\BasicEntityId; use DDDStarterPack\Aggregate\Domain\EntityId; +use DDDStarterPack\Aggregate\Domain\UuidEntityId; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\GuidType; -abstract class DoctrineEntityId extends GuidType +abstract class DoctrineUuidEntityId extends GuidType { public function convertToDatabaseValue($value, AbstractPlatform $platform) { - return $value instanceof EntityId ? $value->id() : $value ?? null; + return $value instanceof UuidEntityId ? $value->id() : $value ?? null; } public function convertToPHPValue($value, AbstractPlatform $platform) @@ -35,25 +35,24 @@ public function convertToPHPValue($value, AbstractPlatform $platform) /** * @param mixed $value * - * @return null|int|string + * @return null|string */ - private function prepareValue(mixed $value): null|int|string + private function prepareValue(mixed $value): null|string { return match (true) { is_object($value), is_null($value) => null, - is_int($value) => $value, default => (string) $value }; } /** - * @param int|string $value + * @param string $value * * @return bool */ - private function isValidUuid(int|string $value): bool + private function isValidUuid(string $value): bool { - return is_string($value) && BasicEntityId::isValidUuid($value); + return UuidEntityId::isValidUuid($value); } protected function isCustomValid(): bool diff --git a/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/AWS/SQS/SQSMessageConsumer.php b/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/AWS/SQS/SQSMessageConsumer.php index f55d2e2..c4cfab9 100644 --- a/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/AWS/SQS/SQSMessageConsumer.php +++ b/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/AWS/SQS/SQSMessageConsumer.php @@ -28,10 +28,10 @@ class SQSMessageConsumer extends BasicMessageService implements MessageConsumerC public const NAME = 'SQS'; /** @var string[] */ - private array $attributeNames = ['All']; //'ApproximateReceiveCount' + private array $attributeNames = ['All']; // 'ApproximateReceiveCount' /** @var string[] */ - private array $messageAttributeNames = ['All']; //'Type', 'OccurredAt' + private array $messageAttributeNames = ['All']; // 'Type', 'OccurredAt' public function __construct( private AWSMessageFactory $AWSMessageFactory diff --git a/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/RabbitMQ/RabbitMQMessageConsumer.php b/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/RabbitMQ/RabbitMQMessageConsumer.php index 162f1c5..a5723f2 100644 --- a/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/RabbitMQ/RabbitMQMessageConsumer.php +++ b/src/Matiux/DDDStarterPack/Message/Infrastructure/Driver/RabbitMQ/RabbitMQMessageConsumer.php @@ -37,7 +37,7 @@ public function consume(null|string $queue = null): null|Message * Inviando la conferma il messaggio verrĂ  definitivamente cancellato dalla coda. No conferma = no cancellazione dalla coda e reinvio * a un nuovo worker. */ - //$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); + // $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); }; $this->channel->basic_qos(null, 1, null); @@ -50,7 +50,7 @@ public function consume(null|string $queue = null): null|Message while (count($this->channel->callbacks)) { if ($body) { return $this->messageFactory->build($body, '', $deliveryTag, '', null, null); - //return new ArrayObject(['Body' => $body, 'ReceiptHandle' => $deliveryTag]); + // return new ArrayObject(['Body' => $body, 'ReceiptHandle' => $deliveryTag]); } try { diff --git a/tests/Support/Model/Doctrine/DoctrinePersonId.php b/tests/Support/Model/Doctrine/DoctrineUuidPersonId.php similarity index 67% rename from tests/Support/Model/Doctrine/DoctrinePersonId.php rename to tests/Support/Model/Doctrine/DoctrineUuidPersonId.php index 1681d2c..dbd0824 100644 --- a/tests/Support/Model/Doctrine/DoctrinePersonId.php +++ b/tests/Support/Model/Doctrine/DoctrineUuidPersonId.php @@ -4,10 +4,10 @@ namespace Tests\Support\Model\Doctrine; -use DDDStarterPack\Aggregate\Infrastructure\Doctrine\DoctrineEntityId; +use DDDStarterPack\Aggregate\Infrastructure\Doctrine\DoctrineUuidEntityId; use Tests\Support\Model\PersonId; -class DoctrinePersonId extends DoctrineEntityId +class DoctrineUuidPersonId extends DoctrineUuidEntityId { public function getName() { diff --git a/tests/Support/Model/PersonId.php b/tests/Support/Model/PersonId.php index 8e913d5..21d0dee 100644 --- a/tests/Support/Model/PersonId.php +++ b/tests/Support/Model/PersonId.php @@ -4,8 +4,8 @@ namespace Tests\Support\Model; -use DDDStarterPack\Aggregate\Domain\BasicEntityId; +use DDDStarterPack\Aggregate\Domain\UuidEntityId; -class PersonId extends BasicEntityId +class PersonId extends UuidEntityId { } diff --git a/tests/Tool/EntityManagerBuilder.php b/tests/Tool/EntityManagerBuilder.php index 64c101b..eb4b74a 100644 --- a/tests/Tool/EntityManagerBuilder.php +++ b/tests/Tool/EntityManagerBuilder.php @@ -13,7 +13,7 @@ use Doctrine\Persistence\ObjectRepository; use InvalidArgumentException; use Nyholm\Dsn\DsnParser; -use Tests\Support\Model\Doctrine\DoctrinePersonId; +use Tests\Support\Model\Doctrine\DoctrineUuidPersonId; class EntityManagerBuilder { @@ -68,7 +68,7 @@ public static function create(bool $isDevMode = false): self $builder = new self($isDevMode); if (!Type::hasType('PersonId')) { - Type::addType('PersonId', DoctrinePersonId::class); + Type::addType('PersonId', DoctrineUuidPersonId::class); } $builder->ems['default'] = EntityManager::create($builder->connectionParams, $builder->config); diff --git a/tests/Unit/DDDStarterPack/Aggregate/Domain/BasicEntityIdTest.php b/tests/Unit/DDDStarterPack/Aggregate/Domain/BasicEntityIdTest.php deleted file mode 100644 index e074c0b..0000000 --- a/tests/Unit/DDDStarterPack/Aggregate/Domain/BasicEntityIdTest.php +++ /dev/null @@ -1,89 +0,0 @@ -id = $id; - } - - public function id(): BasicEntityId - { - return $this->id; - } - }; - - self::assertInstanceOf(BasicEntityId::class, $entity->id()); - self::assertMatchesRegularExpression(BasicEntityId::UUID_PATTERN, (string) $entity->id()); - } - - /** - * @test - */ - public function create_specific_uuid(): void - { - $myId = BasicEntityId::createFrom('79fe4c6b-87f6-4093-98f9-ce6a193ab2a5'); - - self::assertEquals('79fe4c6b-87f6-4093-98f9-ce6a193ab2a5', $myId->id()); - self::assertIsString($myId->id()); - } - - /** - * @test - */ - public function create_numeric_id(): void - { - $myId = BasicEntityId::createFrom(5); - - self::assertEquals(5, $myId->id()); - self::assertIsInt($myId->id()); - } - - /** - * @test - */ - public function create_null_id(): void - { - $myId = BasicEntityId::createNull(); - - self::assertTrue($myId->isNull()); - self::assertNull($myId->id()); - } - - /** - * @test - */ - public function it_should_throw_exception_if_input_id_is_invalid(): void - { - self::expectException(InvalidArgumentException::class); - - BasicEntityId::createFrom(''); - } - - /** - * @test - */ - public function is_should_verify_if_id_is_in_uuid_v4_format(): void - { - self::assertTrue(BasicEntityId::isValidUuid('79fe4c6b-87f6-4093-98f9-ce6a193ab2a5')); - self::assertFalse(BasicEntityId::isValidUuid('12345')); - } -} diff --git a/tests/Unit/DDDStarterPack/Aggregate/Domain/Repository/IdentifiableRepositoryTest.php b/tests/Unit/DDDStarterPack/Aggregate/Domain/Repository/IdentifiableRepositoryTest.php index ba343d7..1be37e1 100644 --- a/tests/Unit/DDDStarterPack/Aggregate/Domain/Repository/IdentifiableRepositoryTest.php +++ b/tests/Unit/DDDStarterPack/Aggregate/Domain/Repository/IdentifiableRepositoryTest.php @@ -5,6 +5,7 @@ namespace Tests\Unit\DDDStarterPack\Aggregate\Domain\Repository; use DDDStarterPack\Aggregate\Domain\Repository\IdentifiableRepository; +use DDDStarterPack\Aggregate\Domain\UuidEntityId; use PHPUnit\Framework\TestCase; use Tests\Support\Model\Person; use Tests\Support\Model\PersonId; @@ -21,15 +22,15 @@ public function find_person_by_id(): void $repo = new InMemoryRepository($personId); // Psalm gets angry - as it should be - //$repo->ofId(35); - //$repo->ofId(null); + // $repo->ofId(35); + // $repo->ofId(null); $person = $repo->ofId($personId); self::assertNotNull($person); $personId = $repo->nextIdentity(); - self::assertFalse($personId->isNull()); + self::assertTrue(UuidEntityId::isValidUuid($personId->id())); } } diff --git a/tests/Unit/DDDStarterPack/Aggregate/Domain/UuidEntityIdTest.php b/tests/Unit/DDDStarterPack/Aggregate/Domain/UuidEntityIdTest.php new file mode 100644 index 0000000..af95d7d --- /dev/null +++ b/tests/Unit/DDDStarterPack/Aggregate/Domain/UuidEntityIdTest.php @@ -0,0 +1,61 @@ +id()); + self::assertIsString($myId->id()); + } + +// /** +// * @test +// */ +// public function create_numeric_id(): void +// { +// $myId = UuidEntityId::createFrom(5); +// +// self::assertEquals(5, $myId->id()); +// self::assertIsInt($myId->id()); +// } + + /** + * @test + */ + public function it_should_throw_exception_if_input_id_is_invalid(): void + { + self::expectException(InvalidArgumentException::class); + + UuidEntityId::createFrom(''); + } + + /** + * @test + */ + public function is_should_verify_if_id_is_in_uuid_v4_format(): void + { + self::assertTrue(UuidEntityId::isValidUuid('79fe4c6b-87f6-4093-98f9-ce6a193ab2a5')); + self::assertFalse(UuidEntityId::isValidUuid('12345')); + } +} diff --git a/tests/Unit/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityIdTest.php b/tests/Unit/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityIdTest.php index bc5864b..32cb4a3 100644 --- a/tests/Unit/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityIdTest.php +++ b/tests/Unit/DDDStarterPack/Aggregate/Infrastructure/Doctrine/DoctrineEntityIdTest.php @@ -4,7 +4,7 @@ namespace Tests\Unit\DDDStarterPack\Aggregate\Infrastructure\Doctrine; -use DDDStarterPack\Aggregate\Infrastructure\Doctrine\DoctrineEntityId; +use DDDStarterPack\Aggregate\Infrastructure\Doctrine\DoctrineUuidEntityId; use Doctrine\DBAL\Platforms\AbstractPlatform; use Mockery; use PHPUnit\Framework\TestCase; @@ -17,8 +17,8 @@ class DoctrineEntityIdTest extends TestCase */ public function php_value_should_be_same_of_input_if_database_value_is_not_valid_uuid_or_custom_valid(): void { - MyId::addType('MyId', MyId::class); - $id = MyId::getType('MyId'); + MyIdUuid::addType('MyId', MyIdUuid::class); + $id = MyIdUuid::getType('MyId'); $phpValue = $id->convertToPHPValue('foo_id', Mockery::mock(AbstractPlatform::class)); @@ -26,7 +26,7 @@ public function php_value_should_be_same_of_input_if_database_value_is_not_valid } } -class MyId extends DoctrineEntityId +class MyIdUuid extends DoctrineUuidEntityId { protected function getFQCN(): string { diff --git a/tests/Unit/DDDStarterPack/Service/Domain/BasicServiceResponseTest.php b/tests/Unit/DDDStarterPack/Service/Domain/BasicServiceResponseTest.php index c420411..0a893e4 100644 --- a/tests/Unit/DDDStarterPack/Service/Domain/BasicServiceResponseTest.php +++ b/tests/Unit/DDDStarterPack/Service/Domain/BasicServiceResponseTest.php @@ -14,7 +14,7 @@ class BasicServiceResponseTest extends TestCase */ public function create_error_response(): void { - //$response = ServiceResponse::error('Error message'); // Psalm si arrabbia, giustamente + // $response = ServiceResponse::error('Error message'); // Psalm si arrabbia, giustamente $response = ServiceResponse::error(['status' => 'Error message']); self::assertSame(['status' => 'Error message'], $response->body()); diff --git a/tests/Unit/DDDStarterPack/Service/Domain/CommandServiceTest.php b/tests/Unit/DDDStarterPack/Service/Domain/CommandServiceTest.php index 7c61fbd..315bd04 100644 --- a/tests/Unit/DDDStarterPack/Service/Domain/CommandServiceTest.php +++ b/tests/Unit/DDDStarterPack/Service/Domain/CommandServiceTest.php @@ -21,9 +21,9 @@ public function service_requires_a_domain_command(): void $service = new MyCommandService($store); // Psalm gets angry - as it should be - //$service->execute(); - //$service->execute(2); - //$service->execute([]); + // $service->execute(); + // $service->execute(2); + // $service->execute([]); $service->execute(new MyCommand()); diff --git a/tests/Unit/DDDStarterPack/Service/Domain/NoRequestServiceTest.php b/tests/Unit/DDDStarterPack/Service/Domain/NoRequestServiceTest.php index 00809e7..584376f 100644 --- a/tests/Unit/DDDStarterPack/Service/Domain/NoRequestServiceTest.php +++ b/tests/Unit/DDDStarterPack/Service/Domain/NoRequestServiceTest.php @@ -17,8 +17,8 @@ public function use_service(): void $service = new MyNoRequestService(); // Psalm gets angry - as it should be - //$service->execute(new \stdClass()); - //$service->execute('Foo'); + // $service->execute(new \stdClass()); + // $service->execute('Foo'); $result = $service->execute();