From aea0392492a97e74907fc1d1c12f6e92f9409c1f Mon Sep 17 00:00:00 2001 From: Siebe Vanden Eynden Date: Mon, 28 Mar 2022 12:01:13 +0200 Subject: [PATCH] Split replace/delete original from response type --- src/Kit.php | 4 +- src/Previewer.php | 4 +- src/Surfaces/Message.php | 44 +++++++---- .../MessageDirective/DeleteOriginal.php | 51 +++++++++++++ .../MessageDirective/ReplaceOriginal.php | 51 +++++++++++++ .../ResponseType.php} | 12 +-- tests/Surfaces/MessageTest.php | 76 ++++++++++++++++--- 7 files changed, 207 insertions(+), 35 deletions(-) create mode 100644 src/Surfaces/MessageDirective/DeleteOriginal.php create mode 100644 src/Surfaces/MessageDirective/ReplaceOriginal.php rename src/Surfaces/{MessageDirective.php => MessageDirective/ResponseType.php} (65%) diff --git a/src/Kit.php b/src/Kit.php index e471c88..beadf1c 100644 --- a/src/Kit.php +++ b/src/Kit.php @@ -43,13 +43,13 @@ public static function attachment( */ public static function message( Collections\BlockCollection|array|null $blocks = null, - ?Surfaces\MessageDirective $directive = null, + ?Surfaces\MessageDirective\ResponseType $responseType = null, ?string $text = null, Collections\AttachmentCollection|array|null $attachments = null, ?bool $mrkdwn = null, ?string $threadTs = null, ): Surfaces\Message { - return new Surfaces\Message($blocks, $directive, $text, $attachments, $mrkdwn, $threadTs); + return new Surfaces\Message($blocks, $responseType, $text, $attachments, $mrkdwn, $threadTs); } /** diff --git a/src/Previewer.php b/src/Previewer.php index 5ebe934..a968719 100644 --- a/src/Previewer.php +++ b/src/Previewer.php @@ -27,7 +27,9 @@ public function preview(Surfaces\Surface $surface): string if ($surface instanceof Surfaces\Message) { // Block Kit Builder doesn't support message directives or fallback text. $surface = (clone $surface) - ->directive(null) + ->responseType(null) + ->deleteOriginal(null) + ->replaceOriginal(null) ->text(null) ->mrkdwn(null) ->threadTs(null); diff --git a/src/Surfaces/Message.php b/src/Surfaces/Message.php index b2b8167..455f0dc 100644 --- a/src/Surfaces/Message.php +++ b/src/Surfaces/Message.php @@ -4,9 +4,13 @@ namespace SlackPhp\BlockKit\Surfaces; +use SlackPhp\BlockKit\{FauxProperty, + Property, + Surfaces\MessageDirective\DeleteOriginal, + Surfaces\MessageDirective\ReplaceOriginal, + Surfaces\MessageDirective\ResponseType}; use SlackPhp\BlockKit\Blocks\Block; use SlackPhp\BlockKit\Collections\{AttachmentCollection, BlockCollection}; -use SlackPhp\BlockKit\{FauxProperty, Property}; use SlackPhp\BlockKit\Hydration\OmitType; use SlackPhp\BlockKit\Validation\{RequiresAnyOf, UniqueIds, ValidCollection, ValidString}; @@ -19,8 +23,14 @@ class Message extends Surface #[Property, ValidCollection(50, 0), UniqueIds] public BlockCollection $blocks; - #[FauxProperty('response_type', 'replace_original', 'delete_original')] - public ?MessageDirective $directive; + #[FauxProperty('response_type')] + public ?ResponseType $responseType; + + #[FauxProperty('replace_original')] + public ?ReplaceOriginal $replaceOriginal; + + #[FauxProperty('delete_original')] + public ?DeleteOriginal $deleteOriginal; #[Property, ValidString] public ?string $text; @@ -40,19 +50,23 @@ class Message extends Surface */ public function __construct( BlockCollection|array|null $blocks = null, - ?MessageDirective $directive = null, + ?ResponseType $directive = null, ?string $text = null, AttachmentCollection|array|null $attachments = null, ?bool $mrkdwn = null, ?string $threadTs = null, ?bool $ephemeral = null, + ?bool $replaceOriginal = null, + ?bool $deleteOriginal = null, ) { parent::__construct($blocks); $this->attachments = AttachmentCollection::wrap($attachments); - $this->directive($directive ?? ($ephemeral ? MessageDirective::EPHEMERAL : null)); + $this->responseType($directive ?? ($ephemeral ? ResponseType::EPHEMERAL : null)); $this->text($text); $this->mrkdwn($mrkdwn); $this->threadTs($threadTs); + $this->replaceOriginal($replaceOriginal); + $this->deleteOriginal($deleteOriginal); } /** @@ -62,7 +76,7 @@ public function __construct( */ public function ephemeral(): static { - return $this->directive(MessageDirective::EPHEMERAL); + return $this->responseType(ResponseType::EPHEMERAL); } /** @@ -70,28 +84,32 @@ public function ephemeral(): static */ public function inChannel(): static { - return $this->directive(MessageDirective::IN_CHANNEL); + return $this->responseType(ResponseType::IN_CHANNEL); } /** * Configures message to "replace_original" mode. */ - public function replaceOriginal(): static + public function replaceOriginal(ReplaceOriginal|array|bool|null $replaceOriginal = true): static { - return $this->directive(MessageDirective::REPLACE_ORIGINAL); + $this->replaceOriginal = ReplaceOriginal::fromValue($replaceOriginal); + + return $this; } /** * Configures message to "delete_original" mode. */ - public function deleteOriginal(): static + public function deleteOriginal(DeleteOriginal|array|bool|null $deleteOriginal = true): static { - return $this->directive(MessageDirective::DELETE_ORIGINAL); + $this->deleteOriginal = DeleteOriginal::fromValue($deleteOriginal); + + return $this; } - public function directive(MessageDirective|array|null $directive): static + public function responseType(ResponseType|array|null $responseType): static { - $this->directive = MessageDirective::fromValue($directive); + $this->responseType = ResponseType::fromValue($responseType); return $this; } diff --git a/src/Surfaces/MessageDirective/DeleteOriginal.php b/src/Surfaces/MessageDirective/DeleteOriginal.php new file mode 100644 index 0000000..cc414f0 --- /dev/null +++ b/src/Surfaces/MessageDirective/DeleteOriginal.php @@ -0,0 +1,51 @@ + + */ + public function toArray(): array + { + return match ($this) { + self::DELETE_ORIGINAL => ['delete_original' => 'true'], + self::DONT_DELETE_ORIGINAL => ['delete_original' => 'false'], + }; + } + + /** + * @param self|array|bool|null $data + * @return static|null + */ + public static function fromValue(self|array|bool|null $data): ?self + { + if ($data instanceof self) { + return $data; + } + + if (is_bool($data)) { + return $data ? self::DELETE_ORIGINAL : self::DONT_DELETE_ORIGINAL; + } + + if (is_array($data)) { + $data = array_filter($data); + return match ($data) { + ['delete_original' => 'true'] => self::DELETE_ORIGINAL, + ['delete_original' => 'false'] => self::DONT_DELETE_ORIGINAL, + [] => null, + default => throw new Exception('Invalid Delete Original enum encountered: %s', [json_encode($data)]), + }; + } + + return null; + } +} diff --git a/src/Surfaces/MessageDirective/ReplaceOriginal.php b/src/Surfaces/MessageDirective/ReplaceOriginal.php new file mode 100644 index 0000000..8d999af --- /dev/null +++ b/src/Surfaces/MessageDirective/ReplaceOriginal.php @@ -0,0 +1,51 @@ + + */ + public function toArray(): array + { + return match ($this) { + self::REPLACE_ORIGINAL => ['replace_original' => 'true'], + self::DONT_REPLACE_ORIGINAL => ['replace_original' => 'false'], + }; + } + + /** + * @param self|array|bool|null $data + * @return static|null + */ + public static function fromValue(self|array|bool|null $data): ?self + { + if ($data instanceof self) { + return $data; + } + + if (is_bool($data)) { + return $data ? self::REPLACE_ORIGINAL : self::DONT_REPLACE_ORIGINAL; + } + + if (is_array($data)) { + $data = array_filter($data); + return match ($data) { + ['replace_original' => 'true'] => self::REPLACE_ORIGINAL, + ['replace_original' => 'false'] => self::DONT_REPLACE_ORIGINAL, + [] => null, + default => throw new Exception('Invalid Replace Original enum encountered: %s', [json_encode($data)]), + }; + } + + return null; + } +} diff --git a/src/Surfaces/MessageDirective.php b/src/Surfaces/MessageDirective/ResponseType.php similarity index 65% rename from src/Surfaces/MessageDirective.php rename to src/Surfaces/MessageDirective/ResponseType.php index 9b2a44f..9a40654 100644 --- a/src/Surfaces/MessageDirective.php +++ b/src/Surfaces/MessageDirective/ResponseType.php @@ -2,16 +2,14 @@ declare(strict_types=1); -namespace SlackPhp\BlockKit\Surfaces; +namespace SlackPhp\BlockKit\Surfaces\MessageDirective; use SlackPhp\BlockKit\Exception; -enum MessageDirective +enum ResponseType { case EPHEMERAL; case IN_CHANNEL; - case REPLACE_ORIGINAL; - case DELETE_ORIGINAL; /** * @return array @@ -21,8 +19,6 @@ public function toArray(): array return match ($this) { self::EPHEMERAL => ['response_type' => 'ephemeral'], self::IN_CHANNEL => ['response_type' => 'in_channel'], - self::REPLACE_ORIGINAL => ['replace_original' => 'true'], - self::DELETE_ORIGINAL => ['delete_original' => 'true'], }; } @@ -41,10 +37,8 @@ public static function fromValue(self|array|null $data): ?self return match ($data) { ['response_type' => 'ephemeral'] => self::EPHEMERAL, ['response_type' => 'in_channel'] => self::IN_CHANNEL, - ['replace_original' => 'true'] => self::REPLACE_ORIGINAL, - ['delete_original' => 'true'] => self::DELETE_ORIGINAL, [] => null, - default => throw new Exception('Invalid MessageDirective enum encountered: %s', [json_encode($data)]), + default => throw new Exception('Invalid Response Type enum encountered: %s', [json_encode($data)]), }; } diff --git a/tests/Surfaces/MessageTest.php b/tests/Surfaces/MessageTest.php index ca952ef..c89e39f 100644 --- a/tests/Surfaces/MessageTest.php +++ b/tests/Surfaces/MessageTest.php @@ -4,10 +4,10 @@ namespace SlackPhp\BlockKit\Tests\Surfaces; -use SlackPhp\BlockKit\Surfaces\MessageDirective; use SlackPhp\BlockKit\Exception; use SlackPhp\BlockKit\Surfaces\Attachment; use SlackPhp\BlockKit\Surfaces\Message; +use SlackPhp\BlockKit\Surfaces\MessageDirective\ResponseType; use SlackPhp\BlockKit\Tests\TestCase; /** @@ -37,7 +37,7 @@ class MessageTest extends TestCase ['blocks' => self::TEST_BLOCKS], ]; - public function testCanApplyEphemeralDirectives(): void + public function testCanApplyEphemeralMessageType(): void { $msg = new Message(['foo', 'bar']); $msg->ephemeral(); @@ -48,7 +48,7 @@ public function testCanApplyEphemeralDirectives(): void ], $msg); } - public function testCanApplyInChannelDirectives(): void + public function testCanApplyInChannelMessageType(): void { $msg = new Message(['foo', 'bar']); $msg->inChannel(); @@ -59,7 +59,7 @@ public function testCanApplyInChannelDirectives(): void ], $msg); } - public function testCanApplyReplaceOriginalDirectives(): void + public function testCanApplyReplaceOriginal(): void { $msg = new Message(['foo', 'bar']); $msg->replaceOriginal(); @@ -70,6 +70,27 @@ public function testCanApplyReplaceOriginalDirectives(): void ], $msg); } + public function testCanApplyDontReplaceOriginal(): void + { + $msg = new Message(['foo', 'bar']); + $msg->replaceOriginal(false); + + $this->assertJsonData([ + 'replace_original' => 'false', + 'blocks' => self::TEST_BLOCKS, + ], $msg); + } + + public function testCanRemoveReplaceOriginal(): void + { + $msg = new Message(['foo', 'bar']); + $msg->replaceOriginal() + ->replaceOriginal(null); + $data = $msg->toArray(); + + $this->assertArrayNotHasKey('replace_original', $data); + } + public function testCanApplyDeleteOriginalDirectives(): void { $msg = new Message(['foo', 'bar']); @@ -81,6 +102,27 @@ public function testCanApplyDeleteOriginalDirectives(): void ], $msg); } + public function testCanApplyDontDeleteOriginalDirectives(): void + { + $msg = new Message(['foo', 'bar']); + $msg->deleteOriginal(false); + + $this->assertJsonData([ + 'delete_original' => 'false', + 'blocks' => self::TEST_BLOCKS, + ], $msg); + } + + public function testCanRemoveDeleteOriginalDirectives(): void + { + $msg = new Message(['foo', 'bar']); + $msg->deleteOriginal() + ->deleteOriginal(null); + $data = $msg->toArray(); + + $this->assertArrayNotHasKey('delete_original', $data); + } + public function testDoesNotApplyDirectivesWhenNotSet(): void { $msg = new Message(['foo', 'bar']); @@ -91,20 +133,34 @@ public function testDoesNotApplyDirectivesWhenNotSet(): void $this->assertArrayNotHasKey('delete_original', $data); } - public function testCanOnlyApplyOneDirective(): void + public function testCanOnlyApplyOneResponseType(): void + { + $msg = new Message(['foo', 'bar']); + $msg->ephemeral() + ->inChannel(); + + $data = $msg->toArray(); + + $this->assertArrayHasKey('response_type', $data); + $this->assertEquals('in_channel', $data['response_type']); + } + + public function testCanApplyMoreDirectives(): void { $msg = new Message(['foo', 'bar']); $msg->ephemeral() - ->inChannel() ->replaceOriginal() - ->deleteOriginal(); + ->deleteOriginal() + ->inChannel(); $data = $msg->toArray(); - $this->assertArrayNotHasKey('response_type', $data); - $this->assertArrayNotHasKey('replace_original', $data); + $this->assertArrayHasKey('response_type', $data); $this->assertArrayHasKey('delete_original', $data); + $this->assertArrayHasKey('replace_original', $data); + $this->assertEquals('in_channel', $data['response_type']); $this->assertEquals('true', $data['delete_original']); + $this->assertEquals('true', $data['replace_original']); } public function testCanAddAttachments(): void @@ -147,7 +203,7 @@ public function testCanAddFallbackText(): void public function testCanConvertToAnArray(): void { - $msg = new Message(['foo', 'bar'], MessageDirective::EPHEMERAL, 'foo bar'); + $msg = new Message(['foo', 'bar'], ResponseType::EPHEMERAL, 'foo bar'); $data = $msg->toArray(); $this->assertArrayHasKey('blocks', $data);