Skip to content

Commit

Permalink
Merge pull request #110 from buggregator/feauture/107
Browse files Browse the repository at this point in the history
Adds an ability to remove events by uuids
  • Loading branch information
butschster committed Dec 4, 2023
2 parents 6e291e3 + 351e2eb commit 462101b
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 16 deletions.
11 changes: 10 additions & 1 deletion app/modules/Events/Interfaces/Commands/ClearEventsHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ public function __construct(
#[CommandHandler]
public function __invoke(ClearEvents $command): void
{
$this->events->deleteAll($command->type ? ['type' => $command->type] : []);
$args = [];
if ($command->type) {
$args['type'] = $command->type;
}

if ($command->uuids) {
$args['uuid'] = $command->uuids;
}

$this->events->deleteAll($args);
$this->dispatcher->dispatch(new EventsWasClear(type: $command->type));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class ClearAction
public function __invoke(ClearEventsRequest $request, CommandBusInterface $bus): ResourceInterface
{
$bus->dispatch(
new ClearEvents(type: $request->type),
new ClearEvents(type: $request->type, uuids: $request->uuids),
);

return new SuccessResource();
Expand Down
12 changes: 12 additions & 0 deletions app/modules/Events/Interfaces/Http/Request/ClearEventsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Modules\Events\Interfaces\Http\Request;

use Modules\Events\Interfaces\Http\Resources\EventResource;
use Spiral\Filters\Attribute\Input\Data;
use Spiral\Filters\Model\Filter;
use Spiral\Filters\Model\FilterDefinitionInterface;
Expand All @@ -26,10 +27,21 @@ final class ClearEventsRequest extends Filter implements HasFilterDefinition
#[Data]
public ?string $type = null;

#[OA\Property(
property: 'uuids',
description: 'Uuids',
type: 'array',
items: new OA\Items(type: 'string', format: 'uuid'),
nullable: true,
)]
#[Data]
public ?array $uuids = null;

public function filterDefinition(): FilterDefinitionInterface
{
return new FilterDefinition([
'type' => ['string'],
'uuids' => ['array'],
]);
}
}
3 changes: 2 additions & 1 deletion app/src/Application/Commands/ClearEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class ClearEvents implements CommandInterface
{
public function __construct(
public readonly ?string $type = null
public readonly ?string $type = null,
public readonly ?array $uuids = null,
) {}
}
7 changes: 6 additions & 1 deletion app/src/Application/Persistence/CacheEventRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function store(Event $event): bool
$id = (string)$event->getUuid();
$ids = $this->getEventIds();
$ids[$id] = [
'uuid' => (string)$event->getUuid(),
'type' => $event->getType(),
'date' => \microtime(true),
];
Expand Down Expand Up @@ -168,7 +169,11 @@ private function getFilteredEventIds(array $scope = [], array $orderBy = []): ar
{
$criteria = (new Criteria())->orderBy($orderBy);
foreach ($scope as $key => $value) {
$criteria->andWhere(Criteria::expr()->eq($key, $value));
match (true) {
\is_array($value) => $criteria->orWhere(Criteria::expr()->in($key, $value)),
null === $value => $criteria->orWhere(Criteria::expr()->isNull($key)),
default => $criteria->orWhere(Criteria::expr()->eq($key, $value)),
};
}

$ids = (new ArrayCollection($this->getEventIds()))->matching($criteria)->toArray();
Expand Down
17 changes: 15 additions & 2 deletions tests/App/Events/EventsMocker.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Application\Domain\ValueObjects\Uuid;
use Mockery\MockInterface;
use Modules\Events\Domain\EventRepositoryInterface;
use PHPUnit\Framework\TestCase;

final class EventsMocker
{
Expand Down Expand Up @@ -34,11 +35,23 @@ public function eventShouldBeDeleted(Uuid $uuid, bool $status = true): void
->andReturn($status);
}

public function eventShouldBeClear(?string $type = null): void
public function eventShouldBeClear(?string $type = null, ?array $uuids = null): void
{
$args = [];
if ($type) {
$args['type'] = $type;
}

if ($uuids) {
$args['uuid'] = $uuids;
}

$this->events
->shouldReceive('deleteAll')
->with($type ? ['type' => $type] : [])
->withArgs(function (array $data) use($args): bool {
TestCase::assertSame($args, $data);
return true;
})
->once();
}
}
13 changes: 11 additions & 2 deletions tests/App/Http/HttpFaker.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,21 @@ public function deleteEvent(Uuid $uuid): ResponseAssertions
);
}

public function clearEvents(?string $type = null): ResponseAssertions
public function clearEvents(?string $type = null, ?array $uuids = null): ResponseAssertions
{
$args = [];
if ($type) {
$args['type'] = $type;
}

if ($uuids) {
$args['uuids'] = $uuids;
}

return $this->makeResponse(
$this->http->deleteJson(
uri: '/api/events/',
data: $type ? ['type' => $type] : [],
data: $args,
),
);
}
Expand Down
18 changes: 18 additions & 0 deletions tests/Feature/Interfaces/Http/Events/ClearActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,22 @@ public function testClearEventsByType(): void
->clearEvents(type: 'test')
->assertSuccessResource();
}

public function testClearEventsByUuids(): void
{
$this->fakeEvents()->eventShouldBeClear(uuids: ['foo', 'bar']);

$this->http
->clearEvents(uuids: ['foo', 'bar'])
->assertSuccessResource();
}

public function testClearEventsByTypeAndUuids(): void
{
$this->fakeEvents()->eventShouldBeClear(type: 'test', uuids: ['foo', 'bar']);

$this->http
->clearEvents(type: 'test', uuids: ['foo', 'bar'])
->assertSuccessResource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Inspector;
namespace Tests\Feature\Interfaces\Http\Inspector;

use Nyholm\Psr7\Stream;
use Tests\Feature\Interfaces\Http\ControllerTestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Ray;
namespace Tests\Feature\Interfaces\Http\Ray;

use Tests\Feature\Interfaces\Http\ControllerTestCase;

Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/Interfaces/Http/Ray/LocksActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Ray;
namespace Tests\Feature\Interfaces\Http\Ray;

use Psr\SimpleCache\CacheInterface;
use Tests\Feature\Interfaces\Http\ControllerTestCase;
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/Interfaces/Http/Ray/RayActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Ray;
namespace Tests\Feature\Interfaces\Http\Ray;

use Nyholm\Psr7\Stream;
use Tests\Feature\Interfaces\Http\ControllerTestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Sentry;
namespace Tests\Feature\Interfaces\Http\Sentry;

use Nyholm\Psr7\Stream;
use Tests\Feature\Interfaces\Http\ControllerTestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\Http\Sentry;
namespace Tests\Feature\Interfaces\Http\Sentry;

use Nyholm\Psr7\Stream;
use Tests\Feature\Interfaces\Http\ControllerTestCase;
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/Interfaces/TCP/VarDumper/SymfonyV6Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\TCP\VarDumper;
namespace Tests\Feature\Interfaces\TCP\VarDumper;

use Modules\VarDumper\Interfaces\TCP\Service;
use Spiral\RoadRunner\Tcp\Request;
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Interfaces\TCP\VarDumper;
namespace Tests\Feature\Interfaces\TCP\VarDumper;

use Modules\VarDumper\Interfaces\TCP\Service;
use Spiral\RoadRunner\Tcp\Request;
Expand Down
92 changes: 92 additions & 0 deletions tests/Unit/Modules/Events/Domain/CacheEventRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

declare(strict_types=1);

namespace Modules\Events\Domain;

use App\Application\Domain\Entity\Json;
use App\Application\Domain\ValueObjects\Uuid;
use App\Application\Persistence\CacheEventRepository;
use Tests\TestCase;

final class CacheEventRepositoryTest extends TestCase
{
private CacheEventRepository $repository;

protected function setUp(): void
{
parent::setUp();

$this->repository = $this->get(CacheEventRepository::class);
}

public function testStoreEvent(): void
{
$this->assertCount(0, $this->repository->findAll());

$this->createEvent();

$this->assertCount(1, $this->repository->findAll());
}

public function testDeleteByType(): void
{
$this->createEvent(type: 'foo');
$this->createEvent(type: 'foo');
$this->createEvent(type: 'bar');

$this->assertCount(3, $this->repository->findAll());

$this->repository->deleteAll(['type' => 'foo']);
$this->assertCount(1, $this->repository->findAll());
}

public function testDeleteByUuids(): void
{
$this->createEvent(uuid: $uuid1 = $this->randomUuid());
$this->createEvent(uuid: $uuid2 = $this->randomUuid());
$this->createEvent(uuid: $uuid3 = $this->randomUuid());

$this->assertCount(3, $this->repository->findAll());

$this->repository->deleteAll(['uuid' => [(string)$uuid1, (string)$uuid3]]);
$this->assertCount(1, $this->repository->findAll());

$result = \iterator_to_array($this->repository->findAll());

$this->assertSame((string)$uuid2, (string)$result[0]->getUuid());
}

public function testDeleteByTypeAndUuids(): void
{
$this->createEvent(type: 'foo');
$this->createEvent(type: 'foo');
$this->createEvent(type: 'bar', uuid: $uuid1 = $this->randomUuid());
$this->createEvent(uuid: $uuid2 = $this->randomUuid());
$this->createEvent(uuid: $uuid3 = $this->randomUuid());

$this->assertCount(5, $this->repository->findAll());

$this->repository->deleteAll(['type' => 'foo', 'uuid' => [(string)$uuid1, (string)$uuid3]]);
$this->assertCount(1, $this->repository->findAll());

$result = \iterator_to_array($this->repository->findAll());

$this->assertSame((string)$uuid2, (string)$result[0]->getUuid());
}

private function createEvent(string $type = 'test', ?Uuid $uuid = null): Event
{
$this->repository->store(
$event = new Event(
uuid: $uuid ?? $this->randomUuid(),
type: $type,
payload: new Json([]),
timestamp: \microtime(true),
projectId: null,
),
);

return $event;
}
}

0 comments on commit 462101b

Please sign in to comment.