fedi-feed-router/backend/tests/Unit/Services/Auth/LemmyAuthServiceTest.php

297 lines
10 KiB
PHP
Raw Normal View History

2025-08-06 21:49:13 +02:00
<?php
namespace Tests\Unit\Services\Auth;
use App\Enums\PlatformEnum;
use App\Exceptions\PlatformAuthException;
use App\Models\PlatformAccount;
use App\Modules\Lemmy\Services\LemmyApiService;
use App\Services\Auth\LemmyAuthService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
2025-08-10 04:16:53 +02:00
use Illuminate\Support\Facades\Http;
use Illuminate\Cache\CacheManager;
2025-08-06 21:49:13 +02:00
use Tests\TestCase;
class LemmyAuthServiceTest extends TestCase
{
use RefreshDatabase;
2025-08-10 04:16:53 +02:00
protected function setUp(): void
{
parent::setUp();
// Don't set default HTTP mocks here - let individual tests control them
}
2025-08-06 21:49:13 +02:00
protected function tearDown(): void
{
parent::tearDown();
}
public function test_get_token_returns_cached_token_when_available(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls (not needed since token is cached)
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
$cachedToken = 'cached-jwt-token';
$cacheKey = "lemmy_jwt_token_{$account->id}";
2025-08-10 04:16:53 +02:00
// Put token in cache using Laravel's testing cache
cache()->put($cacheKey, $cachedToken, 3000);
2025-08-06 21:49:13 +02:00
$result = LemmyAuthService::getToken($account);
$this->assertEquals($cachedToken, $result);
}
public function test_get_token_throws_exception_when_username_missing(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls (not needed since it throws before API call)
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
// Create account with valid data first, then modify username property
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
2025-08-10 01:26:56 +02:00
2025-08-06 21:49:13 +02:00
// Use reflection to set username to null to bypass validation
$reflection = new \ReflectionClass($account);
$property = $reflection->getProperty('attributes');
$property->setAccessible(true);
$attributes = $property->getValue($account);
$attributes['username'] = null;
$property->setValue($account, $attributes);
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
cache()->forget("lemmy_jwt_token_{$account->id}");
2025-08-06 21:49:13 +02:00
$this->expectException(PlatformAuthException::class);
$this->expectExceptionMessage('Missing credentials for account: ');
LemmyAuthService::getToken($account);
}
public function test_get_token_throws_exception_when_password_missing(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
// Create account with valid data first, then modify password property
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
2025-08-10 01:26:56 +02:00
2025-08-06 21:49:13 +02:00
// Use reflection to set password to null to bypass validation
$reflection = new \ReflectionClass($account);
$property = $reflection->getProperty('attributes');
$property->setAccessible(true);
$attributes = $property->getValue($account);
$attributes['password'] = null;
$property->setValue($account, $attributes);
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
cache()->forget("lemmy_jwt_token_{$account->id}");
2025-08-06 21:49:13 +02:00
$this->expectException(PlatformAuthException::class);
$this->expectExceptionMessage('Missing credentials for account: testuser');
LemmyAuthService::getToken($account);
}
public function test_get_token_throws_exception_when_instance_url_missing(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
// Create account with valid data first, then modify instance_url property
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
2025-08-10 01:26:56 +02:00
2025-08-06 21:49:13 +02:00
// Use reflection to set instance_url to null to bypass validation
$reflection = new \ReflectionClass($account);
$property = $reflection->getProperty('attributes');
$property->setAccessible(true);
$attributes = $property->getValue($account);
$attributes['instance_url'] = null;
$property->setValue($account, $attributes);
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
cache()->forget("lemmy_jwt_token_{$account->id}");
2025-08-06 21:49:13 +02:00
$this->expectException(PlatformAuthException::class);
$this->expectExceptionMessage('Missing credentials for account: testuser');
LemmyAuthService::getToken($account);
}
public function test_get_token_successfully_authenticates_and_caches_token(): void
{
2025-08-10 04:16:53 +02:00
// Mock successful HTTP response for both HTTPS and HTTP (fallback)
Http::fake([
'https://lemmy.test/api/v3/user/login' => Http::response(['jwt' => 'jwt-123'], 200),
'http://lemmy.test/api/v3/user/login' => Http::response(['jwt' => 'jwt-123'], 200)
]);
2025-08-10 01:26:56 +02:00
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
$cacheKey = "lemmy_jwt_token_{$account->id}";
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists initially
cache()->forget($cacheKey);
2025-08-10 01:26:56 +02:00
$result = LemmyAuthService::getToken($account);
$this->assertEquals('jwt-123', $result);
2025-08-10 04:16:53 +02:00
// Verify token was cached
$this->assertEquals('jwt-123', cache()->get($cacheKey));
2025-08-06 21:49:13 +02:00
}
public function test_get_token_throws_exception_when_login_fails(): void
{
2025-08-10 04:16:53 +02:00
// Mock failed HTTP response for both HTTPS and HTTP
Http::fake([
'https://lemmy.test/api/v3/user/login' => Http::response(['error' => 'Invalid credentials'], 401),
'http://lemmy.test/api/v3/user/login' => Http::response(['error' => 'Invalid credentials'], 401)
]);
2025-08-10 01:26:56 +02:00
$account = PlatformAccount::factory()->create([
'username' => 'failingUser',
'password' => 'badpass',
'instance_url' => 'https://lemmy.test'
]);
$cacheKey = "lemmy_jwt_token_{$account->id}";
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
Cache::forget($cacheKey);
2025-08-10 01:26:56 +02:00
$this->expectException(PlatformAuthException::class);
$this->expectExceptionMessage('Login failed for account: failingUser');
LemmyAuthService::getToken($account);
2025-08-06 21:49:13 +02:00
}
public function test_get_token_throws_exception_when_login_returns_false(): void
{
2025-08-10 04:16:53 +02:00
// Mock response with empty/missing JWT for both HTTPS and HTTP
Http::fake([
'https://lemmy.test/api/v3/user/login' => Http::response(['success' => false], 200),
'http://lemmy.test/api/v3/user/login' => Http::response(['success' => false], 200)
]);
2025-08-10 01:26:56 +02:00
$account = PlatformAccount::factory()->create([
'username' => 'emptyUser',
'password' => 'pass',
'instance_url' => 'https://lemmy.test'
]);
$cacheKey = "lemmy_jwt_token_{$account->id}";
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
Cache::forget($cacheKey);
2025-08-10 01:26:56 +02:00
$this->expectException(PlatformAuthException::class);
$this->expectExceptionMessage('Login failed for account: emptyUser');
LemmyAuthService::getToken($account);
2025-08-06 21:49:13 +02:00
}
public function test_get_token_uses_correct_cache_duration(): void
{
2025-08-10 04:16:53 +02:00
// Mock successful HTTP response for both HTTPS and HTTP
Http::fake([
'https://lemmy.test/api/v3/user/login' => Http::response(['jwt' => 'xyz'], 200),
'http://lemmy.test/api/v3/user/login' => Http::response(['jwt' => 'xyz'], 200)
]);
2025-08-10 01:26:56 +02:00
$account = PlatformAccount::factory()->create([
'username' => 'cacheUser',
'password' => 'secret',
'instance_url' => 'https://lemmy.test'
]);
$cacheKey = "lemmy_jwt_token_{$account->id}";
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists initially
cache()->forget($cacheKey);
2025-08-10 01:26:56 +02:00
$token = LemmyAuthService::getToken($account);
$this->assertEquals('xyz', $token);
2025-08-10 04:16:53 +02:00
// Verify token was cached
$this->assertEquals('xyz', cache()->get($cacheKey));
2025-08-06 21:49:13 +02:00
}
public function test_get_token_uses_account_specific_cache_key(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
$account1 = PlatformAccount::factory()->create(['username' => 'user1']);
$account2 = PlatformAccount::factory()->create(['username' => 'user2']);
$cacheKey1 = "lemmy_jwt_token_{$account1->id}";
$cacheKey2 = "lemmy_jwt_token_{$account2->id}";
2025-08-10 04:16:53 +02:00
// Set up different cached tokens for each account
cache()->put($cacheKey1, 'token1', 3000);
cache()->put($cacheKey2, 'token2', 3000);
2025-08-06 21:49:13 +02:00
$result1 = LemmyAuthService::getToken($account1);
$result2 = LemmyAuthService::getToken($account2);
$this->assertEquals('token1', $result1);
$this->assertEquals('token2', $result2);
}
public function test_platform_auth_exception_contains_correct_platform(): void
{
2025-08-10 04:16:53 +02:00
// Mock HTTP to prevent any external calls
Http::fake(['*' => Http::response('', 500)]);
2025-08-06 21:49:13 +02:00
// Create account with valid data first, then modify username property
$account = PlatformAccount::factory()->create([
'username' => 'testuser',
'password' => 'testpass',
'instance_url' => 'https://lemmy.test'
]);
2025-08-10 01:26:56 +02:00
2025-08-06 21:49:13 +02:00
// Use reflection to set username to null to bypass validation
$reflection = new \ReflectionClass($account);
$property = $reflection->getProperty('attributes');
$property->setAccessible(true);
$attributes = $property->getValue($account);
$attributes['username'] = null;
$property->setValue($account, $attributes);
2025-08-10 04:16:53 +02:00
// Ensure no cached token exists
cache()->forget("lemmy_jwt_token_{$account->id}");
2025-08-06 21:49:13 +02:00
try {
LemmyAuthService::getToken($account);
$this->fail('Expected PlatformAuthException to be thrown');
} catch (PlatformAuthException $e) {
$this->assertEquals(PlatformEnum::LEMMY, $e->getPlatform());
}
}
2025-08-10 01:26:56 +02:00
}