Files
Lesstime/tests/Unit/Shared/Doctrine/TimestampableBlamableSubscriberTest.php
T

92 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Unit\Shared\Doctrine;
use App\Shared\Application\CurrentUserProviderInterface;
use App\Shared\Domain\Contract\BlamableInterface;
use App\Shared\Domain\Contract\TimestampableInterface;
use App\Shared\Domain\Contract\UserInterface;
use App\Shared\Domain\Trait\TimestampableBlamableTrait;
use App\Shared\Infrastructure\Doctrine\TimestampableBlamableSubscriber;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
use stdClass;
/**
* @internal
*/
final class TimestampableBlamableSubscriberTest extends TestCase
{
public function testApplyOnCreateSetsTimestampsAndAuthor(): void
{
$user = $this->makeUser(7);
$subscriber = new TimestampableBlamableSubscriber($this->providerReturning($user));
$entity = $this->makeEntity();
$subscriber->applyOnCreate($entity);
self::assertInstanceOf(DateTimeImmutable::class, $entity->getCreatedAt());
self::assertInstanceOf(DateTimeImmutable::class, $entity->getUpdatedAt());
self::assertSame($user, $entity->getCreatedBy());
self::assertSame($user, $entity->getUpdatedBy());
}
public function testApplyOnUpdateLeavesCreatedUntouched(): void
{
$creator = $this->makeUser(1);
$editor = $this->makeUser(2);
$entity = $this->makeEntity();
new TimestampableBlamableSubscriber($this->providerReturning($creator))->applyOnCreate($entity);
$createdAt = $entity->getCreatedAt();
new TimestampableBlamableSubscriber($this->providerReturning($editor))->applyOnUpdate($entity);
self::assertSame($createdAt, $entity->getCreatedAt());
self::assertSame($creator, $entity->getCreatedBy());
self::assertSame($editor, $entity->getUpdatedBy());
}
public function testApplyOnCreateIgnoresNonTimestampableEntities(): void
{
$subscriber = new TimestampableBlamableSubscriber($this->providerReturning(null));
// Must not throw.
$subscriber->applyOnCreate(new stdClass());
$this->addToAssertionCount(1);
}
private function providerReturning(?UserInterface $user): CurrentUserProviderInterface
{
return new class($user) implements CurrentUserProviderInterface {
public function __construct(private ?UserInterface $user) {}
public function getCurrentUser(): ?UserInterface
{
return $this->user;
}
};
}
private function makeUser(int $id): UserInterface
{
return new class($id) implements UserInterface {
public function __construct(private int $id) {}
public function getId(): ?int
{
return $this->id;
}
};
}
private function makeEntity(): object
{
return new class implements TimestampableInterface, BlamableInterface {
use TimestampableBlamableTrait;
};
}
}