From b2dff692ef5d455e4efdfc80131307b08562ce62 Mon Sep 17 00:00:00 2001 From: Koldo Picaza <1093654+kpicaza@users.noreply.github.com> Date: Thu, 4 Nov 2021 22:11:00 +0100 Subject: [PATCH] [#17] Add StrategyWasAdded event --- src/Write/Event/StrategyWasAdded.php | 85 ++++++++++++++++++++++++++++ src/Write/Feature.php | 7 +++ src/Write/Payload.php | 21 ++----- src/Write/Segment.php | 6 +- src/Write/Strategy.php | 15 ++--- test/Write/FeatureTest.php | 30 +++++++++- 6 files changed, 136 insertions(+), 28 deletions(-) create mode 100644 src/Write/Event/StrategyWasAdded.php diff --git a/src/Write/Event/StrategyWasAdded.php b/src/Write/Event/StrategyWasAdded.php new file mode 100644 index 0000000..f7c947a --- /dev/null +++ b/src/Write/Event/StrategyWasAdded.php @@ -0,0 +1,85 @@ +featureId = $featureId; + $this->strategyId = $strategyId; + $this->strategyType = $strategyType; + $this->segments = $segments; + $this->occurredAt = $occurredAt; + } + + /** @param WriteSegment[] $segments */ + public static function occur(string $featureId, string $strategyId, string $strategyType, array $segments): self + { + return new self($featureId, $strategyId, $strategyType, $segments, new DatetimeImmutable()); + } + + public function featureId(): FeatureId + { + return FeatureId::fromString($this->featureId); + } + + public function strategyId(): StrategyId + { + return StrategyId::fromString($this->strategyId); + } + + public function strategyType(): StrategyType + { + return StrategyType::fromString($this->strategyType); + } + + public function occurredAt(): DatetimeImmutable + { + return $this->occurredAt; + } + + /** + * @return Segment[] + */ + public function segments(): array + { + return array_map( + static function (array $segment): Segment { + return new Segment( + SegmentId::fromString($segment['segment_id']), + SegmentType::fromString($segment['segment_type']), + Payload::fromArray($segment['criteria']) + ); + }, + $this->segments + ); + } +} diff --git a/src/Write/Feature.php b/src/Write/Feature.php index 044c322..716ae1e 100644 --- a/src/Write/Feature.php +++ b/src/Write/Feature.php @@ -9,6 +9,7 @@ use Pheature\Core\Toggle\Write\Event\FeatureWasCreated; use JsonSerializable; use Pheature\Core\Toggle\Write\Event\FeatureWasRemoved; +use Pheature\Core\Toggle\Write\Event\StrategyWasAdded; use Pheature\Core\Toggle\Write\Event\StrategyWasRemoved; use function array_map; @@ -61,6 +62,12 @@ public static function withId(FeatureId $featureId): self public function setStrategy(Strategy $strategy): void { $this->strategies[$strategy->id()->value()] = $strategy; + $this->events[] = StrategyWasAdded::occur( + $this->featureId->value(), + $strategy->id()->value(), + $strategy->type()->value(), + array_map(static fn(Segment $segment) => $segment->jsonSerialize(), $strategy->segments()) + ); } public function removeStrategy(StrategyId $strategyId): void diff --git a/src/Write/Payload.php b/src/Write/Payload.php index bdc5a87..b4d63a1 100644 --- a/src/Write/Payload.php +++ b/src/Write/Payload.php @@ -8,23 +8,16 @@ final class Payload { - /** - * @var array - */ + /** @var array */ private array $criteria; - /** - * @param array $criteria - */ + /** @param array $criteria */ private function __construct(array $criteria) { $this->criteria = $criteria; } - /** - * @param array $criteria - * @return static - */ + /** @param array $criteria */ public static function fromArray(array $criteria): self { return new self($criteria); @@ -32,17 +25,13 @@ public static function fromArray(array $criteria): self public static function fromJsonString(string $jsonPayload): self { - /** - * @var array $payload - */ + /** @var array $payload */ $payload = json_decode($jsonPayload, true, 16, JSON_THROW_ON_ERROR); return self::fromArray($payload); } - /** - * @return array - */ + /** @return array */ public function criteria(): array { return $this->criteria; diff --git a/src/Write/Segment.php b/src/Write/Segment.php index a45cf77..a9c9896 100644 --- a/src/Write/Segment.php +++ b/src/Write/Segment.php @@ -6,6 +6,10 @@ use JsonSerializable; +/** + * @phpstan-type WriteSegment array{segment_id: string, segment_type: string, criteria: array} + * @psalm-type WriteSegment array{segment_id: string, segment_type: string, criteria: array} + */ final class Segment implements JsonSerializable { private SegmentId $segmentId; @@ -35,7 +39,7 @@ public function payload(): Payload } /** - * @return array> + * @return WriteSegment */ public function jsonSerialize(): array { diff --git a/src/Write/Strategy.php b/src/Write/Strategy.php index 347d3fb..19ba2de 100644 --- a/src/Write/Strategy.php +++ b/src/Write/Strategy.php @@ -8,6 +8,11 @@ use function array_map; +/** + * @phpstan-import-type WriteSegment from Segment + * @phpstan-type WriteStrategy array{strategy_id: string, strategy_type: string, segments: WriteSegment[]} + * @psalm-type WriteStrategy array{strategy_id: string, strategy_type: string, segments: WriteSegment[]} + */ final class Strategy implements JsonSerializable { private StrategyId $strategyId; @@ -49,15 +54,7 @@ public function segments(): array return $this->segments; } - /** - * @phpstan-return array - * @phpstan-ignore-next-line - * @return array{ - * strategy_id: string, - * strategy_type: string - * segments: array|string>>, - * } - */ + /** @return WriteStrategy */ public function jsonSerialize(): array { return [ diff --git a/test/Write/FeatureTest.php b/test/Write/FeatureTest.php index f4fc181..4ca5356 100644 --- a/test/Write/FeatureTest.php +++ b/test/Write/FeatureTest.php @@ -7,9 +7,14 @@ use Pheature\Core\Toggle\Write\Event\FeatureWasDisabled; use Pheature\Core\Toggle\Write\Event\FeatureWasEnabled; use Pheature\Core\Toggle\Write\Event\FeatureWasRemoved; +use Pheature\Core\Toggle\Write\Event\StrategyWasAdded; use Pheature\Core\Toggle\Write\Event\StrategyWasRemoved; use Pheature\Core\Toggle\Write\Feature; use Pheature\Core\Toggle\Write\FeatureId; +use Pheature\Core\Toggle\Write\Payload; +use Pheature\Core\Toggle\Write\Segment; +use Pheature\Core\Toggle\Write\SegmentId; +use Pheature\Core\Toggle\Write\SegmentType; use Pheature\Core\Toggle\Write\Strategy; use Pheature\Core\Toggle\Write\StrategyId; use Pheature\Core\Toggle\Write\StrategyType; @@ -22,6 +27,8 @@ final class FeatureTest extends TestCase private const FEATURE_ID = 'some_feature'; private const STRATEGY_ID = 'some_strategy'; private const STRATEGY_TYPE = 'some_strategy_type'; + private const SEGMENT_ID = 'some_segment'; + private const SEGMENT_TYPE = 'some_segment_type'; public function testItShouldBeCreatedWithId(): void { @@ -87,14 +94,33 @@ public function testItShouldSetAnStrategy(): void $strategy = new Strategy( StrategyId::fromString(self::STRATEGY_ID), StrategyType::fromString(self::STRATEGY_TYPE), - [] + [ + new Segment( + SegmentId::fromString(self::SEGMENT_ID), + SegmentType::fromString(self::SEGMENT_TYPE), + Payload::fromArray(['foo' => 'bar']) + ) + ] ); $feature = $this->createFeature(); $feature->setStrategy($strategy); $this->assertCount(1, $feature->strategies()); $events = $feature->release(); - $this->assertCount(0, $events); + $this->assertCount(1, $events); + $this->assertEventIsRecorded(StrategyWasAdded::class, $events); + + /** @var StrategyWasAdded $strategyWasAdded */ + $strategyWasAdded = $events[0]; + $this->assertSame(self::FEATURE_ID, $strategyWasAdded->featureId()->value()); + $this->assertSame(self::STRATEGY_ID, $strategyWasAdded->strategyId()->value()); + $this->assertSame(self::STRATEGY_TYPE, $strategyWasAdded->strategyType()->value()); + /** @var Segment $segment */ + $segment = $strategyWasAdded->segments()[0]; + $this->assertSame(self::SEGMENT_ID, $segment->segmentId()->value()); + $this->assertSame(self::SEGMENT_TYPE, $segment->segmentType()->value()); + $this->assertSame(['foo' => 'bar'], $segment->payload()->criteria()); + $this->assertInstanceOf(DatetimeImmutable::class, $strategyWasAdded->occurredAt()); } public function testItShouldRemoveAnStrategy(): void