From c2ef9b7813769cb7e6f020ded7901a184e9d9cba Mon Sep 17 00:00:00 2001 From: Eldar Shahmaliyev Date: Sun, 13 Oct 2024 22:30:16 +0400 Subject: [PATCH] Add tags support to PostBuilder API --- .../App/Bsky/Feed/PostBuilderContract.php | 2 + src/Lexicons/App/Bsky/Feed/Post.php | 35 +++++++++++++- .../Unit/Lexicons/App/Bsky/Feed/PostTest.php | 46 ++++++++++++++++--- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/Contracts/Lexicons/App/Bsky/Feed/PostBuilderContract.php b/src/Contracts/Lexicons/App/Bsky/Feed/PostBuilderContract.php index 9058dc6..835447b 100644 --- a/src/Contracts/Lexicons/App/Bsky/Feed/PostBuilderContract.php +++ b/src/Contracts/Lexicons/App/Bsky/Feed/PostBuilderContract.php @@ -28,4 +28,6 @@ public function reply(StrongRef $root, StrongRef $parent): PostBuilderContract; public function langs(array $languages): PostBuilderContract; public function labels(SelfLabels $labels): PostBuilderContract; + + public function tags(array $tags): PostBuilderContract; } diff --git a/src/Lexicons/App/Bsky/Feed/Post.php b/src/Lexicons/App/Bsky/Feed/Post.php index b028d64..9737904 100644 --- a/src/Lexicons/App/Bsky/Feed/Post.php +++ b/src/Lexicons/App/Bsky/Feed/Post.php @@ -28,6 +28,7 @@ class Post implements PostBuilderContract private ?array $reply = null; private ?array $languages = null; private ?SelfLabels $labels = null; + private ?array $tags = null; public function __construct() @@ -130,6 +131,37 @@ public function labels(SelfLabels $labels): PostBuilderContract return $this; } + /** + * @throws InvalidArgumentException + */ + public function tags(array $tags): PostBuilderContract + { + $maxLength = 8; + $maxLengthByTag = 640; + + if (count($tags) > $maxLength) { + throw new InvalidArgumentException('A maximum of 8 tags is allowed.'); + } + + $invalid = array_filter($tags, function ($tag) { + if (mb_strlen($tag) > 640) { + return true; + } + }); + + if (! empty($invalid)) { + throw new InvalidArgumentException(sprintf( + "Invalid tags: %s. A tag maximum of %s characters is allowed.", + implode(', ', $invalid), + $maxLengthByTag + )); + } + + $this->tags = $tags; + + return $this; + } + /** * Validates the format of a language code. * @@ -175,7 +207,8 @@ public function jsonSerialize(): array 'embed' => $this->embed, 'replyRef' => $this->reply, 'langs' => $this->languages, - 'labels' => $this->labels + 'labels' => $this->labels, + 'tags' => $this->tags, ]); } diff --git a/tests/Unit/Lexicons/App/Bsky/Feed/PostTest.php b/tests/Unit/Lexicons/App/Bsky/Feed/PostTest.php index 8678a23..5e40030 100644 --- a/tests/Unit/Lexicons/App/Bsky/Feed/PostTest.php +++ b/tests/Unit/Lexicons/App/Bsky/Feed/PostTest.php @@ -232,6 +232,41 @@ public function testLabelsMethod(): void ], $result['labels']); } + public function testTagsThrowsExceptionWhenPassedTagExceedsAllowedLength(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid tags: "); + + $trigger = [str_pad('', 641, 'a')]; + $this->post->tags($trigger); + } + + public function testTagsMethodThrowsExceptionWhenPassedArrayExceedsAllowedLength(): void + { + $max = 8; + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("A maximum of $max tags is allowed."); + + $trigger = str_split(str_pad('', ++$max, 'a')); + + $this->post->tags($trigger); + } + + /** + * @throws InvalidArgumentException + */ + public function testTags(): void + { + $tags = [str_pad('', 640, 'a')]; + $this->post->tags($tags); + + $result = json_decode($this->post, true); + + $this->assertArrayHasKey('tags', $result); + $this->assertEquals($tags, $result['tags']); + } + /** * @throws InvalidArgumentException */ @@ -241,15 +276,13 @@ public function testJsonSerialize() $embed = $this->createMock(EmbedInterface::class); $embed->method('jsonSerialize')->willReturn(['embedKey' => 'embedValue']); $this->post->embed($embed); - $sRef = new StrongRef('foo', 'bar'); - $this->post->reply($sRef, clone $sRef); + $this->post->reply($sRef = new StrongRef('foo', 'bar'), clone $sRef); $this->post->langs(['en', 'fr', 'es']); - $this->post->labels(new SelfLabels([ - 'val 1', - 'val 2' - ])); + $this->post->labels(new SelfLabels(str_split(str_pad('', 2, 'val')))); + $this->post->tags(str_split(str_pad('', 2, 'tag'))); $result = $this->post->jsonSerialize(); + $this->assertArrayHasKey('$type', $result); $this->assertEquals('app.bsky.feed.post', $result['$type']); $this->assertArrayHasKey('text', $result); @@ -259,6 +292,7 @@ public function testJsonSerialize() $this->assertArrayHasKey('replyRef', $result); $this->assertArrayHasKey('langs', $result); $this->assertArrayHasKey('labels', $result); + $this->assertArrayHasKey('tags', $result); } public function testConstructorWorksCorrectlyOnDirectBuild()