Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recordsOnce() method #40

Merged
merged 2 commits into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/Doctrine/Event/PreAppendEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
*/
class PreAppendEvent extends Event
{
/**
* @var DomainEvent
*/
protected $domainEvent;
protected DomainEvent $domainEvent;

public function __construct(DomainEvent $domainEvent)
{
Expand Down
5 changes: 1 addition & 4 deletions src/Domain/Model/EventId.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

final class EventId
{
/**
* @var UuidInterface
*/
private $id;
private UuidInterface $id;

private function __construct(UuidInterface $id)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Domain/Model/RecordsEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
interface RecordsEvents
{
public function record(DomainEvent $event): void;

public function recordOnce(DomainEvent $event): void;
}
40 changes: 11 additions & 29 deletions src/Domain/Model/StoredEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,17 @@

class StoredEvent
{
/**
* @var string
*/
private $eventId;

/**
* @var \DateTimeImmutable
*/
private $occurredOn;

/**
* @var \DateTimeImmutable|null
*/
private $publishedOn;

/**
* @var string
*/
private $aggregateRoot;

/**
* @var string
*/
private $typeName;

/**
* @var string
*/
private $eventBody;
private string $eventId;

private \DateTimeImmutable $occurredOn;

private \DateTimeImmutable|null $publishedOn;

private string $aggregateRoot;

private string $typeName;

private string $eventBody;

public function __construct(
EventId $eventId,
Expand Down
14 changes: 3 additions & 11 deletions src/Domain/Model/Traits/DomainEventTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,14 @@

trait DomainEventTrait
{
/**
* @var string
*/
private $aggregateRootId;
private string $aggregateRootId;

/**
* The datetime the event occurred. Please use DomainEvent::MICROSECOND_DATE_FORMAT format.
*
* @var string
*/
private $occurredOn;
private string $occurredOn;

/**
* @var string|null
*/
private $actorId;
private string|null $actorId;

public function setActorId(?string $actorId): void
{
Expand Down
11 changes: 10 additions & 1 deletion src/Domain/Model/Traits/EventRecorderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ trait EventRecorderTrait
/**
* @var DomainEvent[]
*/
private $messages = [];
private array $messages = [];

/**
* @return DomainEvent[]
Expand All @@ -38,4 +38,13 @@ public function record(DomainEvent $message): void
{
$this->messages[] = $message;
}

public function recordOnce(DomainEvent $message): void
{
if (in_array($message, $this->messages, true)) {
return;
}

$this->messages[] = $message;
}
}
5 changes: 1 addition & 4 deletions src/EventSubscriber/NoEnvelopeDomainEventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

class NoEnvelopeDomainEventDispatcher implements DomainEventDispatcher
{
/**
* @var MessageBusInterface
*/
private $eventBus;
private MessageBusInterface $eventBus;

public function __construct(MessageBusInterface $eventBus)
{
Expand Down
20 changes: 4 additions & 16 deletions src/EventSubscriber/PublishDomainEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,13 @@

final class PublishDomainEventSubscriber implements EventSubscriberInterface
{
/**
* @var DomainEventDispatcher
*/
private $domainEventDispatcher;
private DomainEventDispatcher $domainEventDispatcher;

/**
* @var EventStore
*/
private $eventStore;
private EventStore $eventStore;

/**
* @var SerializerInterface
*/
private $serializer;
private SerializerInterface $serializer;

/**
* @var LockFactory
*/
private $lockFactory;
private LockFactory $lockFactory;

public function __construct(
DomainEventDispatcher $domainEventDispatcher,
Expand Down
84 changes: 84 additions & 0 deletions tests/Unit/Domain/Model/EventRecorderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace Headsnet\DomainEventsBundle\Unit\Domain\Model;

use Headsnet\DomainEventsBundle\Domain\Model\ContainsEvents;
use Headsnet\DomainEventsBundle\Domain\Model\DomainEvent;
use Headsnet\DomainEventsBundle\Domain\Model\RecordsEvents;
use Headsnet\DomainEventsBundle\Domain\Model\Traits\DomainEventTrait;
use Headsnet\DomainEventsBundle\Domain\Model\Traits\EventRecorderTrait;
use PHPUnit\Framework\TestCase;

class EventRecorderTest extends TestCase
{
public function test_event_is_recorded(): void
{
$sut = $this->fakeAggregate();
$event = $this->fakeEvent();

$sut->record($event);

$this->assertCount(1, $sut->getRecordedEvents());
$this->assertSame($event, $sut->getRecordedEvents()[0]);
}

public function test_multiple_duplicate_events_are_all_recorded(): void
{
$sut = $this->fakeAggregate();
$event = $this->fakeEvent();

$sut->record($event);
$sut->record($event);

$this->assertCount(2, $sut->getRecordedEvents());
$this->assertSame($event, $sut->getRecordedEvents()[0]);
$this->assertSame($event, $sut->getRecordedEvents()[1]);
}

public function test_record_once_ignores_duplicate_event(): void
{
$sut = $this->fakeAggregate();
$event = $this->fakeEvent();

$sut->recordOnce($event);
$sut->recordOnce($event);

$this->assertCount(1, $sut->getRecordedEvents());
$this->assertSame($event, $sut->getRecordedEvents()[0]);
}

public function test_multiple_events_are_recorded_once_each(): void
{
$sut = $this->fakeAggregate();
$event1 = $this->fakeEvent();
$event2 = $this->fakeEvent();

$sut->recordOnce($event1);
$sut->recordOnce($event1); // This duplicate should be ignored
$sut->recordOnce($event2);
$sut->recordOnce($event2); // This duplicate should be ignored

$this->assertCount(2, $sut->getRecordedEvents());
$this->assertSame($event1, $sut->getRecordedEvents()[0]);
$this->assertSame($event2, $sut->getRecordedEvents()[1]);
}

/**
* @return RecordsEvents&ContainsEvents
*/
public function fakeAggregate(): object
{
return new class() implements RecordsEvents, ContainsEvents {
use EventRecorderTrait;
};
}

public function fakeEvent(): DomainEvent
{
return new class() implements DomainEvent {
use DomainEventTrait;
};
}
}
Loading