-
-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #417: fix bad public relations hydration on non-pr…
…oxy entity
- Loading branch information
Showing
13 changed files
with
550 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
tests/ORM/Functional/Driver/Common/Integration/Case416/CaseTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416; | ||
|
||
use Cycle\ORM\Select; | ||
use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest; | ||
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\IntegrationTestTrait; | ||
use Cycle\ORM\Tests\Traits\TableTrait; | ||
use Ramsey\Uuid\Uuid; | ||
|
||
abstract class CaseTest extends BaseTest | ||
{ | ||
use IntegrationTestTrait; | ||
use TableTrait; | ||
|
||
public function setUp(): void | ||
{ | ||
// Init DB | ||
parent::setUp(); | ||
$this->makeTables(); | ||
|
||
$this->loadSchema(__DIR__ . '/schema.php'); | ||
} | ||
|
||
public function testSelect(): void | ||
{ | ||
$uuid = Uuid::uuid7(); | ||
$identity = new Entity\Identity($uuid); | ||
$profile = new Entity\Profile($uuid); | ||
$account = new Entity\Account($uuid, 'test@mail.com', \md5('password')); | ||
$identity->profile = $profile; | ||
$identity->account = $account; | ||
|
||
$this->save($identity); | ||
|
||
// Note: heap cleaning fixes this issue | ||
// $this->orm->getHeap()->clean(); | ||
|
||
// Get entity | ||
(new Select($this->orm, Entity\Account::class)) | ||
->load('identity.profile') | ||
->wherePK((string)$uuid) | ||
->fetchOne(); | ||
|
||
// There is no any exception like this: | ||
// [Cycle\ORM\Exception\MapperException] | ||
// Can't hydrate an entity because property and value types are incompatible. | ||
// | ||
// [TypeError] | ||
// Cannot assign Cycle\ORM\Reference\Reference to property | ||
// Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity\Profile::$identity of type | ||
// Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity\Identity | ||
$this->assertTrue(true); | ||
|
||
// To avoid `Entity and State are not in sync` exception | ||
$this->orm->getHeap()->clean(); | ||
} | ||
|
||
private function makeTables(): void | ||
{ | ||
$this->makeTable(Entity\Identity::ROLE, [ | ||
'uuid' => 'string,primary', | ||
'created_at' => 'datetime', | ||
'updated_at' => 'datetime', | ||
'deleted_at' => 'datetime,nullable', | ||
]); | ||
|
||
$this->makeTable(Entity\Account::ROLE, [ | ||
'uuid' => 'string,primary', | ||
'email' => 'string', | ||
'password_hash' => 'string', | ||
'updated_at' => 'datetime', | ||
]); | ||
$this->makeFK( | ||
Entity\Account::ROLE, | ||
'uuid', | ||
Entity\Identity::ROLE, | ||
'uuid', | ||
'NO ACTION', | ||
'NO ACTION', | ||
); | ||
|
||
$this->makeTable(Entity\Profile::ROLE, [ | ||
'uuid' => 'string,primary', | ||
'updated_at' => 'datetime', | ||
'first_name' => 'string', | ||
'last_name' => 'string', | ||
]); | ||
$this->makeFK( | ||
Entity\Profile::ROLE, | ||
'uuid', | ||
Entity\Identity::ROLE, | ||
'uuid', | ||
'NO ACTION', | ||
'NO ACTION', | ||
); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Account.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; | ||
|
||
use DateTimeInterface; | ||
use Ramsey\Uuid\UuidInterface; | ||
|
||
class Account | ||
{ | ||
public const ROLE = 'account'; | ||
|
||
public const F_UUID = 'uuid'; | ||
public const F_EMAIL = 'email'; | ||
public const F_PASSWORD_HASH = 'passwordHash'; | ||
public const F_UPDATED_AT = 'updatedAt'; | ||
|
||
/** @readonly */ | ||
public DateTimeInterface $updatedAt; | ||
|
||
public Identity $identity; | ||
|
||
public function __construct( | ||
/** @readonly */ | ||
public UuidInterface $uuid, | ||
public string $email, | ||
public string $passwordHash, | ||
) { | ||
$this->updatedAt = new \DateTimeImmutable(); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Identity.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; | ||
|
||
use DateTimeInterface; | ||
use Ramsey\Uuid\UuidInterface; | ||
|
||
class Identity | ||
{ | ||
public const ROLE = 'identity'; | ||
|
||
public const F_UUID = 'uuid'; | ||
public const F_CREATED_AT = 'createdAt'; | ||
public const F_UPDATED_AT = 'updatedAt'; | ||
public const F_DELETED_AT = 'deletedAt'; | ||
|
||
/** @readonly */ | ||
public DateTimeInterface $createdAt; | ||
/** @readonly */ | ||
public DateTimeInterface $updatedAt; | ||
/** @readonly */ | ||
public ?DateTimeInterface $deletedAt = null; | ||
|
||
public Profile $profile; | ||
|
||
public Account $account; | ||
|
||
public function __construct( | ||
/** @readonly */ | ||
public UuidInterface $uuid, | ||
) { | ||
$now = new \DateTimeImmutable(); | ||
$this->createdAt = $now; | ||
$this->updatedAt = $now; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Profile.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; | ||
|
||
use DateTimeInterface; | ||
use Ramsey\Uuid\UuidInterface; | ||
|
||
class Profile | ||
{ | ||
public const ROLE = 'profile'; | ||
|
||
public const F_UUID = 'uuid'; | ||
public const F_UPDATED_AT = 'updatedAt'; | ||
|
||
/** @readonly */ | ||
public DateTimeInterface $updatedAt; | ||
|
||
/** @psalm-suppress InvalidArgument */ | ||
public UserName $name; | ||
|
||
public Identity $identity; | ||
|
||
public function __construct( | ||
/** @readonly */ | ||
public UuidInterface $uuid, | ||
) { | ||
$this->name = new UserName(); | ||
$this->updatedAt = new \DateTimeImmutable(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/UserName.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; | ||
|
||
class UserName | ||
{ | ||
public const ROLE = 'UserName'; | ||
|
||
public const F_FIRST_NAME = 'firstName'; | ||
public const F_LAST_NAME = 'lastName'; | ||
|
||
public function __construct( | ||
public string $firstName = '', | ||
public string $lastName = '', | ||
) { | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
tests/ORM/Functional/Driver/Common/Integration/Case416/Typecast/UuidTypecast.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Typecast; | ||
|
||
use Cycle\ORM\Parser\CastableInterface; | ||
use Cycle\ORM\Parser\UncastableInterface; | ||
use Ramsey\Uuid\Uuid; | ||
use Ramsey\Uuid\UuidInterface; | ||
|
||
class UuidTypecast implements CastableInterface, UncastableInterface | ||
{ | ||
/** @var non-empty-string[] */ | ||
private array $rules = []; | ||
|
||
public function setRules(array $rules): array | ||
{ | ||
/** | ||
* @var non-empty-string $key | ||
* @var mixed $rule | ||
*/ | ||
foreach ($rules as $key => $rule) { | ||
if ($rule === 'uuid') { | ||
unset($rules[$key]); | ||
$this->rules[$key] = $rule; | ||
} | ||
} | ||
|
||
return $rules; | ||
} | ||
|
||
public function cast(array $data): array | ||
{ | ||
foreach ($this->rules as $column => $rule) { | ||
if (!isset($data[$column])) { | ||
continue; | ||
} | ||
|
||
\assert(\is_string($data[$column])); | ||
$data[$column] = Uuid::fromString($data[$column]); | ||
} | ||
|
||
return $data; | ||
} | ||
|
||
public function uncast(array $data): array | ||
{ | ||
foreach ($this->rules as $column => $rule) { | ||
if (!isset($data[$column]) || !$data[$column] instanceof UuidInterface) { | ||
continue; | ||
} | ||
|
||
$data[$column] = $data[$column]->toString(); | ||
} | ||
|
||
return $data; | ||
} | ||
} |
Oops, something went wrong.