fedi-feed-router/backend/tests/Unit/Modules/Lemmy/LemmyRequestTest.php

273 lines
9.4 KiB
PHP
Raw Normal View History

2025-08-10 04:16:53 +02:00
<?php
namespace Tests\Unit\Modules\Lemmy;
use App\Modules\Lemmy\LemmyRequest;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class LemmyRequestTest extends TestCase
{
public function test_constructor_with_simple_domain(): void
{
$request = new LemmyRequest('lemmy.world');
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
$this->assertEquals('lemmy.world', $this->getPrivateProperty($request, 'instance'));
$this->assertNull($this->getPrivateProperty($request, 'token'));
}
public function test_constructor_with_https_url(): void
{
$request = new LemmyRequest('https://lemmy.world');
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
$this->assertEquals('lemmy.world', $this->getPrivateProperty($request, 'instance'));
}
public function test_constructor_with_http_url(): void
{
$request = new LemmyRequest('http://lemmy.world');
$this->assertEquals('http', $this->getPrivateProperty($request, 'scheme'));
$this->assertEquals('lemmy.world', $this->getPrivateProperty($request, 'instance'));
}
public function test_constructor_with_trailing_slash(): void
{
$request = new LemmyRequest('lemmy.world/');
$this->assertEquals('lemmy.world', $this->getPrivateProperty($request, 'instance'));
}
public function test_constructor_with_full_url_and_trailing_slash(): void
{
$request = new LemmyRequest('https://lemmy.world/');
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
$this->assertEquals('lemmy.world', $this->getPrivateProperty($request, 'instance'));
}
public function test_constructor_with_token(): void
{
$request = new LemmyRequest('lemmy.world', 'test-token');
$this->assertEquals('test-token', $this->getPrivateProperty($request, 'token'));
}
public function test_constructor_preserves_case_in_scheme_detection(): void
{
$request = new LemmyRequest('HTTPS://lemmy.world');
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
}
public function test_with_scheme_sets_https(): void
{
$request = new LemmyRequest('lemmy.world');
$result = $request->withScheme('https');
$this->assertSame($request, $result);
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
}
public function test_with_scheme_sets_http(): void
{
$request = new LemmyRequest('lemmy.world');
$result = $request->withScheme('http');
$this->assertSame($request, $result);
$this->assertEquals('http', $this->getPrivateProperty($request, 'scheme'));
}
public function test_with_scheme_normalizes_case(): void
{
$request = new LemmyRequest('lemmy.world');
$request->withScheme('HTTPS');
$this->assertEquals('https', $this->getPrivateProperty($request, 'scheme'));
}
public function test_with_scheme_ignores_invalid_schemes(): void
{
$request = new LemmyRequest('lemmy.world');
$originalScheme = $this->getPrivateProperty($request, 'scheme');
$request->withScheme('ftp');
$this->assertEquals($originalScheme, $this->getPrivateProperty($request, 'scheme'));
}
public function test_with_token_sets_token(): void
{
$request = new LemmyRequest('lemmy.world');
$result = $request->withToken('new-token');
$this->assertSame($request, $result);
$this->assertEquals('new-token', $this->getPrivateProperty($request, 'token'));
}
public function test_get_without_token(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$response = $request->get('site');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/site'
&& !$httpRequest->hasHeader('Authorization');
});
}
public function test_get_with_token(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world', 'test-token');
$response = $request->get('site');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/site'
&& $httpRequest->header('Authorization')[0] === 'Bearer test-token';
});
}
public function test_get_with_parameters(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$params = ['limit' => 10, 'page' => 1];
$response = $request->get('posts', $params);
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) use ($params) {
$url = $httpRequest->url();
return str_contains($url, 'https://lemmy.world/api/v3/posts')
&& str_contains($url, 'limit=10')
&& str_contains($url, 'page=1');
});
}
public function test_get_with_http_scheme(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$request->withScheme('http');
$response = $request->get('site');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'http://lemmy.world/api/v3/site';
});
}
public function test_post_without_token(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$response = $request->post('login');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/login'
&& $httpRequest->method() === 'POST'
&& !$httpRequest->hasHeader('Authorization');
});
}
public function test_post_with_token(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world', 'test-token');
$response = $request->post('login');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/login'
&& $httpRequest->method() === 'POST'
&& $httpRequest->header('Authorization')[0] === 'Bearer test-token';
});
}
public function test_post_with_data(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$data = ['username' => 'test', 'password' => 'pass'];
$response = $request->post('login', $data);
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) use ($data) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/login'
&& $httpRequest->method() === 'POST'
&& $httpRequest->data() === $data;
});
}
public function test_post_with_http_scheme(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$request->withScheme('http');
$response = $request->post('login');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'http://lemmy.world/api/v3/login';
});
}
public function test_requests_use_30_second_timeout(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$request->get('site');
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'https://lemmy.world/api/v3/site';
});
}
public function test_chaining_methods(): void
{
Http::fake(['*' => Http::response(['success' => true])]);
$request = new LemmyRequest('lemmy.world');
$response = $request->withScheme('http')->withToken('chained-token')->get('site');
$this->assertInstanceOf(Response::class, $response);
Http::assertSent(function ($httpRequest) {
return $httpRequest->url() === 'http://lemmy.world/api/v3/site'
&& $httpRequest->header('Authorization')[0] === 'Bearer chained-token';
});
}
private function getPrivateProperty(object $object, string $property): mixed
{
$reflection = new \ReflectionClass($object);
$reflectionProperty = $reflection->getProperty($property);
$reflectionProperty->setAccessible(true);
return $reflectionProperty->getValue($object);
}
}