Chapter5: Adding Tests for Redis thin layer

This commit is contained in:
Carlos Buenosvinos
2022-02-14 17:51:57 +01:00
parent a150f41290
commit 643c6db080
7 changed files with 40 additions and 57 deletions

View File

@@ -10,9 +10,15 @@ use Cheeper\AllChapters\DomainModel\Author\AuthorId;
interface FollowRepository
{
public function numberOfFollowersFor(AuthorId $authorId): int;
public function add(Follow $follow): void;
public function ofFromAuthorIdAndToAuthorId(AuthorId $fromAuthorId, AuthorId $toAuthorId): ?Follow;
/** @return Follow[] */
public function toAuthorId(AuthorId $authorId): array;
/** @return Follow[] */
public function fromAuthorId(AuthorId $authorId): array;
}
//end-snippet

View File

@@ -42,5 +42,12 @@ final class DoctrineOrmFollowRepository implements FollowRepository
->getRepository(Follow::class)
->findBy(['toAuthorId' => $authorId]);
}
public function fromAuthorId(AuthorId $authorId): array
{
return $this->em
->getRepository(Follow::class)
->findBy(['fromAuthorId' => $authorId]);
}
}
//end-snippet

View File

@@ -8,6 +8,7 @@ use Cheeper\AllChapters\DomainModel\Author\AuthorId;
use Cheeper\AllChapters\DomainModel\Follow\FollowId;
use Cheeper\Chapter4\DomainModel\Follow\Follow;
use Cheeper\Chapter4\DomainModel\Follow\FollowRepository;
use Cheeper\Chapter5\DomainModel\Follow\NumberOfFollowers;
use function Functional\head;
use function Functional\reduce_left;
use function Functional\select;
@@ -63,4 +64,9 @@ final class InMemoryFollowRepository implements FollowRepository
{
return select($this->collection, fn (Follow $f): bool => $f->toAuthorId()->equals($authorId));
}
public function fromAuthorId(AuthorId $authorId): array
{
return select($this->collection, fn (Follow $f): bool => $f->fromAuthorId()->equals($authorId));
}
}

View File

@@ -9,7 +9,7 @@ use Cheeper\AllChapters\DomainModel\Author\AuthorId;
use Cheeper\Chapter4\DomainModel\Author\AuthorRepository;
use Cheeper\Chapter5\Application\Author\Query\CountFollowersQueryHandler\CountFollowersQuery;
use Cheeper\Chapter5\Application\Author\Query\CountFollowersQueryHandler\CountFollowersResponse;
use Cheeper\Chapter5\DomainModel\Follow\FollowRepository;
use Cheeper\Chapter4\DomainModel\Follow\FollowRepository;
//snippet count-followers-handler
final class CountFollowersQueryHandler
@@ -29,7 +29,7 @@ final class CountFollowersQueryHandler
throw AuthorDoesNotExist::withAuthorIdOf($authorId);
}
$followersCount = $this->followRepository->ofAuthorId($authorId)?->followers() ?? 0;
$followersCount = count($this->followRepository->toAuthorId($authorId));
// Other option would be with a counter method in the Repository
// $followersCount = $this->followers->countOfAuthorId($authorId));

View File

@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Cheeper\Chapter5\DomainModel\Follow;
use Cheeper\AllChapters\DomainModel\Author\AuthorId;
interface FollowRepository
{
public function ofAuthorId(AuthorId $authorId): ?NumberOfFollowers;
}

View File

@@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace Cheeper\Chapter5\Infrastructure\Persistence;
use Cheeper\AllChapters\DomainModel\Author\AuthorId;
use Cheeper\Chapter5\DomainModel\Follow\FollowRepository;
use Cheeper\Chapter5\DomainModel\Follow\NumberOfFollowers;
use Doctrine\ORM\EntityManagerInterface;
final class DoctrineOrmFollowRepository implements FollowRepository
{
public function __construct(
private EntityManagerInterface $entityManager
) {
}
public function ofAuthorId(AuthorId $authorId): ?NumberOfFollowers
{
return null;
}
}

View File

@@ -13,10 +13,8 @@ use Cheeper\Chapter4\DomainModel\Author\AuthorRepository;
use Cheeper\Chapter5\Application\Author\Query\CountFollowersQueryHandler\CountFollowersResponse;
use Cheeper\Chapter5\Application\Author\Query\CountFollowersQueryHandler\WithRepositoriesAccess\CountFollowersQueryHandler;
use Cheeper\Chapter5\Application\Author\Query\CountFollowersQueryHandler\CountFollowersQuery;
use Cheeper\Chapter5\DomainModel\Follow\FollowRepository;
use Cheeper\Chapter5\DomainModel\Follow\NumberOfFollowers;
use Cheeper\Chapter4\DomainModel\Follow\FollowRepository;
use PHPUnit\Framework\TestCase;
use Ramsey\Uuid\Uuid;
final class CountFollowersQueryHandlerTest extends TestCase
{
@@ -26,14 +24,14 @@ final class CountFollowersQueryHandlerTest extends TestCase
$this->expectException(AuthorDoesNotExist::class);
$this->expectExceptionMessage('Author "3409a21d-83b3-471e-a4f1-cf6748af65d2" does not exist');
$nonExistingAuthorId = '3409a21d-83b3-471e-a4f1-cf6748af65d2';
$authorId = '3409a21d-83b3-471e-a4f1-cf6748af65d2';
$queryHandler = new CountFollowersQueryHandler(
$this->buildFollowRepositoryMockReturning(null),
$this->buildFollowRepositoryMockReturning([]),
$this->buildAuthorRepositoryMockReturning(null)
);
$queryHandler->__invoke(
CountFollowersQuery::ofAuthor($nonExistingAuthorId)
CountFollowersQuery::ofAuthor($authorId)
);
}
@@ -42,20 +40,13 @@ final class CountFollowersQueryHandlerTest extends TestCase
{
$authorId = '3409a21d-83b3-471e-a4f1-cf6748af65d2';
$authorUsername = 'buenosvinos';
$authorEmail = 'carlos.buenosvinos@gmail.com';
$authorFollowers = 0;
$queryHandler = new CountFollowersQueryHandler(
$this->buildFollowRepositoryMockReturning(
new NumberOfFollowers(
Uuid::fromString($authorId),
0
)
),
$this->buildFollowRepositoryMockReturning([]),
$this->buildAuthorRepositoryMockReturning(
Author::signUp(
AuthorId::fromString($authorId),
UserName::pick('buenosvinos'),
EmailAddress::from('carlos.buenosvinos@gmail.com')
)
$this->buildSampleAuthor($authorId, $authorUsername, $authorEmail)
)
);
@@ -72,7 +63,7 @@ final class CountFollowersQueryHandlerTest extends TestCase
$this->assertEquals($expectedReponse, $actualResponse);
}
private function buildAuthorRepositoryMockReturning($fakeReturn) {
private function buildAuthorRepositoryMockReturning(?Author $fakeReturn) {
$mock = $this->createStub(AuthorRepository::class);
$mock->method('ofId')->willReturn(
@@ -82,10 +73,10 @@ final class CountFollowersQueryHandlerTest extends TestCase
return $mock;
}
private function buildFollowRepositoryMockReturning($fakeReturn) {
private function buildFollowRepositoryMockReturning(array $fakeReturn) {
$mock = $this->createStub(FollowRepository::class);
$mock->method('ofAuthorId')->willReturn(
$mock->method('fromAuthorId')->willReturn(
$fakeReturn
);
@@ -93,4 +84,12 @@ final class CountFollowersQueryHandlerTest extends TestCase
}
// @TODO: What happen if the connection is not right?
private function buildSampleAuthor(string $authorId, string $authorUsername, string $authorEmail): Author
{
return Author::signUp(
AuthorId::fromString($authorId),
UserName::pick($authorUsername),
EmailAddress::from($authorEmail)
);
}
}