- Add HasSocialHttpClient trait with 429 rate limit retry (3 attempts, 5s delay) - Integrate trait into all 10 publishers (YouTube uses Google SDK) - Add inline token refresh retry in PublishToSocialPlatform job - Add per-platform Horizon queues via Platform::queue() and Platform::allQueues() - Add RefreshExpiringTokens hourly command for proactive token refresh - Fix token leaks: redact response bodies in all Log::error calls - Fix token leaks: remove $response->body() from exception messages - Fix ConnectionVerifier: redact all refresh error logs - Fix null checks on API response IDs (Instagram, Threads, Pinterest, Facebook) - Fix PublishPost::failed() to mark post as failed - Fix StoreChunkedMediaRequest: validate max 1GB total size - Fix scheduled_at validation: string → date - Fix StoreMediaRequest: images max 10MB, videos max 1GB, only MP4 video
68 lines
1.7 KiB
PHP
68 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\Social\Concerns\HasSocialHttpClient;
|
|
use Illuminate\Http\Client\Response;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
beforeEach(function () {
|
|
$this->client = new class
|
|
{
|
|
use HasSocialHttpClient;
|
|
|
|
public function makeRequest(string $url): Response
|
|
{
|
|
return $this->socialHttp()->get($url);
|
|
}
|
|
};
|
|
});
|
|
|
|
it('retries on 429 responses', function () {
|
|
Http::fake([
|
|
'https://example.com/api' => Http::sequence()
|
|
->push('Rate limited', 429)
|
|
->push(['success' => true], 200),
|
|
]);
|
|
|
|
$response = $this->client->makeRequest('https://example.com/api');
|
|
|
|
expect($response->status())->toBe(200);
|
|
Http::assertSentCount(2);
|
|
});
|
|
|
|
it('does not retry on non-429 errors', function () {
|
|
Http::fake([
|
|
'https://example.com/api' => Http::response('Server error', 500),
|
|
]);
|
|
|
|
$response = $this->client->makeRequest('https://example.com/api');
|
|
|
|
expect($response->status())->toBe(500);
|
|
Http::assertSentCount(1);
|
|
});
|
|
|
|
it('gives up after 3 retries', function () {
|
|
Http::fake([
|
|
'https://example.com/api' => Http::sequence()
|
|
->push('Rate limited', 429)
|
|
->push('Rate limited', 429)
|
|
->push('Rate limited', 429),
|
|
]);
|
|
|
|
$response = $this->client->makeRequest('https://example.com/api');
|
|
|
|
expect($response->status())->toBe(429);
|
|
Http::assertSentCount(3);
|
|
});
|
|
|
|
it('returns successful response normally', function () {
|
|
Http::fake([
|
|
'https://example.com/api' => Http::response(['data' => 'ok'], 200),
|
|
]);
|
|
|
|
$response = $this->client->makeRequest('https://example.com/api');
|
|
|
|
expect($response->status())->toBe(200);
|
|
Http::assertSentCount(1);
|
|
});
|