Skip to content

Commit

Permalink
Fixing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
floriankraemer committed Jul 19, 2024
1 parent 9b5f18d commit 8157c3b
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
/tmp/
/tools/
.idea/
.env
infection.log
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Event Snapshot Store

**⚠ Do not use it in production!⚠ This is still in development!**
# Event Sourcing Snapshot Store

This is a snapshot store for the [Phauthentic event sourcing library](https://github.com/phauthentic/event-sourcing).

Snapshotting is a technique used to reduce the number of events that need to be replayed to reconstitute an aggregate. Snapshots are taken periodically and stored in a snapshot store. When an aggregate is loaded, the snapshot is loaded first and then the events are replayed on top of the snapshot.


## Installation

```sh
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"php": "^8.2"
},
"require-dev": {
"ext-redis": "*",
"phpunit/phpunit": "^10.5",
"predis/predis": "^2.2",
"ramsey/uuid": "^4.7",
Expand All @@ -30,7 +31,8 @@
"config": {
"bin-dir": "bin",
"allow-plugins": {
"infection/extension-installer": true
"infection/extension-installer": true,
"phpro/grumphp": true
}
},
"scripts": {
Expand Down
24 changes: 17 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ version: '3.8'

services:
php:
build: ./docker/php
build:
dockerfile: ./docker/php/Dockerfile
container_name: phpunit-container
volumes:
- .:/app
Expand All @@ -13,15 +14,24 @@ services:
- redis
networks:
- phpnet
environment:
- REDIS_SCHEME=${REDIS_SCHEME}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- DB_HOST=${DB_HOST}
- DB_DATABASE=${DB_DATABASE}
- DB_USER=${DB_USER}
- DB_PASSWORD=$DB_PASSWORD

mysql:
image: mysql:latest
container_name: mysql-container
image: mariadb:latest
container_name: mariadb-container
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: changeme
MARIADB_ROOT_PASSWORD: ${DB_PASSWORD}
MARIADB_DATABASE: ${DB_DATABASE}
MARIADB_ROOT_HOST: '%'
MARIADB_USER: test
MARIADB_PASSWORD: ${DB_PASSWORD}
ports:
- "3306:3306"
networks:
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Snapshot Store Documentation

TBD
Snapshotting is a technique used to reduce the number of events that need to be replayed to reconstitute an aggregate. Snapshots are taken periodically and stored in a snapshot store. When an aggregate is loaded, the snapshot is loaded first and then the events are replayed on top of the snapshot.
3 changes: 2 additions & 1 deletion src/SnapshotFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use DateTimeImmutable;
use Phauthentic\SnapshotStore\Exception\AssertionException;
use Phauthentic\SnapshotStore\Exception\SnapshotStoreException;

/**
* Snapshot Factory
Expand Down Expand Up @@ -38,7 +39,7 @@ protected function assertArrayKeys(array $data): void

/**
* @param array<string, mixed> $data
* @throws \Phauthentic\SnapshotStore\Exception\SnapshotStoreException
* @throws SnapshotStoreException
*/
public function fromArray(array $data): SnapshotInterface
{
Expand Down
2 changes: 1 addition & 1 deletion src/SnapshotFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface SnapshotFactoryInterface
* It's up to the implementation how this is validated.
*
* @param array<string, mixed> $array
* @return \Phauthentic\SnapshotStore\SnapshotInterface
* @return SnapshotInterface
*/
public function fromArray(array $array): SnapshotInterface;
}
2 changes: 1 addition & 1 deletion src/SnapshotTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ protected function assertArrayKeys(array $array): void
continue;
}

throw new AssertionException(sprintf('The array is missing the key %s.', $field));
throw AssertionException::missingArrayKey(sprintf($field));
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/SnapshotTransformerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,15 @@
*/
interface SnapshotTransformerInterface
{
/**
* @param array<string, mixed> $data
* @return SnapshotInterface
*/
public function arrayToSnapshot(array $data): SnapshotInterface;

/**
* @param SnapshotInterface $snapshot
* @return array<string, mixed>
*/
public function snapshotToArray(SnapshotInterface $snapshot): array;
}
4 changes: 2 additions & 2 deletions src/Store/FileSnapshotStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FileSnapshotStore implements SnapshotStoreInterface
/**
* Serializer
*
* @var \Phauthentic\SnapshotStore\Serializer\SerializerInterface
* @var SerializerInterface
*/
protected SerializerInterface $serializer;

Expand All @@ -42,7 +42,7 @@ class FileSnapshotStore implements SnapshotStoreInterface
/**
* Constructor
*
* @param \Phauthentic\SnapshotStore\Serializer\SerializerInterface|null $serializer Serializer
* @param SerializerInterface|null $serializer Serializer
*/
public function __construct(
?SerializerInterface $serializer = null,
Expand Down
14 changes: 9 additions & 5 deletions src/Store/RedisSnapshotStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ class RedisSnapshotStore implements SnapshotStoreInterface
/**
* Serializer
*
* @var \Phauthentic\SnapshotStore\Serializer\SerializerInterface
* @var SerializerInterface
*/
protected SerializerInterface $serializer;

/**
* @var \Redis
* @var Redis
*/

protected Redis $redis;

/**
* Constructor
*
* @param \Redis $redis
* @param \Phauthentic\SnapshotStore\Serializer\SerializerInterface|null $serializer Serializer
* @param Redis $redis
* @param SerializerInterface|null $serializer Serializer
*/
public function __construct(
Redis $redis,
Expand Down Expand Up @@ -80,6 +80,10 @@ public function store(SnapshotInterface $snapshot): void
public function get(string $aggregateId): ?SnapshotInterface
{
$data = $this->redis->get($this->keyPrefix . $aggregateId);
if ($data === false) {
return null;
}

$data = $this->serializer->unserialize((string)$data);

$createdAt = $data[SnapshotInterface::AGGREGATE_CREATED_AT];
Expand All @@ -103,6 +107,6 @@ public function get(string $aggregateId): ?SnapshotInterface
*/
public function delete(string $aggregateId): void
{
$this->redis->del($aggregateId);
$this->redis->del($this->keyPrefix . $aggregateId);
}
}
23 changes: 23 additions & 0 deletions tests/SnapshotFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
use PHPUnit\Framework\TestCase;
use stdClass;

/**
*
*/
class SnapshotFactoryTest extends TestCase
{
protected SnapshotFactoryInterface $snapshotFactory;
Expand Down Expand Up @@ -59,4 +62,24 @@ public function testFromArrayWithMissingKey(): void

$this->snapshotFactory->fromArray($data);
}

public function testToArray(): void
{
$dateTime = new DateTimeImmutable('2022-01-01 12:00:00');
$aggregate = new stdClass();

$data = [
SnapshotInterface::AGGREGATE_TYPE => 'user',
SnapshotInterface::AGGREGATE_ID => '123',
SnapshotInterface::AGGREGATE_ROOT => $aggregate,
SnapshotInterface::AGGREGATE_VERSION => 1,
SnapshotInterface::AGGREGATE_CREATED_AT => $dateTime
];

$snapshot = $this->snapshotFactory->fromArray($data);

$data[SnapshotInterface::AGGREGATE_CREATED_AT] = '2022-01-01 12:00:00';

$this->assertSame($data, $this->snapshotFactory->toArray($snapshot));
}
}
2 changes: 1 addition & 1 deletion tests/SnapshotTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function testArrayToSnapshotMissingKeyThrowsException(): void
];

$this->expectException(SnapshotStoreException::class);
$this->expectExceptionMessage('The array is missing the key created_at.');
$this->expectExceptionMessage('The array is missing the `created_at` key');

$this->transformer->arrayToSnapshot($data);
}
Expand Down
5 changes: 4 additions & 1 deletion tests/Store/FileStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class FileStoreTest extends AbstractStoreTestCase
{
protected function createSnapshotStore(): SnapshotStoreInterface
{
return new FileSnapshotStore(new SerializeSerializer());
return new FileSnapshotStore(
new SerializeSerializer(),
sys_get_temp_dir() . DIRECTORY_SEPARATOR
);
}
}
4 changes: 2 additions & 2 deletions tests/Store/PdoSqlStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ protected function getPdo(): PDO
$host = getenv('DB_HOST') ?: '127.0.0.1';
$dbname = getenv('DB_DATABASE') ?: 'test';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASSWORD') ?: 'changeme';
$password = getenv('DB_PASSWORD') ?: 'changeme';

$pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $password);

// Set PDO attributes for error handling and fetch mode
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Expand Down

0 comments on commit 8157c3b

Please sign in to comment.