Skip to content

Commit

Permalink
[#32] create and test ChainFeatureRepository
Browse files Browse the repository at this point in the history
  • Loading branch information
kpicaza committed Oct 10, 2021
1 parent 4fc0b87 commit 955f0ac
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 5 deletions.
47 changes: 47 additions & 0 deletions src/Write/ChainFeatureRepository.php
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Pheature\Core\Toggle\Write;

use InvalidArgumentException;

final class ChainFeatureRepository implements FeatureRepository
{
/** @var FeatureRepository[] */
private array $featureRepositories;

public function __construct(FeatureRepository ...$featureRepositories)
{
$this->featureRepositories = $featureRepositories;
}

public function save(Feature $feature): void
{
foreach ($this->featureRepositories as $featureRepository) {
$featureRepository->save($feature);
}
}

public function remove(Feature $feature): void
{
foreach ($this->featureRepositories as $featureRepository) {
$featureRepository->remove($feature);
}
}

public function get(FeatureId $featureId): Feature
{
foreach ($this->featureRepositories as $featureRepository) {
try {
$feature = $featureRepository->get($featureId);
} catch (InvalidArgumentException $exception) {
continue;
}

return $feature;
}

throw new InvalidArgumentException(sprintf('Feature with id %s not found.', $featureId->value()));
}
}
2 changes: 1 addition & 1 deletion src/Write/Payload.php
Expand Up @@ -37,7 +37,7 @@ public static function fromJsonString(string $jsonPayload): self
*/
$payload = json_decode($jsonPayload, true, 16, JSON_THROW_ON_ERROR);

return new self($payload);
return self::fromArray($payload);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Write/Strategy.php
Expand Up @@ -62,8 +62,8 @@ public function jsonSerialize(): array
{
return [
'strategy_id' => $this->strategyId->value(),
'strategy_type' => $this->strategyType->value(),
'segments' => array_map(static fn(Segment $segment) => $segment->jsonSerialize(), $this->segments),
'strategy_type' => $this->type()->value(),
'segments' => array_map(static fn(Segment $segment) => $segment->jsonSerialize(), $this->segments()),
];
}
}
4 changes: 2 additions & 2 deletions test/Read/ChainSegmentFactoryTest.php
Expand Up @@ -30,7 +30,7 @@ public function testItShouldThrowAnExceptionWhenItCantCreateAToggleStrategyType(
public function testItShouldBeCreatedWithAtLeastOneSegmentFactoryInstance(): void
{
$segmentFactory = $this->createMock(SegmentFactory::class);
$segmentFactory->expects(self::once())
$segmentFactory->expects(self::atLeastOnce())
->method('types')
->willReturn([self::SEGMENT_TYPE]);
$expectedSegment = $this->createMock(Segment::class);
Expand All @@ -43,6 +43,6 @@ public function testItShouldBeCreatedWithAtLeastOneSegmentFactoryInstance(): voi
$current = $chainSegmentFactory->create(self::SEGMENT_ID, self::SEGMENT_TYPE, self::PAYLOAD);

self::assertSame($expectedSegment, $current);
self::assertSame([self::SEGMENT_TYPE], $chainSegmentFactory->types());
}
}

112 changes: 112 additions & 0 deletions test/Write/ChainFeatureRepositoryTest.php
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace Pheature\Test\Core\Toggle\Write;

use InvalidArgumentException;
use Pheature\Core\Toggle\Write\ChainFeatureRepository;
use Pheature\Core\Toggle\Write\Feature;
use Pheature\Core\Toggle\Write\FeatureId;
use Pheature\Core\Toggle\Write\FeatureRepository;
use PHPUnit\Framework\TestCase;

final class ChainFeatureRepositoryTest extends TestCase
{
const FEATURE_ID = 'some_id';

public function testItShouldThrowExceptionGWhenFeatureDoesNotExistInAnyOfGivenFeatureRepositories(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Feature with id some_id not found.');
$firstRepository = $this->createMock(FeatureRepository::class);
$firstRepository->expects(static::once())
->method('get')
->with(static::isInstanceOf(FeatureId::class))
->willThrowException($this->createMock(InvalidArgumentException::class));
$secondRepository = $this->createMock(FeatureRepository::class);
$secondRepository->expects(static::once())
->method('get')
->with(static::isInstanceOf(FeatureId::class))
->willThrowException($this->createMock(InvalidArgumentException::class));

$chainFeatureRepository = new ChainFeatureRepository(
$firstRepository,
$secondRepository
);

$chainFeatureRepository->get(FeatureId::fromString(self::FEATURE_ID));
}

public function testItShouldCreateInstanceOfChainFeatureRepositoryAndGetSAFeatureFromGivenFeatureRepositories(): void
{
$feature = new Feature(
FeatureId::fromString(self::FEATURE_ID),
true
);
$firstRepository = $this->createMock(FeatureRepository::class);
$firstRepository->expects(static::once())
->method('get')
->with(static::isInstanceOf(FeatureId::class))
->willThrowException($this->createMock(InvalidArgumentException::class));
$secondRepository = $this->createMock(FeatureRepository::class);
$secondRepository->expects(static::once())
->method('get')
->with(static::isInstanceOf(FeatureId::class))
->willReturn($feature);

$chainFeatureRepository = new ChainFeatureRepository(
$firstRepository,
$secondRepository
);

$chainFeatureRepository->get(FeatureId::fromString(self::FEATURE_ID));
}

public function testItShouldCreateInstanceOfChainFeatureRepositoryAndSaveAFeatureInEveryGivenFeatureRepositories(): void
{
$feature = new Feature(
FeatureId::fromString(self::FEATURE_ID),
true
);
$firstRepository = $this->createMock(FeatureRepository::class);
$firstRepository->expects(static::once())
->method('save')
->with($feature);
$secondRepository = $this->createMock(FeatureRepository::class);
$secondRepository->expects(static::once())
->method('save')
->with($feature);

$chainFeatureRepository = new ChainFeatureRepository(
$firstRepository,
$secondRepository
);

$chainFeatureRepository->save($feature);
}

public function testItShouldCreateInstanceOfChainFeatureRepositoryAndRemoveAFeatureInEveryGivenFeatureRepositories(): void
{
$feature = new Feature(
FeatureId::fromString(self::FEATURE_ID),
true
);
$firstRepository = $this->createMock(FeatureRepository::class);
$firstRepository->expects(static::once())
->method('remove')
->with($feature);
$secondRepository = $this->createMock(FeatureRepository::class);
$secondRepository->expects(static::once())
->method('remove')
->with($feature);

$chainFeatureRepository = new ChainFeatureRepository(
$firstRepository,
$secondRepository
);

$chainFeatureRepository->remove($feature);
}
}

0 comments on commit 955f0ac

Please sign in to comment.