trypost/tests/Unit
Paulo Castellano 620d23187e fix(social): handle TokenExpired status fail-fast and notify user
Three related fixes for the failure mode where a scheduled post errors out
as 'An unknown X error occurred.' when a social account's refresh_token
was already invalidated by the provider:

1. **PublishToSocialPlatform**: fail-fast when account status is
   `TokenExpired`. Previously the job tried to publish, the publisher
   internally tried to refresh, the provider rejected the rotated
   refresh_token, and the failure surfaced as a generic 'unknown' error
   instead of a clear 'reconnect your account' signal.

2. **XPublisher::refreshToken**: when the OAuth endpoint rejects the
   refresh_token (typically because it was rotated/revoked at X), log the
   raw response and throw `TokenExpiredException` instead of falling
   through to `XPublishException::fromApiResponse` which expects the
   tweet-API response shape (`type`/`title`/`detail`) and treats
   OAuth-style responses (`error`/`error_description`) as 'Unknown'.

3. **SocialAccount::markAsTokenExpired**: dispatch an in-app + email
   notification (`Type::AccountDisconnected`) when an account
   transitions from `Connected` → `TokenExpired`, mirroring the
   existing pattern in `markAsDisconnected`. Wrapped in a lock to
   prevent duplicate notifications on concurrent transitions. Accepts an
   optional `notify: false` so the batch verifier
   (`VerifyWorkspaceConnections`) can suppress per-account
   notifications and rely on its summary email.
2026-05-12 18:46:06 -03:00
..
Ai/Agents chore: remove unused Gemini provider extension and debug middleware 2026-05-11 21:24:11 -03:00
Broadcasting feat: workspace-scoped broadcast channel and post lifecycle events 2026-05-07 16:02:22 -03:00
Enums refactor(posts): tighten content-length caps and simplify contentOverflow 2026-05-11 20:06:44 -03:00
Events refactor: prefer string interpolation over concatenation for channel names 2026-05-08 19:22:01 -03:00
Exceptions/Social fix: Facebook/Instagram/Threads OAuthException type incorrectly treated as token error — now only code 190 triggers TokenExpiredException 2026-04-01 14:33:26 -03:00
Features feat: transition AI usage from feature-based limits to a centralized monthly credit system with token tracking. 2026-05-03 19:36:26 -03:00
Mail feat: @mentions in comments, AI Action layer + MCP tools, settings tabs 2026-05-01 20:59:03 -03:00
Models refactor: replace hashtags functionality with reusable signatures feature 2026-05-03 15:23:30 -03:00
Policies feat: transition AI usage from feature-based limits to a centralized monthly credit system with token tracking. 2026-05-03 19:36:26 -03:00
PostTemplates refactor: reorganize settings UI, migrate post templates to a file-based registry, and remove legacy video generation features 2026-05-03 13:44:13 -03:00
Rules fix(posts): block scheduling when content exceeds any platform's char limit 2026-05-11 19:39:41 -03:00
Services fix(social): handle TokenExpired status fail-fast and notify user 2026-05-12 18:46:06 -03:00
Socialite refactor: settings redesign, Spanish translations, language system, strict_types 2026-03-30 00:20:43 -03:00
Support feat: AI image generation pipeline and post creation overhaul 2026-05-08 13:38:30 -03:00
Traits refactor: centralize media size limits in config + drop Document type 2026-05-04 14:54:47 -03:00
ExampleTest.php refactor: settings redesign, Spanish translations, language system, strict_types 2026-03-30 00:20:43 -03:00
HelpersTest.php refactor: settings redesign, Spanish translations, language system, strict_types 2026-03-30 00:20:43 -03:00
MediaPolymorphTest.php fix: persist morph map alias on AI-generated Media rows 2026-05-04 14:14:14 -03:00
PostHogServiceTest.php fix: serialize plan_slug as string and broaden PostHog enabled tests 2026-05-07 13:21:58 -03:00