Skip to content

Commit 351e2eb

Browse files
committed
Adds an ability to remove events by uuids
fixes #107
1 parent 6e291e3 commit 351e2eb

File tree

17 files changed

+175
-16
lines changed

17 files changed

+175
-16
lines changed

app/modules/Events/Interfaces/Commands/ClearEventsHandler.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,16 @@ public function __construct(
2121
#[CommandHandler]
2222
public function __invoke(ClearEvents $command): void
2323
{
24-
$this->events->deleteAll($command->type ? ['type' => $command->type] : []);
24+
$args = [];
25+
if ($command->type) {
26+
$args['type'] = $command->type;
27+
}
28+
29+
if ($command->uuids) {
30+
$args['uuid'] = $command->uuids;
31+
}
32+
33+
$this->events->deleteAll($args);
2534
$this->dispatcher->dispatch(new EventsWasClear(type: $command->type));
2635
}
2736
}

app/modules/Events/Interfaces/Http/Controllers/ClearAction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class ClearAction
3333
public function __invoke(ClearEventsRequest $request, CommandBusInterface $bus): ResourceInterface
3434
{
3535
$bus->dispatch(
36-
new ClearEvents(type: $request->type),
36+
new ClearEvents(type: $request->type, uuids: $request->uuids),
3737
);
3838

3939
return new SuccessResource();

app/modules/Events/Interfaces/Http/Request/ClearEventsRequest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Modules\Events\Interfaces\Http\Request;
66

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

30+
#[OA\Property(
31+
property: 'uuids',
32+
description: 'Uuids',
33+
type: 'array',
34+
items: new OA\Items(type: 'string', format: 'uuid'),
35+
nullable: true,
36+
)]
37+
#[Data]
38+
public ?array $uuids = null;
39+
2940
public function filterDefinition(): FilterDefinitionInterface
3041
{
3142
return new FilterDefinition([
3243
'type' => ['string'],
44+
'uuids' => ['array'],
3345
]);
3446
}
3547
}

app/src/Application/Commands/ClearEvents.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
class ClearEvents implements CommandInterface
1010
{
1111
public function __construct(
12-
public readonly ?string $type = null
12+
public readonly ?string $type = null,
13+
public readonly ?array $uuids = null,
1314
) {}
1415
}

app/src/Application/Persistence/CacheEventRepository.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public function store(Event $event): bool
5656
$id = (string)$event->getUuid();
5757
$ids = $this->getEventIds();
5858
$ids[$id] = [
59+
'uuid' => (string)$event->getUuid(),
5960
'type' => $event->getType(),
6061
'date' => \microtime(true),
6162
];
@@ -168,7 +169,11 @@ private function getFilteredEventIds(array $scope = [], array $orderBy = []): ar
168169
{
169170
$criteria = (new Criteria())->orderBy($orderBy);
170171
foreach ($scope as $key => $value) {
171-
$criteria->andWhere(Criteria::expr()->eq($key, $value));
172+
match (true) {
173+
\is_array($value) => $criteria->orWhere(Criteria::expr()->in($key, $value)),
174+
null === $value => $criteria->orWhere(Criteria::expr()->isNull($key)),
175+
default => $criteria->orWhere(Criteria::expr()->eq($key, $value)),
176+
};
172177
}
173178

174179
$ids = (new ArrayCollection($this->getEventIds()))->matching($criteria)->toArray();

tests/App/Events/EventsMocker.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Application\Domain\ValueObjects\Uuid;
88
use Mockery\MockInterface;
99
use Modules\Events\Domain\EventRepositoryInterface;
10+
use PHPUnit\Framework\TestCase;
1011

1112
final class EventsMocker
1213
{
@@ -34,11 +35,23 @@ public function eventShouldBeDeleted(Uuid $uuid, bool $status = true): void
3435
->andReturn($status);
3536
}
3637

37-
public function eventShouldBeClear(?string $type = null): void
38+
public function eventShouldBeClear(?string $type = null, ?array $uuids = null): void
3839
{
40+
$args = [];
41+
if ($type) {
42+
$args['type'] = $type;
43+
}
44+
45+
if ($uuids) {
46+
$args['uuid'] = $uuids;
47+
}
48+
3949
$this->events
4050
->shouldReceive('deleteAll')
41-
->with($type ? ['type' => $type] : [])
51+
->withArgs(function (array $data) use($args): bool {
52+
TestCase::assertSame($args, $data);
53+
return true;
54+
})
4255
->once();
4356
}
4457
}

tests/App/Http/HttpFaker.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,21 @@ public function deleteEvent(Uuid $uuid): ResponseAssertions
4040
);
4141
}
4242

43-
public function clearEvents(?string $type = null): ResponseAssertions
43+
public function clearEvents(?string $type = null, ?array $uuids = null): ResponseAssertions
4444
{
45+
$args = [];
46+
if ($type) {
47+
$args['type'] = $type;
48+
}
49+
50+
if ($uuids) {
51+
$args['uuids'] = $uuids;
52+
}
53+
4554
return $this->makeResponse(
4655
$this->http->deleteJson(
4756
uri: '/api/events/',
48-
data: $type ? ['type' => $type] : [],
57+
data: $args,
4958
),
5059
);
5160
}

tests/Feature/Interfaces/Http/Events/ClearActionTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,22 @@ public function testClearEventsByType(): void
2525
->clearEvents(type: 'test')
2626
->assertSuccessResource();
2727
}
28+
29+
public function testClearEventsByUuids(): void
30+
{
31+
$this->fakeEvents()->eventShouldBeClear(uuids: ['foo', 'bar']);
32+
33+
$this->http
34+
->clearEvents(uuids: ['foo', 'bar'])
35+
->assertSuccessResource();
36+
}
37+
38+
public function testClearEventsByTypeAndUuids(): void
39+
{
40+
$this->fakeEvents()->eventShouldBeClear(type: 'test', uuids: ['foo', 'bar']);
41+
42+
$this->http
43+
->clearEvents(type: 'test', uuids: ['foo', 'bar'])
44+
->assertSuccessResource();
45+
}
2846
}

tests/Feature/Interfaces/Http/Inspector/InspectorActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Inspector;
5+
namespace Tests\Feature\Interfaces\Http\Inspector;
66

77
use Nyholm\Psr7\Stream;
88
use Tests\Feature\Interfaces\Http\ControllerTestCase;

tests/Feature/Interfaces/Http/Ray/AvailabilityCheckActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Ray;
5+
namespace Tests\Feature\Interfaces\Http\Ray;
66

77
use Tests\Feature\Interfaces\Http\ControllerTestCase;
88

tests/Feature/Interfaces/Http/Ray/LocksActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Ray;
5+
namespace Tests\Feature\Interfaces\Http\Ray;
66

77
use Psr\SimpleCache\CacheInterface;
88
use Tests\Feature\Interfaces\Http\ControllerTestCase;

tests/Feature/Interfaces/Http/Ray/RayActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Ray;
5+
namespace Tests\Feature\Interfaces\Http\Ray;
66

77
use Nyholm\Psr7\Stream;
88
use Tests\Feature\Interfaces\Http\ControllerTestCase;

tests/Feature/Interfaces/Http/Sentry/SentryV3ActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Sentry;
5+
namespace Tests\Feature\Interfaces\Http\Sentry;
66

77
use Nyholm\Psr7\Stream;
88
use Tests\Feature\Interfaces\Http\ControllerTestCase;

tests/Feature/Interfaces/Http/Sentry/SentryV4ActionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\Http\Sentry;
5+
namespace Tests\Feature\Interfaces\Http\Sentry;
66

77
use Nyholm\Psr7\Stream;
88
use Tests\Feature\Interfaces\Http\ControllerTestCase;

tests/Feature/Interfaces/TCP/VarDumper/SymfonyV6Test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\TCP\VarDumper;
5+
namespace Tests\Feature\Interfaces\TCP\VarDumper;
66

77
use Modules\VarDumper\Interfaces\TCP\Service;
88
use Spiral\RoadRunner\Tcp\Request;

tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Interfaces\TCP\VarDumper;
5+
namespace Tests\Feature\Interfaces\TCP\VarDumper;
66

77
use Modules\VarDumper\Interfaces\TCP\Service;
88
use Spiral\RoadRunner\Tcp\Request;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Modules\Events\Domain;
6+
7+
use App\Application\Domain\Entity\Json;
8+
use App\Application\Domain\ValueObjects\Uuid;
9+
use App\Application\Persistence\CacheEventRepository;
10+
use Tests\TestCase;
11+
12+
final class CacheEventRepositoryTest extends TestCase
13+
{
14+
private CacheEventRepository $repository;
15+
16+
protected function setUp(): void
17+
{
18+
parent::setUp();
19+
20+
$this->repository = $this->get(CacheEventRepository::class);
21+
}
22+
23+
public function testStoreEvent(): void
24+
{
25+
$this->assertCount(0, $this->repository->findAll());
26+
27+
$this->createEvent();
28+
29+
$this->assertCount(1, $this->repository->findAll());
30+
}
31+
32+
public function testDeleteByType(): void
33+
{
34+
$this->createEvent(type: 'foo');
35+
$this->createEvent(type: 'foo');
36+
$this->createEvent(type: 'bar');
37+
38+
$this->assertCount(3, $this->repository->findAll());
39+
40+
$this->repository->deleteAll(['type' => 'foo']);
41+
$this->assertCount(1, $this->repository->findAll());
42+
}
43+
44+
public function testDeleteByUuids(): void
45+
{
46+
$this->createEvent(uuid: $uuid1 = $this->randomUuid());
47+
$this->createEvent(uuid: $uuid2 = $this->randomUuid());
48+
$this->createEvent(uuid: $uuid3 = $this->randomUuid());
49+
50+
$this->assertCount(3, $this->repository->findAll());
51+
52+
$this->repository->deleteAll(['uuid' => [(string)$uuid1, (string)$uuid3]]);
53+
$this->assertCount(1, $this->repository->findAll());
54+
55+
$result = \iterator_to_array($this->repository->findAll());
56+
57+
$this->assertSame((string)$uuid2, (string)$result[0]->getUuid());
58+
}
59+
60+
public function testDeleteByTypeAndUuids(): void
61+
{
62+
$this->createEvent(type: 'foo');
63+
$this->createEvent(type: 'foo');
64+
$this->createEvent(type: 'bar', uuid: $uuid1 = $this->randomUuid());
65+
$this->createEvent(uuid: $uuid2 = $this->randomUuid());
66+
$this->createEvent(uuid: $uuid3 = $this->randomUuid());
67+
68+
$this->assertCount(5, $this->repository->findAll());
69+
70+
$this->repository->deleteAll(['type' => 'foo', 'uuid' => [(string)$uuid1, (string)$uuid3]]);
71+
$this->assertCount(1, $this->repository->findAll());
72+
73+
$result = \iterator_to_array($this->repository->findAll());
74+
75+
$this->assertSame((string)$uuid2, (string)$result[0]->getUuid());
76+
}
77+
78+
private function createEvent(string $type = 'test', ?Uuid $uuid = null): Event
79+
{
80+
$this->repository->store(
81+
$event = new Event(
82+
uuid: $uuid ?? $this->randomUuid(),
83+
type: $type,
84+
payload: new Json([]),
85+
timestamp: \microtime(true),
86+
projectId: null,
87+
),
88+
);
89+
90+
return $event;
91+
}
92+
}

0 commit comments

Comments
 (0)