Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Feb 19, 2024
1 parent 76c5c89 commit 2c4b5be
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 0 deletions.
94 changes: 94 additions & 0 deletions tests/Unit/Projection/Projection/Store/InMemoryStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace Patchlevel\EventSourcing\Tests\Unit\Projection\Projection\Store;

use Patchlevel\EventSourcing\Projection\Projection\Projection;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionAlreadyExists;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionCriteria;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionNotFound;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionStatus;
use Patchlevel\EventSourcing\Projection\Projection\Store\InMemoryStore;
use PHPUnit\Framework\TestCase;

Expand All @@ -25,6 +28,17 @@ public function testAdd(): void
self::assertEquals([$projection], $store->find());
}

public function testAddDuplicated(): void
{
$this->expectException(ProjectionAlreadyExists::class);

$id = 'test';
$projection = new Projection($id);

$store = new InMemoryStore([$projection]);
$store->add($projection);
}

public function testUpdate(): void
{
$id = 'test';
Expand All @@ -38,6 +52,18 @@ public function testUpdate(): void
self::assertEquals([$projection], $store->find());
}

public function testUpdateNotFound(): void
{
$this->expectException(ProjectionNotFound::class);

$id = 'test';
$projection = new Projection($id);

$store = new InMemoryStore();

$store->update($projection);
}

public function testNotFound(): void
{
$this->expectException(ProjectionNotFound::class);
Expand All @@ -57,4 +83,72 @@ public function testRemove(): void

self::assertEquals([], $store->find());
}

public function testFind(): void
{
$projection1 = new Projection('1');
$projection2 = new Projection('2');

$store = new InMemoryStore([$projection1, $projection2]);

self::assertEquals([$projection1, $projection2], $store->find());
}

public function testFindById(): void
{
$projection1 = new Projection('1');
$projection2 = new Projection('2');

$store = new InMemoryStore([$projection1, $projection2]);

$criteria = new ProjectionCriteria(
ids: ['1'],
);

self::assertEquals([$projection1], $store->find($criteria));
}

public function testFindByGroup(): void
{
$projection1 = new Projection('1', group: 'group1');
$projection2 = new Projection('2', group: 'group2');

$store = new InMemoryStore([$projection1, $projection2]);

$criteria = new ProjectionCriteria(
groups: ['group1'],
);

self::assertEquals([$projection1], $store->find($criteria));
}

public function testFindByStatus(): void
{
$projection1 = new Projection('1', status: ProjectionStatus::New);
$projection2 = new Projection('2', status: ProjectionStatus::Booting);

$store = new InMemoryStore([$projection1, $projection2]);

$criteria = new ProjectionCriteria(
status: [ProjectionStatus::New],
);

self::assertEquals([$projection1], $store->find($criteria));
}

public function testFindByAll(): void
{
$projection1 = new Projection('1', group: 'group1', status: ProjectionStatus::New);
$projection2 = new Projection('2', group: 'group2', status: ProjectionStatus::Booting);

$store = new InMemoryStore([$projection1, $projection2]);

$criteria = new ProjectionCriteria(
ids: ['1'],
groups: ['group1'],
status: [ProjectionStatus::New],
);

self::assertEquals([$projection1], $store->find($criteria));
}
}
114 changes: 114 additions & 0 deletions tests/Unit/Projection/Projectionist/DefaultProjectionistTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@

namespace Patchlevel\EventSourcing\Tests\Unit\Projection\Projectionist;

use Closure;
use Generator;
use Patchlevel\EventSourcing\Attribute\Projector as ProjectionAttribute;
use Patchlevel\EventSourcing\Attribute\Setup;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Attribute\Teardown;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Projection\Projection\Projection;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionCriteria;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionError;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionStatus;
use Patchlevel\EventSourcing\Projection\Projection\Store\ErrorContext;
use Patchlevel\EventSourcing\Projection\Projection\Store\LockableProjectionStore;
use Patchlevel\EventSourcing\Projection\Projection\Store\ProjectionStore;
use Patchlevel\EventSourcing\Projection\Projectionist\DefaultProjectionist;
use Patchlevel\EventSourcing\Projection\Projectionist\ProjectionistCriteria;
use Patchlevel\EventSourcing\Store\ArrayStream;
Expand All @@ -21,7 +26,9 @@
use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileId;
use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileVisited;
use Patchlevel\EventSourcing\Tests\Unit\Projection\DummyStore;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use RuntimeException;

Expand Down Expand Up @@ -688,6 +695,31 @@ class {
], $projectionStore->addedProjections);
}

public function testTeardownWithoutTeardownMethod(): void
{
$projectionId = 'test';
$projector = new #[ProjectionAttribute('test')]
class {
};

$projection = new Projection($projectionId, Projection::DEFAULT_GROUP, ProjectionStatus::Outdated);

$projectionStore = new DummyStore([$projection]);

$streamableStore = $this->prophesize(Store::class);

$projectionist = new DefaultProjectionist(
$streamableStore->reveal(),
$projectionStore,
[$projector],
);

$projectionist->teardown();

self::assertEquals([], $projectionStore->updatedProjections);
self::assertEquals([$projection], $projectionStore->removedProjections);
}

public function testTeardownWithProjector(): void
{
$projectionId = 'test';
Expand Down Expand Up @@ -978,6 +1010,88 @@ class {
], $projections);
}

#[DataProvider('methodProvider')]
public function testCriteria(string $method): void
{
$projector = new #[ProjectionAttribute('id1')]
class {
};

$projectionStore = $this->prophesize(ProjectionStore::class);
$projectionStore->find(
Argument::that(
static fn (ProjectionCriteria $criteria) => $criteria->ids === ['id1'] && $criteria->groups === ['group1']
),
)->willReturn([])->shouldBeCalled();

$projectionStore->find(
new ProjectionCriteria(),
)->willReturn([
new Projection('id1'),
])->shouldBeCalled();

$streamableStore = $this->prophesize(Store::class);
$streamableStore->load($this->criteria())->willReturn(new ArrayStream([]));

$projectionist = new DefaultProjectionist(
$streamableStore->reveal(),
$projectionStore->reveal(),
[$projector],
);

$projectionistCriteria = new ProjectionistCriteria(
ids: ['id1'],
groups: ['group1'],
);

$projectionist->{$method}($projectionistCriteria);
}

#[DataProvider('methodProvider')]
public function testWithLockableStore(string $method): void
{
$projector = new #[ProjectionAttribute('id1')]
class {
};

$projectionStore = $this->prophesize(LockableProjectionStore::class);
$projectionStore->inLock(Argument::type(Closure::class))->will(
/** @param array{Closure} $args */
static fn (array $args): mixed => $args[0]()
)->shouldBeCalled();
$projectionStore->find(Argument::any())->willReturn([])->shouldBeCalled();

$projectionStore->find(
new ProjectionCriteria(),
)->willReturn([
new Projection('id1'),
])->shouldBeCalled();

$projectionStore->remove(Argument::type(Projection::class));
$projectionStore->add(Argument::type(Projection::class));

$streamableStore = $this->prophesize(Store::class);
$streamableStore->load($this->criteria())->willReturn(new ArrayStream([]));

$projectionist = new DefaultProjectionist(
$streamableStore->reveal(),
$projectionStore->reveal(),
[$projector],
);

$projectionist->{$method}();
}

public static function methodProvider(): Generator
{
yield 'boot' => ['boot'];
yield 'run' => ['run'];
yield 'teardown' => ['teardown'];
yield 'remove' => ['remove'];
yield 'reactivate' => ['reactivate'];
yield 'projections' => ['projections'];
}

private function criteria(int $fromIndex = 0): Criteria
{
return new Criteria(fromIndex: $fromIndex);
Expand Down

0 comments on commit 2c4b5be

Please sign in to comment.