diff --git a/src/product/Application/BillingRegistryService.php b/src/product/Application/BillingRegistryService.php new file mode 100644 index 00000000..8897a7fb --- /dev/null +++ b/src/product/Application/BillingRegistryService.php @@ -0,0 +1,166 @@ +registry->priceTypes() as $priceTypeDefinition) { + foreach ($priceTypeDefinition->documentRepresentation() as $representation) { + if ($representation instanceof $representationClass) { + $representations[] = $representation; + } + } + } + + return $representations; + } + + public function createQuantityFormatter(string $type, FractionQuantityData $data): QuantityFormatterInterface { + $type = $this->convertStringTypeToType($type); + + foreach ($this->registry->priceTypes() as $priceTypeDefinition) { + if ($priceTypeDefinition->hasType($type)) { + return $priceTypeDefinition->createQuantityFormatter($data); + } + } + + throw new QuantityFormatterNotFoundException('Quantity formatter not found'); + } + + private function convertStringTypeToType(string $type): TypeInterface + { + return Type::anyId($type); + } + + public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface + { + if (!class_exists($behaviorClassWrapper)) { + throw new InvalidBehaviorException( + sprintf('Behavior class "%s" does not exist', $behaviorClassWrapper) + ); + } + + if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) { + throw new InvalidBehaviorException( + sprintf('Behavior class "%s" does not implement BehaviorInterface', $behaviorClassWrapper) + ); + } + + $billingType = $this->convertStringTypeToType($type); + + foreach ($this->registry->priceTypes() as $priceTypeDefinition) { + if ($priceTypeDefinition->hasType($billingType)) { + $behavior = $this->findBehaviorInPriceType($priceTypeDefinition, $behaviorClassWrapper); + + if ($behavior) { + return $behavior; + } + } + } + + throw new BehaviorNotFoundException( + sprintf('Behavior of class "%s" not found for type "%s"', $behaviorClassWrapper, $type), + ); + } + + private function findBehaviorInPriceType( + PriceTypeDefinitionInterface $priceTypeDefinition, + string $behaviorClassWrapper + ): ?BehaviorInterface { + foreach ($priceTypeDefinition->withBehaviors() as $behavior) { + if ($behavior instanceof $behaviorClassWrapper) { + return $behavior; + } + } + + return null; + } + + public function getBehaviors(string $behaviorClassWrapper): \Generator + { + foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) { + foreach ($tariffTypeDefinition->withBehaviors() as $behavior) { + if ($behavior instanceof $behaviorClassWrapper) { + yield $behavior; + } + } + } + + foreach ($this->registry->priceTypes() as $priceTypeDefinition) { + foreach ($priceTypeDefinition->withBehaviors() as $behavior) { + if ($behavior instanceof $behaviorClassWrapper) { + yield $behavior; + } + } + } + } + + public function getAggregate(string $type): AggregateInterface + { + $type = $this->convertStringTypeToType($type); + + foreach ($this->registry->priceTypes() as $priceTypeDefinition) { + if ($priceTypeDefinition->hasType($type)) { + return $priceTypeDefinition->getAggregate(); + } + } + + throw new AggregateNotFoundException('Aggregate was not found'); + } + + public function findTariffTypeDefinitionByBehavior(BehaviorInterface $behavior): TariffTypeDefinitionInterface + { + $tariffType = $behavior->getTariffType(); + + foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) { + if ($tariffTypeDefinition->belongToTariffType($tariffType)) { + return $tariffTypeDefinition; + } + } + + throw new TariffTypeDefinitionNotFoundException('Tariff type definition was not found'); + } + + public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): \Generator + { + foreach ($this->registry->priceTypes() as $priceTypeDefinition) { + if ($priceTypeDefinition->hasBehavior($behaviorClassWrapper)) { + yield $priceTypeDefinition; + } + } + } +} diff --git a/src/product/Application/BillingRegistryServiceInterface.php b/src/product/Application/BillingRegistryServiceInterface.php new file mode 100644 index 00000000..5e2ccbc1 --- /dev/null +++ b/src/product/Application/BillingRegistryServiceInterface.php @@ -0,0 +1,54 @@ + + */ + public function getBehaviors(string $behaviorClassWrapper): Generator; + + public function getAggregate(string $type): AggregateInterface; + + public function findTariffTypeDefinitionByBehavior(BehaviorInterface $behavior): TariffTypeDefinitionInterface; + + /** + * Find all PriceTypeDefinition in registry by specified Behavior class. + * + * @param string $behaviorClassWrapper + * @return Generator + */ + public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): Generator; +} \ No newline at end of file diff --git a/src/product/BillingRegistry.php b/src/product/BillingRegistry.php index 18c5e2f1..4856128e 100644 --- a/src/product/BillingRegistry.php +++ b/src/product/BillingRegistry.php @@ -2,19 +2,7 @@ namespace hiqdev\php\billing\product; -use hiqdev\php\billing\product\behavior\InvalidBehaviorException; -use hiqdev\php\billing\product\Exception\AggregateNotFoundException; -use hiqdev\php\billing\product\invoice\InvalidRepresentationException; -use hiqdev\php\billing\product\invoice\RepresentationInterface; -use hiqdev\php\billing\product\price\PriceTypeDefinition; -use hiqdev\php\billing\product\quantity\QuantityFormatterInterface; -use hiqdev\php\billing\product\quantity\QuantityFormatterNotFoundException; -use hiqdev\php\billing\product\quantity\FractionQuantityData; -use hiqdev\php\billing\product\behavior\BehaviorInterface; -use hiqdev\php\billing\product\behavior\BehaviorNotFoundException; use hiqdev\php\billing\product\trait\HasLock; -use hiqdev\php\billing\type\Type; -use hiqdev\php\billing\type\TypeInterface; class BillingRegistry implements BillingRegistryInterface { @@ -22,7 +10,6 @@ class BillingRegistry implements BillingRegistryInterface /** @var TariffTypeDefinitionInterface[] */ private array $tariffTypeDefinitions = []; - private bool $locked = false; public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void { @@ -31,140 +18,18 @@ public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinitio $this->tariffTypeDefinitions[] = $tariffTypeDefinition; } - public function priceTypes(): \Generator - { - foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) { - foreach ($tariffTypeDefinition->withPrices() as $priceTypeDefinition) { - yield $priceTypeDefinition; - } - } - } - - public function getRepresentationsByType(string $representationClass): array - { - if (!class_exists($representationClass)) { - throw new InvalidRepresentationException("Class '$representationClass' does not exist"); - } - - if (!is_subclass_of($representationClass, RepresentationInterface::class)) { - throw new InvalidBehaviorException( - sprintf('Representation class "%s" does not implement RepresentationInterface', $representationClass) - ); - } - - $representations = []; - foreach ($this->priceTypes() as $priceTypeDefinition) { - foreach ($priceTypeDefinition->documentRepresentation() as $representation) { - if ($representation instanceof $representationClass) { - $representations[] = $representation; - } - } - } - - return $representations; - } - - public function createQuantityFormatter( - string $type, - FractionQuantityData $data, - ): QuantityFormatterInterface { - $type = $this->convertStringTypeToType($type); - - foreach ($this->priceTypes() as $priceTypeDefinition) { - if ($priceTypeDefinition->hasType($type)) { - return $priceTypeDefinition->createQuantityFormatter($data); - } - } - - throw new QuantityFormatterNotFoundException('Quantity formatter not found'); - } - - private function convertStringTypeToType(string $type): TypeInterface - { - return Type::anyId($type); - } - - public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface - { - if (!class_exists($behaviorClassWrapper)) { - throw new InvalidBehaviorException( - sprintf('Behavior class "%s" does not exist', $behaviorClassWrapper) - ); - } - - if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) { - throw new InvalidBehaviorException( - sprintf('Behavior class "%s" does not implement BehaviorInterface', $behaviorClassWrapper) - ); - } - - $billingType = $this->convertStringTypeToType($type); - - foreach ($this->priceTypes() as $priceTypeDefinition) { - if ($priceTypeDefinition->hasType($billingType)) { - $behavior = $this->findBehaviorInPriceType($priceTypeDefinition, $behaviorClassWrapper); - - if ($behavior) { - return $behavior; - } - } - } - - throw new BehaviorNotFoundException( - sprintf('Behavior of class "%s" not found for type "%s"', $behaviorClassWrapper, $type), - ); - } - - private function findBehaviorInPriceType( - PriceTypeDefinition $priceTypeDefinition, - string $behaviorClassWrapper - ): ?BehaviorInterface { - foreach ($priceTypeDefinition->withBehaviors() as $behavior) { - if ($behavior instanceof $behaviorClassWrapper) { - return $behavior; - } - } - - return null; - } - - public function getBehaviors(string $behaviorClassWrapper): \Generator + public function getTariffTypeDefinitions(): array { - foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) { - foreach ($tariffTypeDefinition->withBehaviors() as $behavior) { - if ($behavior instanceof $behaviorClassWrapper) { - yield $behavior; - } - } - } - - foreach ($this->priceTypes() as $priceTypeDefinition) { - foreach ($priceTypeDefinition->withBehaviors() as $behavior) { - if ($behavior instanceof $behaviorClassWrapper) { - yield $behavior; - } - } - } + return $this->tariffTypeDefinitions; } - public function getAggregate(string $type): AggregateInterface + public function priceTypes(): \Generator { - $type = $this->convertStringTypeToType($type); - - foreach ($this->priceTypes() as $priceTypeDefinition) { - if ($priceTypeDefinition->hasType($type)) { - return $priceTypeDefinition->getAggregate(); + foreach ($this->getTariffTypeDefinitions() as $tariffTypeDefinition) { + foreach ($tariffTypeDefinition->withPrices() as $priceTypeDefinition) { + yield $priceTypeDefinition; } } - - throw new AggregateNotFoundException('Aggregate was not found'); - } - - public function getTariffTypeDefinitions(): \Generator - { - foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) { - yield $tariffTypeDefinition; - } } protected function afterLock(): void diff --git a/src/product/BillingRegistryInterface.php b/src/product/BillingRegistryInterface.php index 908984df..38885f93 100644 --- a/src/product/BillingRegistryInterface.php +++ b/src/product/BillingRegistryInterface.php @@ -3,54 +3,17 @@ namespace hiqdev\php\billing\product; use Generator; -use hiqdev\php\billing\product\behavior\BehaviorInterface; -use hiqdev\php\billing\product\behavior\BehaviorNotFoundException; -use hiqdev\php\billing\product\behavior\InvalidBehaviorException; -use hiqdev\php\billing\product\invoice\RepresentationInterface; use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface; -use hiqdev\php\billing\product\quantity\FractionQuantityData; -use hiqdev\php\billing\product\quantity\QuantityFormatterInterface; use hiqdev\php\billing\product\trait\HasLockInterface; interface BillingRegistryInterface extends HasLockInterface { /** - * @return Generator - * @psalm-return Generator + * @return Generator */ public function priceTypes(): Generator; - public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void; - - /** - * @param string $representationClass - * @return RepresentationInterface[] - */ - public function getRepresentationsByType(string $representationClass): array; - - public function createQuantityFormatter(string $type, FractionQuantityData $data): QuantityFormatterInterface; - - /** - * @param string $type - full type like 'overuse,lb_capacity_unit' - * @param string $behaviorClassWrapper - * @return BehaviorInterface - * @throws BehaviorNotFoundException - * @throws InvalidBehaviorException - */ - public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface; + public function getTariffTypeDefinitions(): array; - /** - * @param string $behaviorClassWrapper - * @return Generator - * @psalm-return Generator - */ - public function getBehaviors(string $behaviorClassWrapper): Generator; - - public function getAggregate(string $type): AggregateInterface; - - /** - * @return Generator - * @psalm-return Generator - */ - public function getTariffTypeDefinitions(): Generator; + public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void; } diff --git a/src/product/Domain/Model/TariffTypeInterface.php b/src/product/Domain/Model/TariffTypeInterface.php index a5ec5faa..0e9ee03d 100644 --- a/src/product/Domain/Model/TariffTypeInterface.php +++ b/src/product/Domain/Model/TariffTypeInterface.php @@ -7,4 +7,8 @@ interface TariffTypeInterface public function name(): string; public function label(): string; + + public function equals(TariffTypeInterface $tariffType): bool; + + public function equalsName(string $tariffTypeName): bool; } diff --git a/src/product/Domain/Model/Unit/UnitInterface.php b/src/product/Domain/Model/Unit/UnitInterface.php index 116d048b..ce02a585 100644 --- a/src/product/Domain/Model/Unit/UnitInterface.php +++ b/src/product/Domain/Model/Unit/UnitInterface.php @@ -6,6 +6,8 @@ interface UnitInterface { + public function name(): string; + public function createExternalUnit(): BaseUnitInterface; public function fractionUnit(): FractionUnitInterface; diff --git a/src/product/TariffTypeDefinition.php b/src/product/TariffTypeDefinition.php index 8e17fa47..d4b8b33b 100644 --- a/src/product/TariffTypeDefinition.php +++ b/src/product/TariffTypeDefinition.php @@ -10,6 +10,9 @@ use hiqdev\php\billing\product\price\PriceTypeDefinitionFactory; use hiqdev\php\billing\product\trait\HasLock; +/** + * @implements TariffTypeDefinitionInterface + */ class TariffTypeDefinition implements TariffTypeDefinitionInterface { use HasLock; @@ -31,6 +34,11 @@ public function tariffType(): TariffTypeInterface return $this->tariffType; } + public function belongToTariffType(TariffTypeInterface $tariffType): bool + { + return $this->tariffType->equals($tariffType); + } + public function ofProduct(ProductInterface $product): TariffTypeDefinitionInterface { $this->ensureNotLocked(); diff --git a/src/product/TariffTypeDefinitionInterface.php b/src/product/TariffTypeDefinitionInterface.php index f9c092e9..f52e978a 100644 --- a/src/product/TariffTypeDefinitionInterface.php +++ b/src/product/TariffTypeDefinitionInterface.php @@ -14,6 +14,14 @@ interface TariffTypeDefinitionInterface extends HasBehaviorsInterface, HasLockIn { public function tariffType(): TariffTypeInterface; + /** + * Check if TariffTypeDefinition belongs to specified TariffType + * + * @param TariffTypeInterface $tariffType + * @return bool + */ + public function belongToTariffType(TariffTypeInterface $tariffType): bool; + public function ofProduct(ProductInterface $product): self; public function getProduct(): ProductInterface; diff --git a/src/product/behavior/BehaviorCollectionInterface.php b/src/product/behavior/BehaviorCollectionInterface.php index 6954828e..14c9ca81 100644 --- a/src/product/behavior/BehaviorCollectionInterface.php +++ b/src/product/behavior/BehaviorCollectionInterface.php @@ -5,13 +5,18 @@ use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface; use hiqdev\php\billing\product\TariffTypeDefinitionInterface; use hiqdev\php\billing\product\trait\HasLockInterface; +use IteratorAggregate; +use Traversable; -interface BehaviorCollectionInterface extends \IteratorAggregate, HasLockInterface +/** + * @extends IteratorAggregate + */ +interface BehaviorCollectionInterface extends IteratorAggregate, HasLockInterface { /** - * @return BehaviorInterface[] + * @return Traversable */ - public function getIterator(): \Traversable; + public function getIterator(): Traversable; public function attach(BehaviorInterface $behavior): self; diff --git a/src/product/invoice/RepresentationCollection.php b/src/product/invoice/RepresentationCollection.php index a3b9e75c..81990d0c 100644 --- a/src/product/invoice/RepresentationCollection.php +++ b/src/product/invoice/RepresentationCollection.php @@ -5,11 +5,14 @@ use hiqdev\php\billing\product\price\PriceTypeDefinition; use hiqdev\php\billing\product\trait\HasLock; use hiqdev\php\billing\product\trait\HasLockInterface; +use IteratorAggregate; +use Traversable; /** * @template T of PriceTypeDefinition + * @implements IteratorAggregate */ -class RepresentationCollection implements \IteratorAggregate, HasLockInterface +class RepresentationCollection implements IteratorAggregate, HasLockInterface { use HasLock; @@ -23,9 +26,9 @@ public function __construct(private readonly PriceTypeDefinition $priceTypeDefin } /** - * @return RepresentationInterface[] + * @return Traversable */ - public function getIterator(): \Traversable + public function getIterator(): Traversable { return new \ArrayIterator($this->representations); } diff --git a/src/product/measure/TrafCollectorInterface.php b/src/product/measure/TrafCollectorInterface.php new file mode 100644 index 00000000..6f0f3f3c --- /dev/null +++ b/src/product/measure/TrafCollectorInterface.php @@ -0,0 +1,21 @@ +representationCollection; } - public function measuredWith(\hiqdev\billing\registry\measure\RcpTrafCollector $param): self + public function measuredWith(TrafCollectorInterface $collector): self { $this->ensureNotLocked(); + // Not completed yet, only for implementing the interface purpose + return $this; } @@ -198,4 +202,14 @@ protected function afterLock(): void $this->representationCollection->lock(); $this->behaviorCollection->lock(); } + + public function getTariffTypeDefinition(): TariffTypeDefinitionInterface + { + return $this->parent->getTariffTypeDefinition(); + } + + public function belongsToTariffType(string $tariffTypeName): bool + { + return $this->getTariffTypeDefinition()->tariffType()->equalsName($tariffTypeName); + } } diff --git a/src/product/price/PriceTypeDefinitionCollection.php b/src/product/price/PriceTypeDefinitionCollection.php index e6e89e28..a978c2a9 100644 --- a/src/product/price/PriceTypeDefinitionCollection.php +++ b/src/product/price/PriceTypeDefinitionCollection.php @@ -46,10 +46,6 @@ public function priceType(TypeInterface $type): PriceTypeDefinitionInterface return $priceType; } - /** - * @return TariffTypeDefinitionInterface - * @plsam-return M - */ public function end(): TariffTypeDefinitionInterface { return $this->parent; @@ -59,4 +55,9 @@ public function count(): int { return $this->storage->count(); } + + public function getTariffTypeDefinition(): TariffTypeDefinitionInterface + { + return $this->parent; + } } diff --git a/src/product/price/PriceTypeDefinitionCollectionInterface.php b/src/product/price/PriceTypeDefinitionCollectionInterface.php index e7ab0535..637fbfc8 100644 --- a/src/product/price/PriceTypeDefinitionCollectionInterface.php +++ b/src/product/price/PriceTypeDefinitionCollectionInterface.php @@ -5,15 +5,33 @@ use hiqdev\php\billing\product\TariffTypeDefinitionInterface; use hiqdev\php\billing\product\trait\HasLockInterface; use hiqdev\php\billing\type\TypeInterface; +use IteratorAggregate; +use Traversable; -interface PriceTypeDefinitionCollectionInterface extends \IteratorAggregate, \Countable, HasLockInterface +/** + * @extends IteratorAggregate + */ +interface PriceTypeDefinitionCollectionInterface extends IteratorAggregate, \Countable, HasLockInterface { /** - * @return PriceTypeDefinitionInterface[] + * @return Traversable */ - public function getIterator(): \Traversable; + public function getIterator(): Traversable; public function priceType(TypeInterface $type): PriceTypeDefinitionInterface; + /** + * @return TariffTypeDefinitionInterface + * @plsam-return M + */ public function end(): TariffTypeDefinitionInterface; -} \ No newline at end of file + + /** + * For easier understanding and establishing a relationship between PriceTypeDefinitionCollection + * and TariffTypeDefinition + * + * @return TariffTypeDefinitionInterface + * @plsam-return M + */ + public function getTariffTypeDefinition(): TariffTypeDefinitionInterface; +} diff --git a/src/product/price/PriceTypeDefinitionInterface.php b/src/product/price/PriceTypeDefinitionInterface.php index 10eefc68..860031ce 100644 --- a/src/product/price/PriceTypeDefinitionInterface.php +++ b/src/product/price/PriceTypeDefinitionInterface.php @@ -6,8 +6,10 @@ use hiqdev\php\billing\product\behavior\HasBehaviorsInterface; use hiqdev\php\billing\product\Domain\Model\Unit\UnitInterface; use hiqdev\php\billing\product\invoice\RepresentationCollection; +use hiqdev\php\billing\product\measure\TrafCollectorInterface; use hiqdev\php\billing\product\quantity\FractionQuantityData; use hiqdev\php\billing\product\quantity\QuantityFormatterInterface; +use hiqdev\php\billing\product\TariffTypeDefinitionInterface; use hiqdev\php\billing\product\trait\HasLockInterface; use hiqdev\php\billing\type\TypeInterface; @@ -27,8 +29,7 @@ public function end(): PriceTypeDefinitionCollectionInterface; public function documentRepresentation(): RepresentationCollection; - // TODO: Not sure if it will be needed at all - public function measuredWith(\hiqdev\billing\registry\measure\RcpTrafCollector $param): self; + public function measuredWith(TrafCollectorInterface $collector): self; public function type(): TypeInterface; @@ -46,4 +47,13 @@ public function getUnit(): UnitInterface; public function aggregation(AggregateInterface $aggregate): self; public function getAggregate(): AggregateInterface; + + /** + * For establishing a relationship between PriceTypeDefinition and TariffTypeDefinition + * + * @return TariffTypeDefinitionInterface + */ + public function getTariffTypeDefinition(): TariffTypeDefinitionInterface; + + public function belongsToTariffType(string $tariffTypeName): bool; } diff --git a/tests/unit/product/Application/BillingRegistryServiceTest.php b/tests/unit/product/Application/BillingRegistryServiceTest.php new file mode 100644 index 00000000..0d88e210 --- /dev/null +++ b/tests/unit/product/Application/BillingRegistryServiceTest.php @@ -0,0 +1,147 @@ +registry = new BillingRegistry(); + $this->registryService = new BillingRegistryService($this->registry); + } + + public function testGetRepresentationsByTypeThrowsOnInvalidClass(): void + { + $this->expectException(InvalidRepresentationException::class); + $this->registryService->getRepresentationsByType('InvalidClass'); + } + + public function testGetAggregateThrowsExceptionWhenNotFound(): void + { + $this->expectException(AggregateNotFoundException::class); + $this->registryService->getAggregate('non-existent-type'); + } + + public function testGetBehavior(): void + { + $tariffType = new DummyTariffType(); + $tariffTypeDefinition = new TariffTypeDefinition($tariffType); + $dummyBehavior = new TestBehavior('dummy'); + $type = Type::anyId('dummy'); + $tariffTypeDefinition + ->withPrices() + ->priceType($type) + ->withBehaviors() + ->attach($dummyBehavior); + + $this->registry->addTariffType($tariffTypeDefinition); + + $behavior = $this->registryService->getBehavior($type->getName(), TestBehavior::class); + + $this->assertSame($dummyBehavior->getContext(), $behavior->getContext()); + } + + public function testGetBehavior_WithMultipleTariffTypeDefinitions(): void + { + $tariffType = new DummyTariffType(); + $tariffTypeDefinition = new TariffTypeDefinition($tariffType); + $type1 = Type::anyId('type,dummy1'); + $type2 = Type::anyId('type,dummy2'); + $dummyBehavior1 = new TestBehavior('dummy 1'); + $dummyBehavior2 = new TestBehavior('dummy 2'); + $dummyBehavior3 = new FakeBehavior('dummy 3'); + + $tariffTypeDefinition + ->withPrices() + ->priceType($type1) + ->withBehaviors() + ->attach($dummyBehavior1) + ->end() + ->end() + ->priceType($type2) + ->withBehaviors() + ->attach($dummyBehavior2) + ->attach($dummyBehavior3) + ->end() + ->end() + ->end(); + + $this->registry->addTariffType($tariffTypeDefinition); + + $behavior = $this->registryService->getBehavior($type1->getName(), TestBehavior::class); + $this->assertSame($dummyBehavior1->getContext(), $behavior->getContext()); + + $behavior = $this->registryService->getBehavior($type2->getName(), TestBehavior::class); + $this->assertSame($dummyBehavior2->getContext(), $behavior->getContext()); + + $behavior = $this->registryService->getBehavior($type2->getName(), FakeBehavior::class); + $this->assertSame($dummyBehavior3->getContext(), $behavior->getContext()); + } + + public function testGetBehavior_WithMultiplePriceTypeDefinitions(): void + { + $tariffTypeDefinition1 = new TariffTypeDefinition(new DummyTariffType()); + $testBehavior = new TestBehavior('dummy'); + $type1 = Type::anyId('type,dummy1'); + $tariffTypeDefinition1 + ->withPrices() + ->priceType($type1) + ->withBehaviors() + ->attach($testBehavior) + ->end() + ->end() + ->end(); + + $tariffTypeDefinition2 = new TariffTypeDefinition(new FakeTariffType()); + $fakeBehavior = new FakeBehavior('dummy'); + $type2 = Type::anyId('type,dummy2'); + $tariffTypeDefinition2 + ->withPrices() + ->priceType($type2) + ->withBehaviors() + ->attach($fakeBehavior) + ->end() + ->end() + ->end(); + + $this->registry->addTariffType($tariffTypeDefinition1); + $this->registry->addTariffType($tariffTypeDefinition2); + + /** @var TestBehavior $testBehaviorActual */ + $testBehaviorActual = $this->registryService->getBehavior($type1->getName(), TestBehavior::class); + $this->assertSame($testBehavior->getContext(), $testBehaviorActual->getContext()); + + /** @var FakeBehavior $fakeBehaviorActual */ + $fakeBehaviorActual = $this->registryService->getBehavior($type2->getName(), FakeBehavior::class); + $this->assertSame($fakeBehavior->getContext(), $fakeBehaviorActual->getContext()); + } + + public function testGetBehaviorThrowsExceptionWhenNotFound(): void + { + $this->expectException(BehaviorNotFoundException::class); + $this->registryService->getBehavior('non-existent-type', TestBehavior::class); + } + + // public function testCreateQuantityFormatterThrowsExceptionWhenNotFound(): void +// { +// $this->expectException(QuantityFormatterNotFoundException::class); +// $this->registryService->createQuantityFormatter('non-existent-type', $this->createMock(FractionQuantityData::class)); +// } +} diff --git a/tests/unit/product/BillingRegistryTest.php b/tests/unit/product/BillingRegistryTest.php index 443d86ab..16885710 100644 --- a/tests/unit/product/BillingRegistryTest.php +++ b/tests/unit/product/BillingRegistryTest.php @@ -7,13 +7,7 @@ use hiqdev\php\billing\product\price\PriceTypeDefinition; use hiqdev\php\billing\product\TariffTypeDefinition; use hiqdev\php\billing\product\TariffTypeDefinitionInterface; -use hiqdev\php\billing\product\Exception\AggregateNotFoundException; -use hiqdev\php\billing\product\invoice\InvalidRepresentationException; -use hiqdev\php\billing\product\behavior\BehaviorNotFoundException; -use hiqdev\php\billing\tests\unit\product\behavior\FakeBehavior; -use hiqdev\php\billing\tests\unit\product\behavior\TestBehavior; use hiqdev\php\billing\tests\unit\product\Domain\Model\DummyTariffType; -use hiqdev\php\billing\tests\unit\product\Domain\Model\FakeTariffType; use hiqdev\php\billing\type\Type; use PHPUnit\Framework\TestCase; @@ -55,122 +49,4 @@ public function testLockPreventsModification(): void $this->registry->addTariffType($this->tariffTypeDefinition); } - - public function testGetRepresentationsByTypeThrowsOnInvalidClass(): void - { - $this->expectException(InvalidRepresentationException::class); - $this->registry->getRepresentationsByType('InvalidClass'); - } - - public function testGetAggregateThrowsExceptionWhenNotFound(): void - { - $this->expectException(AggregateNotFoundException::class); - $this->registry->getAggregate('non-existent-type'); - } - - public function testGetBehavior(): void - { - $tariffType = new DummyTariffType(); - $tariffTypeDefinition = new TariffTypeDefinition($tariffType); - $dummyBehavior = new TestBehavior('dummy'); - $type = Type::anyId('dummy'); - $tariffTypeDefinition - ->withPrices() - ->priceType($type) - ->withBehaviors() - ->attach($dummyBehavior); - - $this->registry->addTariffType($tariffTypeDefinition); - - $behavior = $this->registry->getBehavior($type->getName(), TestBehavior::class); - - $this->assertSame($dummyBehavior->getContext(), $behavior->getContext()); - } - - public function testGetBehavior_WithMultipleTariffTypeDefinitions(): void - { - $tariffType = new DummyTariffType(); - $tariffTypeDefinition = new TariffTypeDefinition($tariffType); - $type1 = Type::anyId('type,dummy1'); - $type2 = Type::anyId('type,dummy2'); - $dummyBehavior1 = new TestBehavior('dummy 1'); - $dummyBehavior2 = new TestBehavior('dummy 2'); - $dummyBehavior3 = new FakeBehavior('dummy 3'); - - $tariffTypeDefinition - ->withPrices() - ->priceType($type1) - ->withBehaviors() - ->attach($dummyBehavior1) - ->end() - ->end() - ->priceType($type2) - ->withBehaviors() - ->attach($dummyBehavior2) - ->attach($dummyBehavior3) - ->end() - ->end() - ->end(); - - $this->registry->addTariffType($tariffTypeDefinition); - - $behavior = $this->registry->getBehavior($type1->getName(), TestBehavior::class); - $this->assertSame($dummyBehavior1->getContext(), $behavior->getContext()); - - $behavior = $this->registry->getBehavior($type2->getName(), TestBehavior::class); - $this->assertSame($dummyBehavior2->getContext(), $behavior->getContext()); - - $behavior = $this->registry->getBehavior($type2->getName(), FakeBehavior::class); - $this->assertSame($dummyBehavior3->getContext(), $behavior->getContext()); - } - - public function testGetBehavior_WithMultiplePriceTypeDefinitions(): void - { - $tariffTypeDefinition1 = new TariffTypeDefinition(new DummyTariffType()); - $testBehavior = new TestBehavior('dummy'); - $type1 = Type::anyId('type,dummy1'); - $tariffTypeDefinition1 - ->withPrices() - ->priceType($type1) - ->withBehaviors() - ->attach($testBehavior) - ->end() - ->end() - ->end(); - - $tariffTypeDefinition2 = new TariffTypeDefinition(new FakeTariffType()); - $fakeBehavior = new FakeBehavior('dummy'); - $type2 = Type::anyId('type,dummy2'); - $tariffTypeDefinition2 - ->withPrices() - ->priceType($type2) - ->withBehaviors() - ->attach($fakeBehavior) - ->end() - ->end() - ->end(); - - $this->registry->addTariffType($tariffTypeDefinition1); - $this->registry->addTariffType($tariffTypeDefinition2); - - /** @var TestBehavior $testBehaviorActual */ - $testBehaviorActual = $this->registry->getBehavior($type1->getName(), TestBehavior::class); - $this->assertSame($testBehavior->getContext(), $testBehaviorActual->getContext()); - - /** @var FakeBehavior $fakeBehaviorActual */ - $fakeBehaviorActual = $this->registry->getBehavior($type2->getName(), FakeBehavior::class); - $this->assertSame($fakeBehavior->getContext(), $fakeBehaviorActual->getContext()); - } - - public function testGetBehaviorThrowsExceptionWhenNotFound(): void - { - $this->expectException(BehaviorNotFoundException::class); - $this->registry->getBehavior('non-existent-type', TestBehavior::class); - } - -// public function testCreateQuantityFormatterThrowsExceptionWhenNotFound(): void -// { -// $this->expectException(QuantityFormatterNotFoundException::class); -// $this->registry->createQuantityFormatter('non-existent-type', $this->createMock(FractionQuantityData::class)); -// } } diff --git a/tests/unit/product/Domain/Model/DummyTariffType.php b/tests/unit/product/Domain/Model/DummyTariffType.php index 87b56ae4..0e6e086e 100644 --- a/tests/unit/product/Domain/Model/DummyTariffType.php +++ b/tests/unit/product/Domain/Model/DummyTariffType.php @@ -2,9 +2,7 @@ namespace hiqdev\php\billing\tests\unit\product\Domain\Model; -use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface; - -class DummyTariffType implements TariffTypeInterface +class DummyTariffType extends TariffType { public function name(): string { diff --git a/tests/unit/product/Domain/Model/FakeTariffType.php b/tests/unit/product/Domain/Model/FakeTariffType.php index b74d9892..9894152c 100644 --- a/tests/unit/product/Domain/Model/FakeTariffType.php +++ b/tests/unit/product/Domain/Model/FakeTariffType.php @@ -2,9 +2,7 @@ namespace hiqdev\php\billing\tests\unit\product\Domain\Model; -use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface; - -class FakeTariffType implements TariffTypeInterface +class FakeTariffType extends TariffType { public function name(): string { diff --git a/tests/unit/product/Domain/Model/MockTariffType.php b/tests/unit/product/Domain/Model/MockTariffType.php index 3a066322..38511ece 100644 --- a/tests/unit/product/Domain/Model/MockTariffType.php +++ b/tests/unit/product/Domain/Model/MockTariffType.php @@ -2,9 +2,7 @@ namespace hiqdev\php\billing\tests\unit\product\Domain\Model; -use hiqdev\php\billing\product\Domain\Model\TariffTypeInterface; - -class MockTariffType implements TariffTypeInterface +class MockTariffType extends TariffType { public function name(): string { diff --git a/tests/unit/product/Domain/Model/TariffType.php b/tests/unit/product/Domain/Model/TariffType.php new file mode 100644 index 00000000..143bb85a --- /dev/null +++ b/tests/unit/product/Domain/Model/TariffType.php @@ -0,0 +1,18 @@ +name() === $tariffType->name(); + } + + public function equalsName(string $tariffTypeName): bool + { + return $this->name() === $tariffTypeName; + } +}