diff --git a/tests/Feature/Services/Social/BlueskyPublisherTest.php b/tests/Feature/Services/Social/BlueskyPublisherTest.php index 25de1134..136c7b75 100644 --- a/tests/Feature/Services/Social/BlueskyPublisherTest.php +++ b/tests/Feature/Services/Social/BlueskyPublisherTest.php @@ -123,6 +123,27 @@ }); }); +test('bluesky publisher keeps a closing paren that has a matching open paren', function () { + $this->post->update(['content' => 'see https://en.wikipedia.org/wiki/Foo_(bar)']); + + Http::fake([ + config('trypost.platforms.bluesky.default_service').'/xrpc/com.atproto.repo.createRecord' => Http::response([ + 'uri' => 'at://did:plc:testuser123/app.bsky.feed.post/3abc123xyz', + 'cid' => 'bafyreiabc123', + ], 200), + ]); + + $this->publisher->publish($this->postPlatform); + + Http::assertSent(function ($request) { + $link = collect($request['record']['facets'] ?? []) + ->first(fn ($facet) => $facet['features'][0]['$type'] === 'app.bsky.richtext.facet#link'); + + // The trailing ')' is part of the URL because it has a matching '('. + return $link && $link['features'][0]['uri'] === 'https://en.wikipedia.org/wiki/Foo_(bar)'; + }); +}); + test('bluesky publisher computes byte offsets after multibyte characters', function () { $this->post->update(['content' => 'Olá 🎉 #café']); diff --git a/tests/Unit/Services/Social/BlueskyLexiconTest.php b/tests/Unit/Services/Social/BlueskyLexiconTest.php new file mode 100644 index 00000000..47916f27 --- /dev/null +++ b/tests/Unit/Services/Social/BlueskyLexiconTest.php @@ -0,0 +1,22 @@ +toBe($nsid); +})->with([ + [BlueskyLexicon::RESOLVE_HANDLE, 'com.atproto.identity.resolveHandle'], + [BlueskyLexicon::CREATE_RECORD, 'com.atproto.repo.createRecord'], + [BlueskyLexicon::UPLOAD_BLOB, 'com.atproto.repo.uploadBlob'], + [BlueskyLexicon::CREATE_SESSION, 'com.atproto.server.createSession'], + [BlueskyLexicon::REFRESH_SESSION, 'com.atproto.server.refreshSession'], + [BlueskyLexicon::FEED_POST, 'app.bsky.feed.post'], + [BlueskyLexicon::GET_POSTS, 'app.bsky.feed.getPosts'], + [BlueskyLexicon::GET_PROFILE, 'app.bsky.actor.getProfile'], + [BlueskyLexicon::EMBED_IMAGES, 'app.bsky.embed.images'], + [BlueskyLexicon::FACET_LINK, 'app.bsky.richtext.facet#link'], + [BlueskyLexicon::FACET_MENTION, 'app.bsky.richtext.facet#mention'], + [BlueskyLexicon::FACET_TAG, 'app.bsky.richtext.facet#tag'], +]);