From 56500542958bfdd619317bd7de4809ae3baec264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Kukli=C5=84ski?= Date: Sun, 5 Nov 2023 17:52:29 +0100 Subject: [PATCH] Finished writing specs for BuildingConstruction component --- .../Command/CancelConstructingCommandSpec.php | 16 +- .../Command/FinishConstructingCommandSpec.php | 16 +- .../Command/StartConstructingCommandSpec.php | 29 +++- .../CancelConstructingCommandHandlerSpec.php | 67 +++++++- .../FinishConstructingCommandHandlerSpec.php | 69 +++++++- .../StartConstructingCommandHandlerSpec.php | 154 +++++++++++++++++- .../Domain/Entity/BuildingSpec.php | 72 +++++++- ...gConstructionHasBeenCancelledEventSpec.php | 48 +++++- ...ngConstructionHasBeenFinishedEventSpec.php | 17 +- ...ingConstructionHasBeenStartedEventSpec.php | 48 +++++- .../Factory/BuildingTypeEventFactorySpec.php | 39 ++++- ...neConstructionHasBeenFinishedEventSpec.php | 22 ++- ...geConstructionHasBeenFinishedEventSpec.php | 22 ++- .../Domain/Factory/BuildingFactorySpec.php | 28 +++- .../FinishConstructingCommandHandler.php | 6 +- .../StartConstructingCommandHandler.php | 18 +- .../Domain/Entity/Building.php | 6 +- .../Factory/BuildingTypeEventFactory.php | 5 +- .../BuildingTypeEventFactoryInterface.php | 13 ++ .../Domain/Factory/BuildingFactory.php | 2 +- .../Factory/BuildingFactoryInterface.php | 19 +++ 21 files changed, 642 insertions(+), 74 deletions(-) create mode 100644 src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactoryInterface.php create mode 100644 src/Application/Component/BuildingConstruction/Domain/Factory/BuildingFactoryInterface.php diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Command/CancelConstructingCommandSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Command/CancelConstructingCommandSpec.php index 1fa6258..29a6fcf 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Command/CancelConstructingCommandSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Command/CancelConstructingCommandSpec.php @@ -5,16 +5,28 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Command; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class CancelConstructingCommandSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "05FEB5A6-285B-46A8-8A3D-10280C68ECBA"; + $buildingType = BuildingType::ResourceStorage->value; + $this->beConstructedWith( + $planetId, + $buildingType, + ); } - public function it_has_building_type(): void + public function it_has_planet_id(): void { + $this->getPlanetId()->shouldReturn("05FEB5A6-285B-46A8-8A3D-10280C68ECBA"); + } + public function it_has_building_type(): void + { + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Command/FinishConstructingCommandSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Command/FinishConstructingCommandSpec.php index 6e23331..60b76b9 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Command/FinishConstructingCommandSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Command/FinishConstructingCommandSpec.php @@ -5,16 +5,28 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Command; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class FinishConstructingCommandSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "05FEB5A6-285B-46A8-8A3D-10280C68ECBA"; + $buildingType = BuildingType::ResourceStorage->value; + $this->beConstructedWith( + $planetId, + $buildingType, + ); } - public function it_has_building_type(): void + public function it_has_planet_id(): void { + $this->getPlanetId()->shouldReturn("05FEB5A6-285B-46A8-8A3D-10280C68ECBA"); + } + public function it_has_building_type(): void + { + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Command/StartConstructingCommandSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Command/StartConstructingCommandSpec.php index 619ee7b..b36e46c 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Command/StartConstructingCommandSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Command/StartConstructingCommandSpec.php @@ -5,26 +5,49 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Command; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class StartConstructingCommandSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "05FEB5A6-285B-46A8-8A3D-10280C68ECBA"; + $buildingType = BuildingType::ResourceStorage->value; + $resourceContextId = "68A3E097-C576-4087-9655-1ECAB8AA92F6"; + + $this->beConstructedWith( + $planetId, + $buildingType, + $resourceContextId, + ); + } + public function it_has_planet_id(): void + { + $this->getPlanetId()->shouldReturn("05FEB5A6-285B-46A8-8A3D-10280C68ECBA"); } public function it_has_building_type(): void { - + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } public function it_has_resource_context_id(): void { - + $this->getResourceContextId()->shouldReturn("68A3E097-C576-4087-9655-1ECAB8AA92F6"); } public function it_has_no_resource_context_id(): void { + $planetId = "05FEB5A6-285B-46A8-8A3D-10280C68ECBA"; + $buildingType = BuildingType::ResourceStorage->value; + + $this->beConstructedWith( + $planetId, + $buildingType, + null, + ); + $this->getResourceContextId()->shouldReturn(null); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/CancelConstructingCommandHandlerSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/CancelConstructingCommandHandlerSpec.php index a589a01..961417a 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/CancelConstructingCommandHandlerSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/CancelConstructingCommandHandlerSpec.php @@ -5,16 +5,75 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\CommandHandler; use PhpSpec\ObjectBehavior; +use Prophecy\Argument; +use TheGame\Application\Component\Balance\Bridge\BuildingContextInterface; +use TheGame\Application\Component\BuildingConstruction\BuildingRepositoryInterface; +use TheGame\Application\Component\BuildingConstruction\Command\CancelConstructingCommand; +use TheGame\Application\Component\BuildingConstruction\Domain\Entity\Building; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\BuildingConstructionHasBeenCancelledEvent; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingHasNotBeenBuiltYetFoundException; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetId; +use TheGame\Application\SharedKernel\Domain\ResourceRequirementsInterface; +use TheGame\Application\SharedKernel\EventBusInterface; final class CancelConstructingCommandHandlerSpec extends ObjectBehavior { - public function it_throws_exception_when_cant_find_aggregate(): void - { + public function let( + BuildingRepositoryInterface $buildingRepository, + BuildingContextInterface $buildingBalanceContext, + EventBusInterface $eventBus, + ): void { + $this->beConstructedWith( + $buildingRepository, + $buildingBalanceContext, + $eventBus, + ); + } + + public function it_throws_exception_when_cant_find_aggregate( + BuildingRepositoryInterface $buildingRepository, + ): void { + $planetId = "1D632422-951F-4181-A48D-5AD654260B2B"; + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceMine) + ->willReturn(null); + $command = new CancelConstructingCommand( + $planetId, + BuildingType::ResourceMine->value, + ); + $this->shouldThrow(BuildingHasNotBeenBuiltYetFoundException::class) + ->during('__invoke', [$command]); } - public function it_cancels_constructing(): void - { + public function it_cancels_constructing( + BuildingRepositoryInterface $buildingRepository, + BuildingContextInterface $buildingBalanceContext, + EventBusInterface $eventBus, + Building $building, + ResourceRequirementsInterface $resourceRequirements, + ): void { + $planetId = "1D632422-951F-4181-A48D-5AD654260B2B"; + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceMine) + ->willReturn($building); + + $buildingBalanceContext->getResourceRequirements(5, BuildingType::ResourceMine) + ->willReturn($resourceRequirements); + + $building->cancelUpgrading()->shouldBeCalledOnce(); + $building->getCurrentLevel()->willReturn(5); + $resourceRequirements->toScalarArray() + ->willReturn([ + "26E29382-BA42-4675-B643-93E9006B089B" => 500, + ]); + + $eventBus->dispatch(Argument::type(BuildingConstructionHasBeenCancelledEvent::class)) + ->shouldBeCalledOnce(); + $command = new CancelConstructingCommand( + $planetId, + BuildingType::ResourceMine->value, + ); + $this->__invoke($command); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandlerSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandlerSpec.php index e3b960f..c521b3d 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandlerSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandlerSpec.php @@ -4,17 +4,78 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\CommandHandler; +use PhpParser\Node\Arg; use PhpSpec\ObjectBehavior; +use Prophecy\Argument; +use TheGame\Application\Component\BuildingConstruction\BuildingRepositoryInterface; +use TheGame\Application\Component\BuildingConstruction\Command\FinishConstructingCommand; +use TheGame\Application\Component\BuildingConstruction\Domain\Entity\Building; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\Factory\BuildingTypeEventFactoryInterface; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\ResourceStorageConstructionHasBeenFinishedEvent; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingHasNotBeenBuiltYetFoundException; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetId; +use TheGame\Application\SharedKernel\EventBusInterface; final class FinishConstructingCommandHandlerSpec extends ObjectBehavior { - public function it_throws_exception_when_aggregate_is_not_found(): void - { + public function let( + BuildingRepositoryInterface $buildingRepository, + EventBusInterface $eventBus, + BuildingTypeEventFactoryInterface $buildingTypeEventFactory, + ): void { + $this->beConstructedWith( + $buildingRepository, + $eventBus, + $buildingTypeEventFactory, + ); + } + + public function it_throws_exception_when_aggregate_is_not_found( + BuildingRepositoryInterface $buildingRepository, + ): void { + $planetId = "1D632422-951F-4181-A48D-5AD654260B2B"; + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceStorage) + ->willReturn(null); + + $command = new FinishConstructingCommand( + $planetId, + BuildingType::ResourceStorage->value, + ); + $this->shouldThrow(BuildingHasNotBeenBuiltYetFoundException::class) + ->during('__invoke', [$command]); } - public function it_finishes_constructing(): void - { + public function it_finishes_constructing( + BuildingRepositoryInterface $buildingRepository, + EventBusInterface $eventBus, + BuildingTypeEventFactoryInterface $buildingTypeEventFactory, + Building $building, + ): void { + $planetId = "1D632422-951F-4181-A48D-5AD654260B2B"; + + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceStorage) + ->willReturn($building); + + $building->finishUpgrading()->shouldBeCalledOnce(); + + $resourceId = "73140C59-DE9C-4959-8E18-1271EB32D76A"; + $event = new ResourceStorageConstructionHasBeenFinishedEvent( + $planetId, + $resourceId, + 1 + ); + $buildingTypeEventFactory->createConstructingFinishedEvent($building) + ->willReturn($event); + + $eventBus->dispatch(Argument::type(ResourceStorageConstructionHasBeenFinishedEvent::class)) + ->shouldBeCalledOnce(); + $command = new FinishConstructingCommand( + $planetId, + BuildingType::ResourceStorage->value, + ); + $this->__invoke($command); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandlerSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandlerSpec.php index b566940..8b18bbe 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandlerSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandlerSpec.php @@ -4,22 +4,164 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\CommandHandler; +use DateTimeImmutable; +use DateTimeInterface; use PhpSpec\ObjectBehavior; +use Prophecy\Argument; +use TheGame\Application\Component\Balance\Bridge\BuildingContextInterface; +use TheGame\Application\Component\BuildingConstruction\BuildingRepositoryInterface; +use TheGame\Application\Component\BuildingConstruction\Command\StartConstructingCommand; +use TheGame\Application\Component\BuildingConstruction\Domain\Entity\Building; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\BuildingConstructionHasBeenStartedEvent; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\InsufficientResourcesException; +use TheGame\Application\Component\BuildingConstruction\Domain\Factory\BuildingFactoryInterface; +use TheGame\Application\Component\ResourceStorage\Bridge\ResourceAvailabilityCheckerInterface; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetId; +use TheGame\Application\SharedKernel\Domain\ResourceId; +use TheGame\Application\SharedKernel\Domain\ResourceRequirementsInterface; +use TheGame\Application\SharedKernel\EventBusInterface; final class StartConstructingCommandHandlerSpec extends ObjectBehavior { - public function it_throws_exception_when_aggregate_is_not_found(): void - { + public function let( + ResourceAvailabilityCheckerInterface $resourceAvailabilityChecker, + BuildingRepositoryInterface $buildingRepository, + BuildingContextInterface $buildingBalanceContext, + BuildingFactoryInterface $buildingFactory, + EventBusInterface $eventBus, + ): void { + $this->beConstructedWith( + $resourceAvailabilityChecker, + $buildingRepository, + $buildingBalanceContext, + $buildingFactory, + $eventBus, + ); + } + + public function it_creates_building_when_the_aggregate_is_not_found( + BuildingRepositoryInterface $buildingRepository, + BuildingFactoryInterface $buildingFactory, + Building $building, + BuildingContextInterface $buildingBalanceContext, + ResourceAvailabilityCheckerInterface $resourceAvailabilityChecker, + ResourceRequirementsInterface $resourceRequirements, + EventBusInterface $eventBus, + ): void { + $planetId = "E7AF94C7-488C-46E4-8C44-DCD8F62B2A45"; + $resourceContextId = "52B4E60C-5CCE-4483-968E-D23D9240A18A"; + + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceStorage) + ->willReturn(null); + + $buildingFactory->createNew( + new PlanetId($planetId), BuildingType::ResourceStorage, new ResourceId($resourceContextId), + )->willReturn($building); + + $building->getCurrentLevel()->willReturn(1); + $building->getType()->willReturn(BuildingType::ResourceStorage); + + $buildingBalanceContext->getResourceRequirements(1, BuildingType::ResourceStorage) + ->willReturn($resourceRequirements); + $resourceAvailabilityChecker->check(new PlanetId($planetId), $resourceRequirements) + ->willReturn(true); + + $buildingBalanceContext->getBuildingDuration(1, BuildingType::ResourceStorage) + ->willReturn(500); + $building->startUpgrading(Argument::type(DateTimeInterface::class))->shouldBeCalledOnce(); + + $resourceRequirements->toScalarArray()->willReturn([ + "0E0987D9-6D13-45A0-9CB5-3000DA9E2174" => 420, + ]); + + $eventBus->dispatch(Argument::type(BuildingConstructionHasBeenStartedEvent::class)) + ->shouldBeCalledOnce(); + + $command = new StartConstructingCommand( + $planetId, + BuildingType::ResourceStorage->value, + $resourceContextId, + ); + $this->__invoke($command); } - public function it_throws_exception_when_storage_hasnt_enough_resources(): void - { + public function it_throws_exception_when_storage_hasnt_enough_resources( + BuildingRepositoryInterface $buildingRepository, + BuildingFactoryInterface $buildingFactory, + Building $building, + BuildingContextInterface $buildingBalanceContext, + ResourceAvailabilityCheckerInterface $resourceAvailabilityChecker, + ResourceRequirementsInterface $resourceRequirements, + ): void { + $planetId = "E7AF94C7-488C-46E4-8C44-DCD8F62B2A45"; + $resourceContextId = "52B4E60C-5CCE-4483-968E-D23D9240A18A"; + + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceStorage) + ->willReturn(null); + $buildingFactory->createNew( + new PlanetId($planetId), BuildingType::ResourceStorage, new ResourceId($resourceContextId), + )->willReturn($building); + + $building->getCurrentLevel()->willReturn(1); + $building->getType()->willReturn(BuildingType::ResourceStorage); + + $buildingBalanceContext->getResourceRequirements(1, BuildingType::ResourceStorage) + ->willReturn($resourceRequirements); + + $resourceAvailabilityChecker->check(new PlanetId($planetId), $resourceRequirements) + ->willReturn(false); + + $command = new StartConstructingCommand( + $planetId, + BuildingType::ResourceStorage->value, + $resourceContextId, + ); + $this->shouldThrow(InsufficientResourcesException::class) + ->during('__invoke', [$command]); } - public function it_starts_constructing_the_building(): void - { + public function it_starts_constructing_the_building( + BuildingRepositoryInterface $buildingRepository, + Building $building, + BuildingContextInterface $buildingBalanceContext, + ResourceAvailabilityCheckerInterface $resourceAvailabilityChecker, + ResourceRequirementsInterface $resourceRequirements, + EventBusInterface $eventBus, + ): void { + $planetId = "E7AF94C7-488C-46E4-8C44-DCD8F62B2A45"; + $resourceContextId = "52B4E60C-5CCE-4483-968E-D23D9240A18A"; + + $buildingRepository->findForPlanet(new PlanetId($planetId), BuildingType::ResourceStorage) + ->willReturn($building); + + $building->getCurrentLevel()->willReturn(1); + $building->getType()->willReturn(BuildingType::ResourceStorage); + + $buildingBalanceContext->getResourceRequirements(1, BuildingType::ResourceStorage) + ->willReturn($resourceRequirements); + + $resourceAvailabilityChecker->check(new PlanetId($planetId), $resourceRequirements) + ->willReturn(true); + + $buildingBalanceContext->getBuildingDuration(1, BuildingType::ResourceStorage) + ->willReturn(500); + $building->startUpgrading(Argument::type(DateTimeInterface::class))->shouldBeCalledOnce(); + + $resourceRequirements->toScalarArray()->willReturn([ + "0E0987D9-6D13-45A0-9CB5-3000DA9E2174" => 420, + ]); + + $eventBus->dispatch(Argument::type(BuildingConstructionHasBeenStartedEvent::class)) + ->shouldBeCalledOnce(); + $command = new StartConstructingCommand( + $planetId, + BuildingType::ResourceStorage->value, + $resourceContextId, + ); + $this->__invoke($command); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Entity/BuildingSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Entity/BuildingSpec.php index 0be5da4..eee047f 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Entity/BuildingSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Entity/BuildingSpec.php @@ -4,72 +4,128 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Entity; +use DateTimeImmutable; use PhpSpec\ObjectBehavior; +use TheGame\Application\Component\BuildingConstruction\Domain\BuildingId; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingIsAlreadyUpgradingException; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingIsNotUpgradingYetException; +use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingTimeHasNotPassedException; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetId; +use TheGame\Application\SharedKernel\Domain\PlanetIdInterface; +use TheGame\Application\SharedKernel\Domain\ResourceId; +use TheGame\Application\SharedKernel\Domain\ResourceIdInterface; final class BuildingSpec extends ObjectBehavior { - public function it_has_identifier(): void + public function let(): void { + $planetId = "0CAB5B81-969A-4C2A-88B6-91B7B4B45E68"; + $buildingId = "B51FAABD-AC4C-4806-A3E7-A35234E54ABB"; + $buildingType = BuildingType::ResourceStorage; + $resourceContextId = "D4EF6F12-604D-4590-944F-0BD5F5270A53"; + + $this->beConstructedWith( + new PlanetId($planetId), + new BuildingId($buildingId), + $buildingType, + new ResourceId($resourceContextId), + ); + } + public function it_has_identifier(): void + { + $this->getId()->shouldHaveType(BuildingId::class); + $this->getId()->getUuid()->shouldReturn("B51FAABD-AC4C-4806-A3E7-A35234E54ABB"); } public function it_has_planet_identifier(): void { - + $this->getPlanetId()->shouldHaveType(PlanetIdInterface::class); + $this->getPlanetId()->getUuid()->shouldReturn("0CAB5B81-969A-4C2A-88B6-91B7B4B45E68"); } public function it_has_current_level(): void { - + $this->getCurrentLevel()->shouldReturn(0); } public function it_has_a_type(): void { - + $this->getType()->shouldReturn(BuildingType::ResourceStorage); } public function it_starts_upgrading(): void { - + $this->startUpgrading(new DateTimeImmutable("now +10 seconds")); } public function it_throws_exception_when_starts_upgrading_building_which_is_already_during_upgrade(): void { + $this->startUpgrading(new DateTimeImmutable("now +10 seconds")); + $this->shouldThrow(BuildingIsAlreadyUpgradingException::class) + ->during('startUpgrading', [new DateTimeImmutable("now +10 seconds")]); } public function it_cancels_upgrading(): void { + $this->startUpgrading(new DateTimeImmutable("now +10 seconds")); + $this->cancelUpgrading(); } public function it_throws_exception_when_cancels_upgrading_a_building_which_is_not_during_upgrade(): void { + $this->startUpgrading(new DateTimeImmutable("now +10 seconds")); + $this->cancelUpgrading(); + $this->shouldThrow(BuildingIsNotUpgradingYetException::class) + ->during('cancelUpgrading', []); } public function it_finishes_upgrading_building(): void { - + $this->startUpgrading(new DateTimeImmutable("now -10 seconds")); + $this->finishUpgrading(); } public function it_throws_exception_when_finishes_upgrading_a_building_which_is_not_during_upgrade(): void { + $this->startUpgrading(new DateTimeImmutable("now -10 seconds")); + $this->finishUpgrading(); + $this->shouldThrow(BuildingIsNotUpgradingYetException::class) + ->during('finishUpgrading', []); } public function it_throws_exception_when_finishes_upgrading_a_building_when_upgrade_time_didnt_pass(): void { + $this->startUpgrading(new DateTimeImmutable("now +1 second")); + $this->shouldThrow(BuildingTimeHasNotPassedException::class) + ->during('finishUpgrading', []); } public function it_has_resource_context_id(): void { - + $this->getResourceContextId()->shouldHaveType(ResourceIdInterface::class); + $this->getResourceContextId()->getUuid()->shouldReturn("D4EF6F12-604D-4590-944F-0BD5F5270A53"); } public function it_has_no_resource_context_id(): void { - + $planetId = "0CAB5B81-969A-4C2A-88B6-91B7B4B45E68"; + $buildingId = "B51FAABD-AC4C-4806-A3E7-A35234E54ABB"; + $buildingType = BuildingType::ResourceStorage; + + $this->beConstructedWith( + new PlanetId($planetId), + new BuildingId($buildingId), + $buildingType, + null, + ); + + $this->getResourceContextId()->shouldReturn(null); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenCancelledEventSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenCancelledEventSpec.php index 58239b2..e73ecb2 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenCancelledEventSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenCancelledEventSpec.php @@ -4,32 +4,74 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event; +use InvalidArgumentException; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class BuildingConstructionHasBeenCancelledEventSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $resourceRequirements = [ + "6842FCCF-9905-41FF-B542-4788579F0847" => 750, + ]; + $this->beConstructedWith( + $planetId, BuildingType::ResourceStorage->value, $resourceRequirements, + ); } - public function it_has_building_type(): void + public function it_has_planet_id(): void { + $this->getPlanetId()->shouldReturn("6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"); + } + public function it_has_building_type(): void + { + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } public function it_has_resource_requirements(): void { - + $this->getResourceRequirements()->shouldReturn([ + "6842FCCF-9905-41FF-B542-4788579F0847" => 750, + ]); } public function it_throws_exception_when_resource_requirements_is_an_array_with_no_string_keys(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $buildingType = BuildingType::ResourceStorage->value; + $resourceRequirements = [ + 300 => 750, + ]; + $this->beConstructedWith( + $planetId, $buildingType, $resourceRequirements, + ); + + $this->shouldThrow(InvalidArgumentException::class) + ->during('__construct', [ + $planetId, $buildingType, $resourceRequirements, + ]); } public function it_throws_exception_when_resource_requirements_is_an_array_with_no_integer_value(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $buildingType = BuildingType::ResourceStorage->value; + $resourceRequirements = [ + "6842FCCF-9905-41FF-B542-4788579F0847" => "not-int-value", + ]; + + $this->beConstructedWith( + $planetId, $buildingType, $resourceRequirements, + ); + $this->shouldThrow(InvalidArgumentException::class) + ->during('__construct', [ + $planetId, $buildingType, $resourceRequirements, + ]); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenFinishedEventSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenFinishedEventSpec.php index c8052b3..b947ecd 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenFinishedEventSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenFinishedEventSpec.php @@ -5,21 +5,32 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class BuildingConstructionHasBeenFinishedEventSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $level = 1; + $this->beConstructedWith( + $planetId, BuildingType::ResourceStorage->value, $level, + ); } - public function it_has_building_type(): void + public function it_has_planet_id(): void { + $this->getPlanetId()->shouldReturn("6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"); + } + public function it_has_building_type(): void + { + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } public function it_has_level(): void { - + $this->getLevel()->shouldReturn(1); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenStartedEventSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenStartedEventSpec.php index 41aff28..40ff101 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenStartedEventSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/BuildingConstructionHasBeenStartedEventSpec.php @@ -4,32 +4,74 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event; +use InvalidArgumentException; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class BuildingConstructionHasBeenStartedEventSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $resourceRequirements = [ + "6842FCCF-9905-41FF-B542-4788579F0847" => 750, + ]; + $this->beConstructedWith( + $planetId, BuildingType::ResourceStorage->value, $resourceRequirements, + ); } - public function it_has_building_type(): void + public function it_has_planet_id(): void { + $this->getPlanetId()->shouldReturn("6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"); + } + public function it_has_building_type(): void + { + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } public function it_has_resource_requirements(): void { - + $this->getResourceRequirements()->shouldReturn([ + "6842FCCF-9905-41FF-B542-4788579F0847" => 750, + ]); } public function it_throws_exception_when_resource_requirements_is_an_array_with_no_string_keys(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $buildingType = BuildingType::ResourceStorage->value; + $resourceRequirements = [ + 300 => 750, + ]; + $this->beConstructedWith( + $planetId, $buildingType, $resourceRequirements, + ); + + $this->shouldThrow(InvalidArgumentException::class) + ->during('__construct', [ + $planetId, $buildingType, $resourceRequirements, + ]); } public function it_throws_exception_when_resource_requirements_is_an_array_with_no_integer_value(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $buildingType = BuildingType::ResourceStorage->value; + $resourceRequirements = [ + "6842FCCF-9905-41FF-B542-4788579F0847" => "not-int-value", + ]; + + $this->beConstructedWith( + $planetId, $buildingType, $resourceRequirements, + ); + $this->shouldThrow(InvalidArgumentException::class) + ->during('__construct', [ + $planetId, $buildingType, $resourceRequirements, + ]); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactorySpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactorySpec.php index 6f9131f..91c8f23 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactorySpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactorySpec.php @@ -4,22 +4,51 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event\Factory; +use PhpSpec\Exception\Example\SkippingException; use PhpSpec\ObjectBehavior; +use TheGame\Application\Component\BuildingConstruction\Domain\Entity\Building; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\ResourceMineConstructionHasBeenFinishedEvent; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\ResourceStorageConstructionHasBeenFinishedEvent; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetId; +use TheGame\Application\SharedKernel\Domain\ResourceId; final class BuildingTypeEventFactorySpec extends ObjectBehavior { - public function it_creates_a_construction_finished_event_for_mine_building(): void - { + public function it_creates_a_construction_finished_event_for_mine_building( + Building $building + ): void { + $planetId = "A16D8FB1-FD3B-4C25-A1FC-D04857EF917A"; + $building->getPlanetId()->willReturn(new PlanetId($planetId)); + + $resourceContextId = "3FA9C84B-F2A7-44D0-8EA3-63DD66D23899"; + $building->getResourceContextId()->willReturn(new ResourceId($resourceContextId)); + $building->getCurrentLevel()->willReturn(1); + $building->getType()->willReturn(BuildingType::ResourceMine); + + $this->createConstructingFinishedEvent($building) + ->shouldReturnAnInstanceOf(ResourceMineConstructionHasBeenFinishedEvent::class); } - public function it_creates_a_construction_finished_event_for_storage_building(): void - { + public function it_creates_a_construction_finished_event_for_storage_building( + Building $building + ): void { + $planetId = "A16D8FB1-FD3B-4C25-A1FC-D04857EF917A"; + $building->getPlanetId()->willReturn(new PlanetId($planetId)); + $resourceContextId = "3FA9C84B-F2A7-44D0-8EA3-63DD66D23899"; + $building->getResourceContextId()->willReturn(new ResourceId($resourceContextId)); + + $building->getCurrentLevel()->willReturn(1); + $building->getType()->willReturn(BuildingType::ResourceStorage); + + $this->createConstructingFinishedEvent($building) + ->shouldReturnAnInstanceOf(ResourceStorageConstructionHasBeenFinishedEvent::class); } public function it_creates_a_generic_construction_finished_event(): void { - + throw new SkippingException('Cannot spec this scenario, because of using enum'); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceMineConstructionHasBeenFinishedEventSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceMineConstructionHasBeenFinishedEventSpec.php index 6933556..6f39c03 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceMineConstructionHasBeenFinishedEventSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceMineConstructionHasBeenFinishedEventSpec.php @@ -5,26 +5,40 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class ResourceMineConstructionHasBeenFinishedEventSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $level = 1; + $resourceContextId = "F8214FC4-B5E8-4D19-8360-8E95BE8FBF9B"; + + $this->beConstructedWith( + $planetId, + $resourceContextId, + $level, + ); + } + public function it_has_planet_id(): void + { + $this->getPlanetId()->shouldReturn("6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"); } public function it_has_building_type(): void { - + $this->getBuildingType()->shouldReturn(BuildingType::ResourceMine->value); } public function it_has_current_level(): void { - + $this->getLevel()->shouldReturn(1); } public function it_has_resource_context_id(): void { - + $this->getResourceContextId()->shouldReturn("F8214FC4-B5E8-4D19-8360-8E95BE8FBF9B"); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceStorageConstructionHasBeenFinishedEventSpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceStorageConstructionHasBeenFinishedEventSpec.php index 96c6177..e589ef9 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceStorageConstructionHasBeenFinishedEventSpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Event/ResourceStorageConstructionHasBeenFinishedEventSpec.php @@ -5,26 +5,40 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Event; use PhpSpec\ObjectBehavior; +use TheGame\Application\SharedKernel\Domain\BuildingType; final class ResourceStorageConstructionHasBeenFinishedEventSpec extends ObjectBehavior { - public function it_has_planet_id(): void + public function let(): void { + $planetId = "6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"; + $level = 1; + $resourceContextId = "F8214FC4-B5E8-4D19-8360-8E95BE8FBF9B"; + + $this->beConstructedWith( + $planetId, + $resourceContextId, + $level, + ); + } + public function it_has_planet_id(): void + { + $this->getPlanetId()->shouldReturn("6B685A5A-E279-4E8D-A9D4-0EEC6E7F0F3D"); } public function it_has_building_type(): void { - + $this->getBuildingType()->shouldReturn(BuildingType::ResourceStorage->value); } public function it_has_current_level(): void { - + $this->getLevel()->shouldReturn(1); } public function it_has_resource_context_id(): void { - + $this->getResourceContextId()->shouldReturn("F8214FC4-B5E8-4D19-8360-8E95BE8FBF9B"); } } diff --git a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Factory/BuildingFactorySpec.php b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Factory/BuildingFactorySpec.php index 88d7f14..ae4b018 100644 --- a/spec/TheGame/Application/Component/BuildingConstruction/Domain/Factory/BuildingFactorySpec.php +++ b/spec/TheGame/Application/Component/BuildingConstruction/Domain/Factory/BuildingFactorySpec.php @@ -5,11 +5,35 @@ namespace spec\TheGame\Application\Component\BuildingConstruction\Domain\Factory; use PhpSpec\ObjectBehavior; +use TheGame\Application\Component\BuildingConstruction\Domain\BuildingIdInterface; +use TheGame\Application\SharedKernel\Domain\BuildingType; +use TheGame\Application\SharedKernel\Domain\PlanetIdInterface; +use TheGame\Application\SharedKernel\Domain\ResourceIdInterface; +use TheGame\Application\SharedKernel\UuidGeneratorInterface; final class BuildingFactorySpec extends ObjectBehavior { - public function it_creates_new_building(): void - { + public function let( + UuidGeneratorInterface $uuidGenerator, + ): void { + $this->beConstructedWith($uuidGenerator); + } + + public function it_creates_new_building( + UuidGeneratorInterface $uuidGenerator, + BuildingIdInterface $buildingId, + PlanetIdInterface $planetId, + ResourceIdInterface $resourceContextId, + ): void { + $uuidGenerator->generateNewBuildingId() + ->willReturn($buildingId); + + $buildingType = BuildingType::ResourceMine; + $building = $this->createNew($planetId, $buildingType, $resourceContextId); + + $building->getPlanetId()->shouldReturn($planetId); + $building->getType()->shouldReturn($buildingType); + $building->getCurrentLevel()->shouldReturn(0); } } diff --git a/src/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandler.php b/src/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandler.php index 0cb60f5..fcc0a8b 100644 --- a/src/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandler.php +++ b/src/Application/Component/BuildingConstruction/CommandHandler/FinishConstructingCommandHandler.php @@ -6,7 +6,7 @@ use TheGame\Application\Component\BuildingConstruction\BuildingRepositoryInterface; use TheGame\Application\Component\BuildingConstruction\Command\FinishConstructingCommand; -use TheGame\Application\Component\BuildingConstruction\Domain\Event\Factory\BuildingTypeEventFactory; +use TheGame\Application\Component\BuildingConstruction\Domain\Event\Factory\BuildingTypeEventFactoryInterface; use TheGame\Application\Component\BuildingConstruction\Domain\Exception\BuildingHasNotBeenBuiltYetFoundException; use TheGame\Application\SharedKernel\Domain\BuildingType; use TheGame\Application\SharedKernel\Domain\PlanetId; @@ -17,14 +17,14 @@ final class FinishConstructingCommandHandler public function __construct( private readonly BuildingRepositoryInterface $buildingRepository, private readonly EventBusInterface $eventBus, - private readonly BuildingTypeEventFactory $buildingTypeEventFactory, + private readonly BuildingTypeEventFactoryInterface $buildingTypeEventFactory, ) { } public function __invoke(FinishConstructingCommand $command): void { $planetId = new PlanetId($command->getPlanetId()); - $buildingType = BuildingType::fromName($command->getBuildingType()); + $buildingType = BuildingType::from($command->getBuildingType()); $building = $this->buildingRepository->findForPlanet($planetId, $buildingType); if ($building === null) { diff --git a/src/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandler.php b/src/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandler.php index 75273b0..9934e8c 100644 --- a/src/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandler.php +++ b/src/Application/Component/BuildingConstruction/CommandHandler/StartConstructingCommandHandler.php @@ -10,7 +10,7 @@ use TheGame\Application\Component\BuildingConstruction\Command\StartConstructingCommand; use TheGame\Application\Component\BuildingConstruction\Domain\Event\BuildingConstructionHasBeenStartedEvent; use TheGame\Application\Component\BuildingConstruction\Domain\Exception\InsufficientResourcesException; -use TheGame\Application\Component\BuildingConstruction\Domain\Factory\BuildingFactory; +use TheGame\Application\Component\BuildingConstruction\Domain\Factory\BuildingFactoryInterface; use TheGame\Application\Component\ResourceStorage\Bridge\ResourceAvailabilityCheckerInterface; use TheGame\Application\SharedKernel\Domain\BuildingType; use TheGame\Application\SharedKernel\Domain\PlanetId; @@ -23,7 +23,7 @@ public function __construct( private readonly ResourceAvailabilityCheckerInterface $resourceAvailabilityChecker, private readonly BuildingRepositoryInterface $buildingRepository, private readonly BuildingContextInterface $buildingBalanceContext, - private readonly BuildingFactory $buildingFactory, + private readonly BuildingFactoryInterface $buildingFactory, private readonly EventBusInterface $eventBus, ) { } @@ -43,12 +43,12 @@ public function __invoke(StartConstructingCommand $command): void ); } + $resourceRequirements = $this->buildingBalanceContext->getResourceRequirements( + $building->getCurrentLevel(), + $building->getType(), + ); $hasEnoughResources = $this->resourceAvailabilityChecker->check( - $planetId, - $this->buildingBalanceContext->getResourceRequirements( - $building->getCurrentLevel(), - $building->getType(), - ), + $planetId, $resourceRequirements, ); if ($hasEnoughResources === false) { @@ -62,10 +62,6 @@ public function __invoke(StartConstructingCommand $command): void $buildingFinishDate = new DateTimeImmutable(sprintf("now + %d seconds", $buildingDuration)); $building->startUpgrading($buildingFinishDate); - $resourceRequirements = $this->buildingBalanceContext->getResourceRequirements( - $building->getCurrentLevel(), - $building->getType() - ); $event = new BuildingConstructionHasBeenStartedEvent( $command->getPlanetId(), $command->getBuildingType(), diff --git a/src/Application/Component/BuildingConstruction/Domain/Entity/Building.php b/src/Application/Component/BuildingConstruction/Domain/Entity/Building.php index 67a3069..ebe2303 100644 --- a/src/Application/Component/BuildingConstruction/Domain/Entity/Building.php +++ b/src/Application/Component/BuildingConstruction/Domain/Entity/Building.php @@ -20,13 +20,13 @@ class Building private bool $duringUpgrade = false; - private ?DateTimeInterface $finishUpgradeAt; + private ?DateTimeInterface $finishUpgradeAt = null; public function __construct( protected readonly PlanetIdInterface $planetId, protected readonly BuildingIdInterface $buildingId, protected readonly BuildingType $type, - protected readonly ResourceIdInterface $resourceContextId, + protected readonly ?ResourceIdInterface $resourceContextId = null, ) { } @@ -98,7 +98,7 @@ public function finishUpgrading(): void $this->currentLevel++; } - public function getResourceContextId(): ResourceIdInterface + public function getResourceContextId(): ?ResourceIdInterface { return $this->resourceContextId; } diff --git a/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactory.php b/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactory.php index 45d6d32..5446fdb 100644 --- a/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactory.php +++ b/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactory.php @@ -9,11 +9,10 @@ use TheGame\Application\Component\BuildingConstruction\Domain\Event\ResourceMineConstructionHasBeenFinishedEvent; use TheGame\Application\Component\BuildingConstruction\Domain\Event\ResourceStorageConstructionHasBeenFinishedEvent; use TheGame\Application\SharedKernel\Domain\BuildingType; -use TheGame\Application\SharedKernel\EventInterface; -final class BuildingTypeEventFactory +final class BuildingTypeEventFactory implements BuildingTypeEventFactoryInterface { - public function createConstructingFinishedEvent(Building $building): EventInterface + public function createConstructingFinishedEvent(Building $building): BuildingConstructionHasBeenFinishedEvent { $type = $building->getType(); switch ($type) { diff --git a/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactoryInterface.php b/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactoryInterface.php new file mode 100644 index 0000000..74c3a65 --- /dev/null +++ b/src/Application/Component/BuildingConstruction/Domain/Event/Factory/BuildingTypeEventFactoryInterface.php @@ -0,0 +1,13 @@ +