2025-08-05 21:53:49 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Feature\Http\Controllers\Api\V1;
|
|
|
|
|
|
2025-08-15 16:39:18 +02:00
|
|
|
use Domains\Platform\Models\PlatformAccount;
|
|
|
|
|
use Domains\Platform\Models\PlatformChannel;
|
|
|
|
|
use Domains\Platform\Models\PlatformInstance;
|
2025-08-16 09:00:46 +02:00
|
|
|
use Domains\Platform\Services\ChannelLanguageDetectionService;
|
2025-08-16 11:34:52 +02:00
|
|
|
use Domains\Platform\Api\Lemmy\LemmyApiService;
|
2025-08-16 09:00:46 +02:00
|
|
|
use Domains\Settings\Models\Language;
|
2025-08-05 21:53:49 +02:00
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
2025-08-16 11:34:52 +02:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2025-08-05 21:53:49 +02:00
|
|
|
use Tests\TestCase;
|
2025-08-16 09:00:46 +02:00
|
|
|
use Mockery;
|
2025-08-05 21:53:49 +02:00
|
|
|
|
|
|
|
|
class PlatformChannelsControllerTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
use RefreshDatabase;
|
|
|
|
|
|
2025-08-16 09:00:46 +02:00
|
|
|
protected function tearDown(): void
|
|
|
|
|
{
|
|
|
|
|
Mockery::close();
|
|
|
|
|
parent::tearDown();
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-05 21:53:49 +02:00
|
|
|
public function test_index_returns_successful_response(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
PlatformChannel::factory()->count(3)->create(['platform_instance_id' => $instance->id]);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels');
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJsonStructure([
|
|
|
|
|
'success',
|
|
|
|
|
'message',
|
|
|
|
|
'data' => [
|
|
|
|
|
'*' => [
|
|
|
|
|
'id',
|
|
|
|
|
'platform_instance_id',
|
|
|
|
|
'channel_id',
|
|
|
|
|
'name',
|
|
|
|
|
'display_name',
|
|
|
|
|
'description',
|
|
|
|
|
'is_active',
|
|
|
|
|
'created_at',
|
|
|
|
|
'updated_at',
|
|
|
|
|
'platform_instance'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channels retrieved successfully.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_creates_platform_channel_successfully(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
2025-08-14 22:01:15 +02:00
|
|
|
|
|
|
|
|
// Create a platform account for this instance first
|
|
|
|
|
PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
2025-08-16 09:00:46 +02:00
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Create a language for the test
|
|
|
|
|
$language = Language::factory()->create([
|
|
|
|
|
'short_code' => 'en',
|
|
|
|
|
'name' => 'English',
|
2025-08-14 22:01:15 +02:00
|
|
|
'is_active' => true
|
|
|
|
|
]);
|
2025-08-05 21:53:49 +02:00
|
|
|
|
2025-08-16 09:00:46 +02:00
|
|
|
// Mock the ChannelLanguageDetectionService
|
|
|
|
|
$mockService = Mockery::mock(ChannelLanguageDetectionService::class);
|
|
|
|
|
$mockService->shouldReceive('detectChannelLanguages')
|
|
|
|
|
->with('Test Channel', $instance->id)
|
|
|
|
|
->once()
|
|
|
|
|
->andReturn([
|
|
|
|
|
'language_id' => $language->id,
|
|
|
|
|
'matched_languages' => [$language->id],
|
|
|
|
|
'community_details' => ['community' => ['id' => 123]]
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->app->bind(ChannelLanguageDetectionService::class, function () use ($mockService) {
|
|
|
|
|
return $mockService;
|
|
|
|
|
});
|
|
|
|
|
|
2025-08-05 21:53:49 +02:00
|
|
|
$data = [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'channel_id' => 'test_channel',
|
|
|
|
|
'name' => 'Test Channel',
|
|
|
|
|
'display_name' => 'Test Channel Display',
|
|
|
|
|
'description' => 'A test channel',
|
|
|
|
|
'is_active' => true
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', $data);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(201)
|
|
|
|
|
->assertJsonStructure([
|
|
|
|
|
'success',
|
|
|
|
|
'message',
|
|
|
|
|
'data' => [
|
|
|
|
|
'id',
|
|
|
|
|
'platform_instance_id',
|
|
|
|
|
'channel_id',
|
|
|
|
|
'name',
|
|
|
|
|
'display_name',
|
|
|
|
|
'description',
|
|
|
|
|
'is_active',
|
|
|
|
|
'created_at',
|
|
|
|
|
'updated_at',
|
|
|
|
|
]
|
|
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2025-08-14 22:01:15 +02:00
|
|
|
'message' => 'Platform channel created successfully and linked to platform account!'
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'channel_id' => 'test_channel',
|
|
|
|
|
'name' => 'Test Channel',
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_validates_required_fields(): void
|
|
|
|
|
{
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', []);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['platform_instance_id', 'channel_id', 'name']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_validates_platform_instance_exists(): void
|
|
|
|
|
{
|
|
|
|
|
$data = [
|
|
|
|
|
'platform_instance_id' => 999,
|
|
|
|
|
'channel_id' => 'test_channel',
|
|
|
|
|
'name' => 'Test Channel'
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', $data);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['platform_instance_id']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_show_returns_platform_channel_successfully(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $instance->id]);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson("/api/v1/platform-channels/{$channel->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJsonStructure([
|
|
|
|
|
'success',
|
|
|
|
|
'message',
|
|
|
|
|
'data' => [
|
|
|
|
|
'id',
|
|
|
|
|
'platform_instance_id',
|
|
|
|
|
'channel_id',
|
|
|
|
|
'name',
|
|
|
|
|
'display_name',
|
|
|
|
|
'description',
|
|
|
|
|
'is_active',
|
|
|
|
|
'created_at',
|
|
|
|
|
'updated_at',
|
|
|
|
|
'platform_instance'
|
|
|
|
|
]
|
|
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel retrieved successfully.',
|
|
|
|
|
'data' => [
|
|
|
|
|
'id' => $channel->id,
|
|
|
|
|
'name' => $channel->name,
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_update_modifies_platform_channel_successfully(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $instance->id]);
|
|
|
|
|
|
|
|
|
|
$updateData = [
|
|
|
|
|
'name' => 'Updated Channel',
|
|
|
|
|
'display_name' => 'Updated Display Name',
|
|
|
|
|
'description' => 'Updated description',
|
|
|
|
|
'is_active' => false
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$response = $this->putJson("/api/v1/platform-channels/{$channel->id}", $updateData);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel updated successfully!'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'id' => $channel->id,
|
|
|
|
|
'name' => 'Updated Channel',
|
|
|
|
|
'display_name' => 'Updated Display Name',
|
|
|
|
|
'is_active' => false,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_destroy_deletes_platform_channel_successfully(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $instance->id]);
|
|
|
|
|
|
|
|
|
|
$response = $this->deleteJson("/api/v1/platform-channels/{$channel->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel deleted successfully!'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseMissing('platform_channels', [
|
|
|
|
|
'id' => $channel->id
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_toggle_activates_inactive_channel(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'is_active' => false
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson("/api/v1/platform-channels/{$channel->id}/toggle");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel activated successfully!'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'id' => $channel->id,
|
|
|
|
|
'is_active' => true
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_toggle_deactivates_active_channel(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'is_active' => true
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson("/api/v1/platform-channels/{$channel->id}/toggle");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel deactivated successfully!'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'id' => $channel->id,
|
|
|
|
|
'is_active' => false
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-08-16 11:34:52 +02:00
|
|
|
|
|
|
|
|
public function test_get_communities_returns_successful_response(): void
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
$account = PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Mock LemmyApiService
|
|
|
|
|
$mockApiService = Mockery::mock(LemmyApiService::class);
|
|
|
|
|
$mockApiService->shouldReceive('listCommunities')
|
|
|
|
|
->with('test-token', 'Local', 'Active', 50, 1, false)
|
|
|
|
|
->once()
|
|
|
|
|
->andReturn([
|
|
|
|
|
'communities' => [
|
|
|
|
|
[
|
|
|
|
|
'community' => [
|
|
|
|
|
'id' => 1,
|
|
|
|
|
'name' => 'technology',
|
|
|
|
|
'title' => 'Technology',
|
|
|
|
|
'description' => 'Tech discussions',
|
|
|
|
|
'nsfw' => false,
|
|
|
|
|
'local' => true
|
|
|
|
|
],
|
|
|
|
|
'counts' => [
|
|
|
|
|
'subscribers' => 1500,
|
|
|
|
|
'posts' => 250
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'community' => [
|
|
|
|
|
'id' => 2,
|
|
|
|
|
'name' => 'news',
|
|
|
|
|
'title' => 'News',
|
|
|
|
|
'description' => 'Latest news',
|
|
|
|
|
'nsfw' => false,
|
|
|
|
|
'local' => true
|
|
|
|
|
],
|
|
|
|
|
'counts' => [
|
|
|
|
|
'subscribers' => 2300,
|
|
|
|
|
'posts' => 450
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->app->bind(LemmyApiService::class, function () use ($mockApiService) {
|
|
|
|
|
return $mockApiService;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=' . $instance->id);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJsonStructure([
|
|
|
|
|
'success',
|
|
|
|
|
'message',
|
|
|
|
|
'data' => [
|
|
|
|
|
'communities' => [
|
|
|
|
|
'*' => [
|
|
|
|
|
'id',
|
|
|
|
|
'name',
|
|
|
|
|
'title',
|
|
|
|
|
'description',
|
|
|
|
|
'nsfw',
|
|
|
|
|
'local',
|
|
|
|
|
'subscribers',
|
|
|
|
|
'posts',
|
|
|
|
|
'display_text'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'total',
|
|
|
|
|
'platform_instance' => [
|
|
|
|
|
'id',
|
|
|
|
|
'name',
|
|
|
|
|
'url'
|
|
|
|
|
],
|
|
|
|
|
'parameters' => [
|
|
|
|
|
'type',
|
|
|
|
|
'sort',
|
|
|
|
|
'limit',
|
|
|
|
|
'page',
|
|
|
|
|
'show_nsfw'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Communities retrieved successfully.',
|
|
|
|
|
'data' => [
|
|
|
|
|
'communities' => [
|
|
|
|
|
[
|
|
|
|
|
'id' => 1,
|
|
|
|
|
'name' => 'technology',
|
|
|
|
|
'title' => 'Technology',
|
|
|
|
|
'subscribers' => 1500,
|
|
|
|
|
'display_text' => 'Technology (1,500 subscribers)'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'id' => 2,
|
|
|
|
|
'name' => 'news',
|
|
|
|
|
'title' => 'News',
|
|
|
|
|
'subscribers' => 2300,
|
|
|
|
|
'display_text' => 'News (2,300 subscribers)'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'total' => 2,
|
|
|
|
|
'parameters' => [
|
|
|
|
|
'type' => 'Local',
|
|
|
|
|
'sort' => 'Active',
|
|
|
|
|
'limit' => 50,
|
|
|
|
|
'page' => 1,
|
|
|
|
|
'show_nsfw' => false
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_with_custom_parameters(): void
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
$account = PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Mock LemmyApiService with custom parameters
|
|
|
|
|
$mockApiService = Mockery::mock(LemmyApiService::class);
|
|
|
|
|
$mockApiService->shouldReceive('listCommunities')
|
|
|
|
|
->with('test-token', 'All', 'TopMonth', 25, 2, true)
|
|
|
|
|
->once()
|
|
|
|
|
->andReturn(['communities' => []]);
|
|
|
|
|
|
|
|
|
|
$this->app->bind(LemmyApiService::class, function () use ($mockApiService) {
|
|
|
|
|
return $mockApiService;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'type' => 'All',
|
|
|
|
|
'sort' => 'TopMonth',
|
|
|
|
|
'limit' => 25,
|
|
|
|
|
'page' => 2,
|
|
|
|
|
'show_nsfw' => true
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'data' => [
|
|
|
|
|
'parameters' => [
|
|
|
|
|
'type' => 'All',
|
|
|
|
|
'sort' => 'TopMonth',
|
|
|
|
|
'limit' => 25,
|
|
|
|
|
'page' => 2,
|
|
|
|
|
'show_nsfw' => true
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_required_platform_instance_id(): void
|
|
|
|
|
{
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities');
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['platform_instance_id']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_platform_instance_exists(): void
|
|
|
|
|
{
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=999');
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['platform_instance_id']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_type_parameter(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'type' => 'InvalidType'
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['type']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_sort_parameter(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'sort' => 'InvalidSort'
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['sort']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_limit_parameter(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'limit' => 0 // Invalid: below minimum
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['limit']);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'limit' => 101 // Invalid: above maximum
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['limit']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_validates_page_parameter(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?' . http_build_query([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'page' => 0 // Invalid: below minimum
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['page']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_fails_when_no_active_account_exists(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
|
|
|
|
|
// Create an inactive account
|
|
|
|
|
PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => false
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=' . $instance->id);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Cannot fetch communities: No active platform accounts found for this instance. Please create a platform account first.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_uses_cache(): void
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
$account = PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$mockData = ['communities' => [['community' => ['id' => 1, 'name' => 'test']]]];
|
|
|
|
|
$cacheKey = "communities:{$instance->id}:Local:Active:50:1:0";
|
|
|
|
|
|
|
|
|
|
// Set cache data
|
|
|
|
|
Cache::put($cacheKey, $mockData, 600);
|
|
|
|
|
|
|
|
|
|
// Mock should not be called since cache hit
|
|
|
|
|
$mockApiService = Mockery::mock(LemmyApiService::class);
|
|
|
|
|
$mockApiService->shouldNotReceive('listCommunities');
|
|
|
|
|
|
|
|
|
|
$this->app->bind(LemmyApiService::class, function () use ($mockApiService) {
|
|
|
|
|
return $mockApiService;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=' . $instance->id);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_clears_cache_on_error(): void
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
$account = PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$cacheKey = "communities:{$instance->id}:Local:Active:50:1:0";
|
|
|
|
|
|
|
|
|
|
// Mock LemmyApiService to throw exception
|
|
|
|
|
$mockApiService = Mockery::mock(LemmyApiService::class);
|
|
|
|
|
$mockApiService->shouldReceive('listCommunities')
|
|
|
|
|
->once()
|
|
|
|
|
->andThrow(new \Exception('API Error'));
|
|
|
|
|
|
|
|
|
|
$this->app->bind(LemmyApiService::class, function () use ($mockApiService) {
|
|
|
|
|
return $mockApiService;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Ensure cache is empty initially so API service gets called
|
|
|
|
|
Cache::forget($cacheKey);
|
|
|
|
|
$this->assertFalse(Cache::has($cacheKey));
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=' . $instance->id);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
$response->assertStatus(500);
|
|
|
|
|
// Cache should still not exist since the error prevented caching
|
|
|
|
|
$this->assertFalse(Cache::has($cacheKey));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_get_communities_handles_missing_community_data_gracefully(): void
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
$instance = PlatformInstance::factory()->create(['url' => 'lemmy.world']);
|
|
|
|
|
$account = PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'settings' => ['api_token' => 'test-token']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Mock LemmyApiService with incomplete community data
|
|
|
|
|
$mockApiService = Mockery::mock(LemmyApiService::class);
|
|
|
|
|
$mockApiService->shouldReceive('listCommunities')
|
|
|
|
|
->once()
|
|
|
|
|
->andReturn([
|
|
|
|
|
'communities' => [
|
|
|
|
|
[
|
|
|
|
|
'community' => [
|
|
|
|
|
'id' => 1,
|
|
|
|
|
'name' => 'minimal',
|
|
|
|
|
// Missing title, description, etc.
|
|
|
|
|
],
|
|
|
|
|
// Missing counts
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->app->bind(LemmyApiService::class, function () use ($mockApiService) {
|
|
|
|
|
return $mockApiService;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
$response = $this->getJson('/api/v1/platform-channels/communities?platform_instance_id=' . $instance->id);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'data' => [
|
|
|
|
|
'communities' => [
|
|
|
|
|
[
|
|
|
|
|
'id' => 1,
|
|
|
|
|
'name' => 'minimal',
|
|
|
|
|
'title' => null,
|
|
|
|
|
'description' => null,
|
|
|
|
|
'nsfw' => false,
|
|
|
|
|
'local' => false,
|
|
|
|
|
'subscribers' => 0,
|
|
|
|
|
'posts' => 0,
|
|
|
|
|
'display_text' => 'minimal (0 subscribers)'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-08-05 21:53:49 +02:00
|
|
|
}
|