From 090cc761dd86f91cee6a01ef0871ae1228d3473a Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 19 May 2026 08:42:02 -0300 Subject: [PATCH] test(social): smoke tests for analytics refactored in this PR LinkedInPageAnalytics and MastodonAnalytics were the only two of the 11 files refactored to read OAuth host / default instance from config that had zero test coverage. Adds smoke tests that assert the HTTP request hits the configured URL, so a typo in the config key (e.g. linkedin.api vs linkedin.oauth_api) would now fail loudly. --- .../Social/LinkedInPageAnalyticsTest.php | 55 ++++++++++++++ .../Services/Social/MastodonAnalyticsTest.php | 75 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 tests/Feature/Services/Social/LinkedInPageAnalyticsTest.php create mode 100644 tests/Feature/Services/Social/MastodonAnalyticsTest.php diff --git a/tests/Feature/Services/Social/LinkedInPageAnalyticsTest.php b/tests/Feature/Services/Social/LinkedInPageAnalyticsTest.php new file mode 100644 index 00000000..0836940d --- /dev/null +++ b/tests/Feature/Services/Social/LinkedInPageAnalyticsTest.php @@ -0,0 +1,55 @@ +user = User::factory()->create(); + $this->workspace = Workspace::factory()->create(['user_id' => $this->user->id]); + $this->socialAccount = SocialAccount::factory()->linkedinPage()->create([ + 'workspace_id' => $this->workspace->id, + 'token_expires_at' => now()->subHour(), + 'refresh_token' => 'old_refresh_token', + ]); + $this->post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + ]); + $this->postPlatform = PostPlatform::factory()->create([ + 'post_id' => $this->post->id, + 'social_account_id' => $this->socialAccount->id, + 'platform' => Platform::LinkedInPage, + 'content_type' => ContentType::LinkedInPagePost, + 'platform_post_id' => 'urn:li:share:1234567890', + ]); +}); + +test('linkedin page analytics refresh hits the configured oauth host', function () { + Http::fake([ + 'www.linkedin.com/oauth/v2/accessToken' => Http::response([ + 'access_token' => 'new_token', + 'refresh_token' => 'new_refresh_token', + 'expires_in' => 5184000, + ], 200), + 'api.linkedin.com/rest/socialActions/*' => Http::response([ + 'likesSummary' => ['totalLikes' => 0], + 'commentsSummary' => ['aggregatedTotalComments' => 0], + ], 200), + ]); + + (new LinkedInPageAnalytics)->fetchPostMetrics($this->postPlatform); + + Http::assertSent(fn ($request) => str_contains( + $request->url(), + rtrim((string) config('trypost.platforms.linkedin.oauth_api'), '/').'/oauth/v2/accessToken' + )); +}); diff --git a/tests/Feature/Services/Social/MastodonAnalyticsTest.php b/tests/Feature/Services/Social/MastodonAnalyticsTest.php new file mode 100644 index 00000000..0a6fe7cc --- /dev/null +++ b/tests/Feature/Services/Social/MastodonAnalyticsTest.php @@ -0,0 +1,75 @@ +user = User::factory()->create(); + $this->workspace = Workspace::factory()->create(['user_id' => $this->user->id]); + $this->post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + ]); +}); + +test('mastodon analytics falls back to configured default instance', function () { + $defaultInstance = (string) config('trypost.platforms.mastodon.default_instance'); + + Http::fake([ + "{$defaultInstance}/api/v1/statuses/*" => Http::response([ + 'favourites_count' => 5, + 'reblogs_count' => 2, + 'replies_count' => 1, + ], 200), + ]); + + $account = SocialAccount::factory()->mastodon()->create([ + 'workspace_id' => $this->workspace->id, + 'meta' => [], + ]); + $postPlatform = PostPlatform::factory()->create([ + 'post_id' => $this->post->id, + 'social_account_id' => $account->id, + 'platform' => Platform::Mastodon, + 'content_type' => ContentType::MastodonPost, + 'platform_post_id' => '109876543210', + ]); + + $metrics = (new MastodonAnalytics)->fetchPostMetrics($postPlatform); + + expect($metrics)->toBeArray(); + Http::assertSent(fn ($request) => str_starts_with($request->url(), $defaultInstance.'/api/v1/statuses/')); +}); + +test('mastodon analytics honors per-account instance override', function () { + Http::fake([ + 'techhub.social/api/v1/statuses/*' => Http::response([ + 'favourites_count' => 0, 'reblogs_count' => 0, 'replies_count' => 0, + ], 200), + ]); + + $account = SocialAccount::factory()->mastodon()->create([ + 'workspace_id' => $this->workspace->id, + 'meta' => ['instance' => 'https://techhub.social'], + ]); + $postPlatform = PostPlatform::factory()->create([ + 'post_id' => $this->post->id, + 'social_account_id' => $account->id, + 'platform' => Platform::Mastodon, + 'content_type' => ContentType::MastodonPost, + 'platform_post_id' => '999', + ]); + + (new MastodonAnalytics)->fetchPostMetrics($postPlatform); + + Http::assertSent(fn ($request) => str_starts_with($request->url(), 'https://techhub.social/api/v1/statuses/')); +});