2025-08-05 21:53:49 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Feature\Http\Controllers\Api\V1;
|
|
|
|
|
|
2025-08-14 22:01:15 +02:00
|
|
|
use App\Models\PlatformAccount;
|
2025-08-05 21:53:49 +02:00
|
|
|
use App\Models\PlatformChannel;
|
|
|
|
|
use App\Models\PlatformInstance;
|
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
2026-08-06 00:20:49 +02:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
|
use Illuminate\Support\Facades\Http;
|
2025-08-05 21:53:49 +02:00
|
|
|
use Tests\TestCase;
|
|
|
|
|
|
|
|
|
|
class PlatformChannelsControllerTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
use RefreshDatabase;
|
|
|
|
|
|
2026-08-06 00:20:49 +02:00
|
|
|
private bool $instanceReachable = true;
|
|
|
|
|
|
|
|
|
|
protected function setUp(): void
|
|
|
|
|
{
|
|
|
|
|
parent::setUp();
|
|
|
|
|
Cache::flush();
|
|
|
|
|
// A stub registered here cannot be overridden by a later Http::fake() for the
|
|
|
|
|
// same pattern, so tests toggle the outcome through $instanceReachable instead.
|
|
|
|
|
Http::fake(['*/api/v3/community/list*' => fn () => $this->instanceReachable
|
|
|
|
|
? Http::response([
|
|
|
|
|
'communities' => [
|
|
|
|
|
['community' => ['id' => 8, 'name' => 'test_channel', 'title' => 'Test Channel']],
|
|
|
|
|
['community' => ['id' => 9, 'name' => 'tech_news', 'title' => 'Tech News']],
|
|
|
|
|
],
|
|
|
|
|
])
|
|
|
|
|
: Http::response([], 503)]);
|
|
|
|
|
}
|
|
|
|
|
|
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',
|
2026-03-08 14:18:28 +01:00
|
|
|
'platform_instance',
|
|
|
|
|
],
|
|
|
|
|
],
|
2025-08-05 21:53:49 +02:00
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2026-03-08 14:18:28 +01:00
|
|
|
'message' => 'Platform channels retrieved successfully.',
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_creates_platform_channel_successfully(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
2026-03-08 14:18:28 +01:00
|
|
|
|
2025-08-14 22:01:15 +02:00
|
|
|
// Create a platform account for this instance first
|
|
|
|
|
PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => true,
|
2025-08-14 22:01:15 +02:00
|
|
|
]);
|
2025-08-05 21:53:49 +02:00
|
|
|
|
|
|
|
|
$data = [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 8,
|
2025-08-05 21:53:49 +02:00
|
|
|
'description' => 'A test channel',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$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',
|
2026-03-08 14:18:28 +01:00
|
|
|
],
|
2025-08-05 21:53:49 +02:00
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2026-03-08 14:18:28 +01: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,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 8,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_validates_required_fields(): void
|
|
|
|
|
{
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', []);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
2026-08-06 00:20:49 +02:00
|
|
|
->assertJsonValidationErrors(['platform_instance_id', 'channel_id']);
|
2025-08-05 21:53:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_validates_platform_instance_exists(): void
|
|
|
|
|
{
|
|
|
|
|
$data = [
|
|
|
|
|
'platform_instance_id' => 999,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 8,
|
2025-08-05 21:53:49 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', $data);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
|
->assertJsonValidationErrors(['platform_instance_id']);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 00:20:49 +02:00
|
|
|
public function test_store_rejects_community_not_on_instance(): void
|
2026-07-29 20:15:43 +02:00
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 4242,
|
2026-07-29 20:15:43 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
2026-08-06 00:20:49 +02:00
|
|
|
->assertJsonValidationErrors(['channel_id']);
|
2026-07-29 20:15:43 +02:00
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('platform_channels', 0);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 00:20:49 +02:00
|
|
|
public function test_store_distinguishes_an_unreachable_instance_from_a_missing_community(): void
|
|
|
|
|
{
|
|
|
|
|
$this->instanceReachable = false;
|
|
|
|
|
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instance->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'channel_id' => 8,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422);
|
|
|
|
|
$this->assertStringContainsString('Could not reach this instance', $response->json('message'));
|
|
|
|
|
$this->assertDatabaseCount('platform_channels', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_store_rejects_duplicate_community_for_same_instance(): void
|
2026-07-29 20:15:43 +02:00
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
|
|
|
|
'name' => 'tech_news',
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 9,
|
2026-07-29 20:15:43 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', [
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 9,
|
2026-07-29 20:15:43 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
2026-08-06 00:20:49 +02:00
|
|
|
->assertJsonValidationErrors(['channel_id']);
|
2026-07-29 20:15:43 +02:00
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('platform_channels', 1);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 00:20:49 +02:00
|
|
|
public function test_store_allows_same_community_on_different_instance(): void
|
2026-07-29 20:15:43 +02:00
|
|
|
{
|
|
|
|
|
$instanceA = PlatformInstance::factory()->create();
|
|
|
|
|
$instanceB = PlatformInstance::factory()->create();
|
|
|
|
|
|
|
|
|
|
PlatformAccount::factory()->create([
|
|
|
|
|
'instance_url' => $instanceB->url,
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instanceA->id,
|
|
|
|
|
'name' => 'tech_news',
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 9,
|
2026-07-29 20:15:43 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/v1/platform-channels', [
|
|
|
|
|
'platform_instance_id' => $instanceB->id,
|
2026-08-06 00:20:49 +02:00
|
|
|
'channel_id' => 9,
|
2026-07-29 20:15:43 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(201);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('platform_channels', 2);
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-05 21:53:49 +02:00
|
|
|
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',
|
2026-03-08 14:18:28 +01:00
|
|
|
'platform_instance',
|
|
|
|
|
],
|
2025-08-05 21:53:49 +02:00
|
|
|
])
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Platform channel retrieved successfully.',
|
|
|
|
|
'data' => [
|
|
|
|
|
'id' => $channel->id,
|
|
|
|
|
'name' => $channel->name,
|
2026-03-08 14:18:28 +01:00
|
|
|
],
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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',
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => false,
|
2025-08-05 21:53:49 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$response = $this->putJson("/api/v1/platform-channels/{$channel->id}", $updateData);
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2026-03-08 14:18:28 +01:00
|
|
|
'message' => 'Platform channel updated successfully!',
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$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,
|
2026-03-08 14:18:28 +01:00
|
|
|
'message' => 'Platform channel deleted successfully!',
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseMissing('platform_channels', [
|
2026-03-08 14:18:28 +01:00
|
|
|
'id' => $channel->id,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_toggle_activates_inactive_channel(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => false,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson("/api/v1/platform-channels/{$channel->id}/toggle");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2026-03-08 14:18:28 +01:00
|
|
|
'message' => 'Platform channel activated successfully!',
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'id' => $channel->id,
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => true,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_toggle_deactivates_active_channel(): void
|
|
|
|
|
{
|
|
|
|
|
$instance = PlatformInstance::factory()->create();
|
|
|
|
|
$channel = PlatformChannel::factory()->create([
|
|
|
|
|
'platform_instance_id' => $instance->id,
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => true,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson("/api/v1/platform-channels/{$channel->id}/toggle");
|
|
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
|
->assertJson([
|
|
|
|
|
'success' => true,
|
2026-03-08 14:18:28 +01:00
|
|
|
'message' => 'Platform channel deactivated successfully!',
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('platform_channels', [
|
|
|
|
|
'id' => $channel->id,
|
2026-03-08 14:18:28 +01:00
|
|
|
'is_active' => false,
|
2025-08-05 21:53:49 +02:00
|
|
|
]);
|
|
|
|
|
}
|
2026-03-08 14:18:28 +01:00
|
|
|
}
|