assertInstanceOf(LemmyApiService::class, $service); } public function test_login_successful(): void { Http::fake([ 'https://lemmy.test/api/v3/user/login' => Http::response([ 'jwt' => 'test-jwt-token' ], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->login('testuser', 'testpass'); $this->assertEquals('test-jwt-token', $result); Http::assertSent(function ($request) { return $request->url() === 'https://lemmy.test/api/v3/user/login' && $request->method() === 'POST' && $request->data() === [ 'username_or_email' => 'testuser', 'password' => 'testpass' ]; }); } public function test_login_failed_response(): void { Http::fake([ 'https://lemmy.test/api/v3/user/login' => Http::response(['error' => 'Invalid credentials'], 401) ]); Log::shouldReceive('error') ->once() ->with('Lemmy login failed', Mockery::type('array')); $service = new LemmyApiService('lemmy.test'); $result = $service->login('testuser', 'wrongpass'); $this->assertNull($result); } public function test_login_missing_jwt_in_response(): void { Http::fake([ 'https://lemmy.test/api/v3/user/login' => Http::response(['success' => true], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->login('testuser', 'testpass'); $this->assertNull($result); } public function test_login_exception_handling(): void { Http::fake([ 'https://lemmy.test/api/v3/user/login' => function () { throw new Exception('Network error'); } ]); Log::shouldReceive('error') ->once() ->with('Lemmy login exception', ['error' => 'Network error']); $service = new LemmyApiService('lemmy.test'); $result = $service->login('testuser', 'testpass'); $this->assertNull($result); } public function test_get_community_id_successful(): void { Http::fake([ 'https://lemmy.test/api/v3/community*' => Http::response([ 'community_view' => [ 'community' => [ 'id' => 123 ] ] ], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->getCommunityId('testcommunity', 'test-token'); $this->assertEquals(123, $result); Http::assertSent(function ($request) { return str_contains($request->url(), 'community') && $request->hasHeader('Authorization', 'Bearer test-token'); }); } public function test_get_community_id_failed_response(): void { Http::fake([ 'https://lemmy.test/api/v3/community*' => Http::response(['error' => 'Not found'], 404) ]); Log::shouldReceive('error') ->once() ->with('Community lookup failed', Mockery::type('array')); $service = new LemmyApiService('lemmy.test'); $this->expectException(Exception::class); $this->expectExceptionMessage('Failed to fetch community: 404'); $service->getCommunityId('nonexistent', 'test-token'); } public function test_get_community_id_missing_data(): void { Http::fake([ 'https://lemmy.test/api/v3/community*' => Http::response([ 'community_view' => ['community' => []] ], 200) ]); Log::shouldReceive('error') ->once() ->with('Community lookup failed', Mockery::type('array')); $service = new LemmyApiService('lemmy.test'); $this->expectException(Exception::class); $this->expectExceptionMessage('Community not found'); $service->getCommunityId('testcommunity', 'test-token'); } public function test_sync_channel_posts_successful(): void { Http::fake([ 'https://lemmy.test/api/v3/post/list*' => Http::response([ 'posts' => [ [ 'post' => [ 'id' => 1, 'name' => 'Test Post 1', 'url' => 'https://example.com/1', 'published' => '2023-01-01T00:00:00Z' ] ], [ 'post' => [ 'id' => 2, 'name' => 'Test Post 2', 'published' => '2023-01-02T00:00:00Z' ] ] ] ], 200) ]); Log::shouldReceive('info') ->once() ->with('Synced channel posts', [ 'platform_channel_id' => 123, 'posts_count' => 2 ]); $service = new LemmyApiService('lemmy.test'); $service->syncChannelPosts('test-token', 123, 'testcommunity'); // Verify posts were stored $this->assertDatabaseCount('platform_channel_posts', 2); $this->assertDatabaseHas('platform_channel_posts', [ 'platform' => PlatformEnum::LEMMY, 'channel_id' => '123', 'post_id' => '1' ]); } public function test_sync_channel_posts_failed_response(): void { Http::fake([ 'https://lemmy.test/api/v3/post/list*' => Http::response(['error' => 'Unauthorized'], 401) ]); Log::shouldReceive('warning') ->once() ->with('Failed to sync channel posts', [ 'status' => 401, 'platform_channel_id' => 123 ]); $service = new LemmyApiService('lemmy.test'); $service->syncChannelPosts('test-token', 123, 'testcommunity'); // Verify no posts were stored $this->assertDatabaseCount('platform_channel_posts', 0); } public function test_sync_channel_posts_exception_handling(): void { Http::fake([ 'https://lemmy.test/api/v3/post/list*' => function () { throw new Exception('Network error'); } ]); Log::shouldReceive('error') ->once() ->with('Exception while syncing channel posts', [ 'error' => 'Network error', 'platform_channel_id' => 123 ]); $service = new LemmyApiService('lemmy.test'); $service->syncChannelPosts('test-token', 123, 'testcommunity'); $this->assertDatabaseCount('platform_channel_posts', 0); } public function test_create_post_successful_minimal_data(): void { Http::fake([ 'https://lemmy.test/api/v3/post' => Http::response([ 'post_view' => [ 'post' => [ 'id' => 456, 'name' => 'Test Title' ] ] ], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->createPost('test-token', 'Test Title', 'Test Body', 123); $this->assertIsArray($result); $this->assertEquals(456, $result['post_view']['post']['id']); Http::assertSent(function ($request) { return $request->url() === 'https://lemmy.test/api/v3/post' && $request->method() === 'POST' && $request->data() === [ 'name' => 'Test Title', 'body' => 'Test Body', 'community_id' => 123 ]; }); } public function test_create_post_successful_with_all_optional_data(): void { Http::fake([ 'https://lemmy.test/api/v3/post' => Http::response([ 'post_view' => ['post' => ['id' => 456]] ], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->createPost( 'test-token', 'Test Title', 'Test Body', 123, 'https://example.com', 'https://example.com/thumb.jpg', 2 ); $this->assertIsArray($result); Http::assertSent(function ($request) { return $request->data() === [ 'name' => 'Test Title', 'body' => 'Test Body', 'community_id' => 123, 'url' => 'https://example.com', 'custom_thumbnail' => 'https://example.com/thumb.jpg', 'language_id' => 2 ]; }); } public function test_create_post_failed_response(): void { Http::fake([ 'https://lemmy.test/api/v3/post' => Http::response(['error' => 'Validation failed'], 400) ]); Log::shouldReceive('error') ->once() ->with('Post creation failed', Mockery::type('array')); $service = new LemmyApiService('lemmy.test'); $this->expectException(Exception::class); $this->expectExceptionMessage('Failed to create post: 400'); $service->createPost('test-token', 'Test Title', 'Test Body', 123); } public function test_create_post_exception_handling(): void { Http::fake([ 'https://lemmy.test/api/v3/post' => function () { throw new Exception('Network error'); } ]); Log::shouldReceive('error') ->once() ->with('Post creation failed', ['error' => 'Network error']); $service = new LemmyApiService('lemmy.test'); $this->expectException(Exception::class); $this->expectExceptionMessage('Network error'); $service->createPost('test-token', 'Test Title', 'Test Body', 123); } public function test_get_languages_successful(): void { Http::fake([ 'https://lemmy.test/api/v3/site' => Http::response([ 'all_languages' => [ ['id' => 0, 'code' => 'und', 'name' => 'Undetermined'], ['id' => 1, 'code' => 'en', 'name' => 'English'], ['id' => 2, 'code' => 'es', 'name' => 'Spanish'] ] ], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->getLanguages(); $this->assertIsArray($result); $this->assertCount(3, $result); $this->assertEquals('English', $result[1]['name']); } public function test_get_languages_failed_response(): void { Http::fake([ 'https://lemmy.test/api/v3/site' => Http::response(['error' => 'Server error'], 500) ]); Log::shouldReceive('warning') ->once() ->with('Failed to fetch site languages', ['status' => 500]); $service = new LemmyApiService('lemmy.test'); $result = $service->getLanguages(); $this->assertIsArray($result); $this->assertEmpty($result); } public function test_get_languages_missing_data(): void { Http::fake([ 'https://lemmy.test/api/v3/site' => Http::response(['site_view' => []], 200) ]); $service = new LemmyApiService('lemmy.test'); $result = $service->getLanguages(); $this->assertIsArray($result); $this->assertEmpty($result); } public function test_get_languages_exception_handling(): void { Http::fake([ 'https://lemmy.test/api/v3/site' => function () { throw new Exception('Network error'); } ]); Log::shouldReceive('error') ->once() ->with('Exception while fetching languages', ['error' => 'Network error']); $service = new LemmyApiService('lemmy.test'); $result = $service->getLanguages(); $this->assertIsArray($result); $this->assertEmpty($result); } }