From 0e980ef428603e802544fe164616d5e96da775a5 Mon Sep 17 00:00:00 2001 From: Carnage Date: Thu, 7 Mar 2019 19:33:28 +0000 Subject: [PATCH] Add prize aggregate, test and projection --- src/Domain/MessageSubscriptions.php | 21 ++++++ src/Domain/Prizes/Command/ChooseWinner.php | 30 ++++++++ src/Domain/Prizes/Command/GiveawayPrize.php | 23 ++++++ src/Domain/Prizes/Command/ReplaceWinner.php | 24 +++++++ src/Domain/Prizes/Command/WinnerIs.php | 38 ++++++++++ src/Domain/Prizes/Event/PrizeGiveaway.php | 33 +++++++++ src/Domain/Prizes/Event/WinnerChosen.php | 30 ++++++++ src/Domain/Prizes/Prize.php | 71 +++++++++++++++++++ src/Domain/Prizes/Projector.php | 49 +++++++++++++ src/Domain/Prizes/ReadModel/Prize.php | 55 ++++++++++++++ .../AttendanceTest/Prizes/PrizeTest.php | 62 ++++++++++++++++ 11 files changed, 436 insertions(+) create mode 100644 src/Domain/Prizes/Command/ChooseWinner.php create mode 100644 src/Domain/Prizes/Command/GiveawayPrize.php create mode 100644 src/Domain/Prizes/Command/ReplaceWinner.php create mode 100644 src/Domain/Prizes/Command/WinnerIs.php create mode 100644 src/Domain/Prizes/Event/PrizeGiveaway.php create mode 100644 src/Domain/Prizes/Event/WinnerChosen.php create mode 100644 src/Domain/Prizes/Prize.php create mode 100644 src/Domain/Prizes/Projector.php create mode 100644 src/Domain/Prizes/ReadModel/Prize.php create mode 100644 tests/domain/Prizes/ConferenceTools/AttendanceTest/Prizes/PrizeTest.php diff --git a/src/Domain/MessageSubscriptions.php b/src/Domain/MessageSubscriptions.php index 6770d57..5dbab6b 100644 --- a/src/Domain/MessageSubscriptions.php +++ b/src/Domain/MessageSubscriptions.php @@ -4,6 +4,7 @@ use ConferenceTools\Attendance\Domain\Delegate; use ConferenceTools\Attendance\Domain\Discounting\DiscountType; +use ConferenceTools\Attendance\Domain\Prizes\Prize; use ConferenceTools\Attendance\Domain\Purchasing; use ConferenceTools\Attendance\Domain\Discounting\Command as DiscountingCommand; use ConferenceTools\Attendance\Domain\Discounting\Event as DiscountingEvent; @@ -40,6 +41,19 @@ public static function getSubscriptions() DiscountType::class, ], + Prizes\Command\ChooseWinner::class => [ + Prizes\Prize::class, + ], + Prizes\Command\GiveawayPrize::class => [ + Prizes\Prize::class, + ], + Prizes\Command\WinnerIs::class => [ + Prizes\Prize::class, + ], + Prizes\Command\ReplaceWinner::class => [ + Prizes\Prize::class, + ], + PurchasingCommand\CheckPurchaseTimeout::class => [ Purchasing\Purchase::class, ], @@ -87,6 +101,13 @@ public static function getSubscriptions() Discounting\Projector::class, ], + Prizes\Event\PrizeGiveaway::class => [ + Prizes\Projector::class, + ], + Prizes\Event\WinnerChosen::class => [ + Prizes\Projector::class, + ], + PurchasingEvent\TicketReservationExpired::class => [ Tickets::class, Purchasing\Projector::class, diff --git a/src/Domain/Prizes/Command/ChooseWinner.php b/src/Domain/Prizes/Command/ChooseWinner.php new file mode 100644 index 0000000..b7cf572 --- /dev/null +++ b/src/Domain/Prizes/Command/ChooseWinner.php @@ -0,0 +1,30 @@ +") */ + private $entrants; + + public function __construct(string $id, string ...$entrants) + { + $this->id = $id; + $this->entrants = $entrants; + } + + public function getActorId(): string + { + return $this->id; + } + + public function getEntrants(): array + { + return $this->entrants; + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/Command/GiveawayPrize.php b/src/Domain/Prizes/Command/GiveawayPrize.php new file mode 100644 index 0000000..1e53308 --- /dev/null +++ b/src/Domain/Prizes/Command/GiveawayPrize.php @@ -0,0 +1,23 @@ +name = $name; + } + + public function getName(): string + { + return $this->name; + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/Command/ReplaceWinner.php b/src/Domain/Prizes/Command/ReplaceWinner.php new file mode 100644 index 0000000..5d7c32d --- /dev/null +++ b/src/Domain/Prizes/Command/ReplaceWinner.php @@ -0,0 +1,24 @@ +id = $id; + } + + public function getActorId(): string + { + return $this->id; + } +} diff --git a/src/Domain/Prizes/Command/WinnerIs.php b/src/Domain/Prizes/Command/WinnerIs.php new file mode 100644 index 0000000..03484ad --- /dev/null +++ b/src/Domain/Prizes/Command/WinnerIs.php @@ -0,0 +1,38 @@ +") */ + private $entrants; + + public function __construct(string $id, string $winner, string ...$entrants) + { + $this->id = $id; + $this->winner = $winner; + $this->entrants = $entrants; + } + + public function getActorId(): string + { + return $this->id; + } + + public function getWinner(): string + { + return $this->winner; + } + + public function getEntrants(): array + { + return $this->entrants; + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/Event/PrizeGiveaway.php b/src/Domain/Prizes/Event/PrizeGiveaway.php new file mode 100644 index 0000000..2867b34 --- /dev/null +++ b/src/Domain/Prizes/Event/PrizeGiveaway.php @@ -0,0 +1,33 @@ +id = $id; + $this->name = $name; + } + + public function getId(): string + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/Event/WinnerChosen.php b/src/Domain/Prizes/Event/WinnerChosen.php new file mode 100644 index 0000000..7ad02b1 --- /dev/null +++ b/src/Domain/Prizes/Event/WinnerChosen.php @@ -0,0 +1,30 @@ +id = $id; + $this->winner = $winner; + } + + public function getId(): string + { + return $this->id; + } + + public function getWinner(): string + { + return $this->winner; + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/Prize.php b/src/Domain/Prizes/Prize.php new file mode 100644 index 0000000..b8acad4 --- /dev/null +++ b/src/Domain/Prizes/Prize.php @@ -0,0 +1,71 @@ +fire(new PrizeGiveaway($this->id(), $command->getName())); + } + + protected function applyPrizeGiveaway(PrizeGiveaway $event) + { + $this->name = $event->getName(); + } + + protected function handleChooseWinner(ChooseWinner $command) + { + $entrants = $command->getEntrants(); + $winner = array_pop($entrants); + $this->fire(new WinnerChosen($this->id(), $winner)); + } + + protected function handleWinnerIs(WinnerIs $command) + { + $this->fire(new WinnerChosen($this->id(), $command->getWinner())); + } + + protected function applyWinnerIs(WinnerIs $command) + { + $this->entrants = $command->getEntrants(); + } + + protected function applyChooseWinner(ChooseWinner $command) + { + $entrants = $command->getEntrants(); + array_pop($entrants); + $this->entrants = $entrants; + } + + protected function applyWinnerChosen(WinnerChosen $event) + { + $this->winner = $event->getWinner(); + } + + protected function handleReplaceWinner(ReplaceWinner $command) + { + $entrants = $this->entrants; + $winner = array_pop($entrants); + $this->fire(new WinnerChosen($this->id(), $winner)); + } + + protected function applyReplaceWinner(ReplaceWinner $command) + { + array_pop($this->entrants); + } + + // Collected +} \ No newline at end of file diff --git a/src/Domain/Prizes/Projector.php b/src/Domain/Prizes/Projector.php new file mode 100644 index 0000000..f922890 --- /dev/null +++ b/src/Domain/Prizes/Projector.php @@ -0,0 +1,49 @@ +repository = $repository; + } + + public function handle(DomainMessage $message) + { + $event = $message->getMessage(); + switch (true) { + case $event instanceof PrizeGiveaway: + $this->prizeGiveaway($event); + break; + case $event instanceof WinnerChosen: + $this->winnerChosen($event); + break; + } + + $this->repository->commit(); + } + + private function prizeGiveaway(PrizeGiveaway $event): void + { + $entity = new ReadModel\Prize($event->getId(), $event->getName()); + $this->repository->add($event); + } + + private function winnerChosen(WinnerChosen $event): void + { + /** @var ReadModel\Prize $entity */ + $entity = $this->repository->get($event->getId()); + $entity->winnerChosen($event->getWinner()); + } +} \ No newline at end of file diff --git a/src/Domain/Prizes/ReadModel/Prize.php b/src/Domain/Prizes/ReadModel/Prize.php new file mode 100644 index 0000000..b61d812 --- /dev/null +++ b/src/Domain/Prizes/ReadModel/Prize.php @@ -0,0 +1,55 @@ +id = $id; + $this->name = $name; + } + + public function getId(): string + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getWinner(): string + { + return $this->winner; + } + + public function hasBeenCollected(): bool + { + return $this->collected; + } + + public function winnerChosen(string $winner): void + { + $this->winner = $winner; + } +} \ No newline at end of file diff --git a/tests/domain/Prizes/ConferenceTools/AttendanceTest/Prizes/PrizeTest.php b/tests/domain/Prizes/ConferenceTools/AttendanceTest/Prizes/PrizeTest.php new file mode 100644 index 0000000..9b44f64 --- /dev/null +++ b/tests/domain/Prizes/ConferenceTools/AttendanceTest/Prizes/PrizeTest.php @@ -0,0 +1,62 @@ +helper = new ActorHelper(Prize::class); + $this->actorId = $this->helper->getActorIdentity()->getId(); + } + + public function testPrizeGiveaway() + { + $this->helper->when(new GiveawayPrize('Prize')); + $this->helper->expect(new PrizeGiveaway($this->actorId, 'Prize')); + } + + public function testWinnerIs() + { + srand(0); + $this->helper->given([new PrizeGiveaway($this->actorId, 'Prize')]); + $this->helper->when(new WinnerIs($this->actorId, 'd1', 'd2', 'd3', 'd4', 'd5')); + $this->helper->expect(new WinnerChosen($this->actorId, 'd1')); + } + + public function testChooseWinner() + { + srand(0); + $this->helper->given([new PrizeGiveaway($this->actorId, 'Prize')]); + $this->helper->when(new ChooseWinner($this->actorId, 'd1', 'd2', 'd3', 'd4', 'd5')); + $this->helper->expect(new WinnerChosen($this->actorId, 'd5')); + } + + public function testReplaceWinner() + { + srand(0); + $this->helper->given([ + new PrizeGiveaway($this->actorId, 'Prize'), + new ChooseWinner($this->actorId, 'd1', 'd2', 'd3', 'd4', 'd5'), + new WinnerChosen($this->actorId, 'd5') + ]); + $this->helper->when(new ReplaceWinner($this->actorId)); + $this->helper->expect(new WinnerChosen($this->actorId, 'd4')); + } + + //@TODO test scenarios with winners chosen multiple times +}