Add some mocking and testing for the repository class, break out the database handler

This commit is contained in:
Dave Smith-Hayes 2024-11-16 22:54:26 -05:00
parent 037ec4eee9
commit 811912784b
4 changed files with 85 additions and 10 deletions

View File

@ -11,6 +11,9 @@ use Slovocast\Infrastructure\Api\Database\DatabaseHandlerInterface;
class UserRepository implements UserRepositoryInterface class UserRepository implements UserRepositoryInterface
{ {
const INSERT_QUERY = "INSERT INTO users (email, password, name)
VALUES (:email, :password, :name)";
public function __construct( public function __construct(
private DatabaseHandlerInterface $db, private DatabaseHandlerInterface $db,
private UserAuthorizationInterface $userAuth private UserAuthorizationInterface $userAuth
@ -56,9 +59,7 @@ class UserRepository implements UserRepositoryInterface
public function getFromEmail(string $email): User public function getFromEmail(string $email): User
{ {
$query = "SELECT * FROM users WHERE email = :email LIMIT 1"; $query = "SELECT * FROM users WHERE email = :email LIMIT 1";
$statement = $this->db->getConnection()->prepare($query); $results = $this->db->query($query, [ ':email' => $email ]);
$statement->execute([ ':email' => $email ]);
$results = $statement->fetch(\PDO::FETCH_ASSOC);
if (!is_array($results) || count($results)) { if (!is_array($results) || count($results)) {
throw new EntityNotFoundException("Unable to find User"); throw new EntityNotFoundException("Unable to find User");
@ -69,11 +70,7 @@ class UserRepository implements UserRepositoryInterface
public function create(User $user): bool public function create(User $user): bool
{ {
$query = "INSERT INTO users (email, password, name) $results = $this->db->insert(self::INSERT_QUERY, [
VALUES (:email, :password, :name)";
$statement = $this->db->getConnection()->prepare($query);
$results = $statement->execute([
':email' => $user->getEmail(), ':email' => $user->getEmail(),
':password' => $this->userAuth->hash($user->getPassword()), ':password' => $this->userAuth->hash($user->getPassword()),
':name' => $user->getName(), ':name' => $user->getName(),
@ -97,8 +94,7 @@ class UserRepository implements UserRepositoryInterface
password = :password password = :password
WHERE id = :id"; WHERE id = :id";
$statement = this->db->prepare($query); $results = $this->db->query($query, [
$results = $statement->execute([
$user->getEmail(), $user->getEmail(),
$user->getName(), $user->getName(),
$this->userAuth->hash($user->getPassword()), $this->userAuth->hash($user->getPassword()),

View File

@ -7,5 +7,24 @@ use PDO;
interface DatabaseHandlerInterface interface DatabaseHandlerInterface
{ {
public function getConnection(): PDO; public function getConnection(): PDO;
/**
* Get the connection string required for establishing connections to the
* database
*/
public function getDsn(): string; public function getDsn(): string;
/**
* @param string $query
* @param array $params Either a list of params of the KV params
* @return array The results as an array, empty if no results
*/
public function query(string $query, array $params = []): array;
/**
* @param string $query
* @param array $params Either a list of params, or the KV of params
* @return bool True if successful
*/
public function insert(string $query, array $params = []): bool;
} }

View File

@ -38,4 +38,17 @@ class DatabaseHandler implements DatabaseHandlerInterface
{ {
return $this->database; return $this->database;
} }
public function query(string $query, array $params = []): array
{
$statement = $this->database->prepare($query);
$statement->execute($params);
return $statement->fetchAll($params);
}
public function insert(string $query, array $params = []): bool
{
$statement = $this->database->prepare($query);
return $statement->execute($params);
}
} }

View File

@ -0,0 +1,47 @@
<?php
namespace Slovocast\Tests\Domain\Repository;
use Slovocast\Domain\Repository\User\UserRepository;
use Slovocast\Domain\Entity\User;
use Slovocast\Infrastructure\Api\Database\DatabaseHandlerInterface;
use Slovocast\Infrastructure\User\BasicUserAuthorization;
use Slovocast\Tests\TestCase;
class UserRepositoryTest extends TestCase
{
protected function getUser(): User
{
return User::fromArray([
'email' => 'dave@slovocast.com',
'name' => 'Dave SH',
'password' => 'hashed_password'
]);
}
public function testRegisteringAUser(): void
{
$user = $this->getUser();
$databaseHandler = $this->prophesize(DatabaseHandlerInterface::class);
$databaseHandler->getConnection()->willReturn(new class {
public function lastInsertId(): int
{
return 100;
}
});
$databaseHandler->insert(UserRepository::INSERT_QUERY, [
':name' => $user->getName(),
':email' => $user->getEmail(),
':password' => $user->getPassword()
])->willReturn(true);
$userRepository = new UserRepository(
$databaseHandler->reveal(),
new BasicUserAuthorization()
);
$results = $userRepository->create($user);
$this->assertTrue($results);
$this->assertEquals(100, $user->getId());
}
}