fedi-feed-router/backend/tests/Unit/Models/PlatformInstanceTest.php

325 lines
No EOL
11 KiB
PHP

<?php
namespace Tests\Unit\Models;
use App\Enums\PlatformEnum;
use App\Models\Language;
use App\Models\PlatformChannel;
use App\Models\PlatformInstance;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PlatformInstanceTest extends TestCase
{
use RefreshDatabase;
public function test_fillable_fields(): void
{
$fillableFields = ['platform', 'url', 'name', 'description', 'is_active'];
$instance = new PlatformInstance();
$this->assertEquals($fillableFields, $instance->getFillable());
}
public function test_table_name(): void
{
$instance = new PlatformInstance();
$this->assertEquals('platform_instances', $instance->getTable());
}
public function test_casts_platform_to_enum(): void
{
$instance = PlatformInstance::factory()->create(['platform' => PlatformEnum::LEMMY]);
$this->assertInstanceOf(PlatformEnum::class, $instance->platform);
$this->assertEquals(PlatformEnum::LEMMY, $instance->platform);
$this->assertEquals('lemmy', $instance->platform->value);
}
public function test_casts_is_active_to_boolean(): void
{
$instance = PlatformInstance::factory()->create(['is_active' => '1']);
$this->assertIsBool($instance->is_active);
$this->assertTrue($instance->is_active);
$instance->update(['is_active' => '0']);
$instance->refresh();
$this->assertIsBool($instance->is_active);
$this->assertFalse($instance->is_active);
}
public function test_has_many_channels_relationship(): void
{
$instance = PlatformInstance::factory()->create();
$channel1 = PlatformChannel::factory()->create(['platform_instance_id' => $instance->id]);
$channel2 = PlatformChannel::factory()->create(['platform_instance_id' => $instance->id]);
// Create channel for different instance
$otherInstance = PlatformInstance::factory()->create();
PlatformChannel::factory()->create(['platform_instance_id' => $otherInstance->id]);
$channels = $instance->channels;
$this->assertCount(2, $channels);
$this->assertTrue($channels->contains('id', $channel1->id));
$this->assertTrue($channels->contains('id', $channel2->id));
$this->assertInstanceOf(PlatformChannel::class, $channels->first());
}
public function test_belongs_to_many_languages_relationship(): void
{
$instance = PlatformInstance::factory()->create();
$language1 = Language::factory()->create();
$language2 = Language::factory()->create();
// Attach languages with pivot data
$instance->languages()->attach($language1->id, [
'platform_language_id' => 1,
'is_default' => true
]);
$instance->languages()->attach($language2->id, [
'platform_language_id' => 2,
'is_default' => false
]);
$languages = $instance->languages;
$this->assertCount(2, $languages);
$this->assertTrue($languages->contains('id', $language1->id));
$this->assertTrue($languages->contains('id', $language2->id));
// Test pivot data
$language1FromRelation = $languages->find($language1->id);
$this->assertEquals(1, $language1FromRelation->pivot->platform_language_id);
$this->assertEquals(1, $language1FromRelation->pivot->is_default); // Database returns 1 for true
$language2FromRelation = $languages->find($language2->id);
$this->assertEquals(2, $language2FromRelation->pivot->platform_language_id);
$this->assertEquals(0, $language2FromRelation->pivot->is_default); // Database returns 0 for false
}
public function test_find_by_url_static_method(): void
{
$url = 'https://lemmy.world';
$instance1 = PlatformInstance::factory()->create([
'platform' => PlatformEnum::LEMMY,
'url' => $url
]);
// Create instance with different URL
PlatformInstance::factory()->create([
'platform' => PlatformEnum::LEMMY,
'url' => 'https://lemmy.ml'
]);
$foundInstance = PlatformInstance::findByUrl(PlatformEnum::LEMMY, $url);
$this->assertNotNull($foundInstance);
$this->assertEquals($instance1->id, $foundInstance->id);
$this->assertEquals($url, $foundInstance->url);
$this->assertEquals(PlatformEnum::LEMMY, $foundInstance->platform);
}
public function test_find_by_url_returns_null_when_not_found(): void
{
$foundInstance = PlatformInstance::findByUrl(PlatformEnum::LEMMY, 'https://nonexistent.lemmy');
$this->assertNull($foundInstance);
}
public function test_find_by_url_filters_by_platform(): void
{
$url = 'https://example.com';
// Create instance with same URL but different platform won't be found
PlatformInstance::factory()->create([
'platform' => PlatformEnum::LEMMY,
'url' => $url
]);
// Since we only have LEMMY in the enum, this test demonstrates the filtering logic
$foundInstance = PlatformInstance::findByUrl(PlatformEnum::LEMMY, $url);
$this->assertNotNull($foundInstance);
}
public function test_instance_creation_with_factory(): void
{
$instance = PlatformInstance::factory()->create();
$this->assertInstanceOf(PlatformInstance::class, $instance);
$this->assertEquals('lemmy', $instance->platform->value);
$this->assertIsString($instance->name);
$this->assertIsString($instance->url);
$this->assertTrue($instance->is_active);
}
public function test_instance_creation_with_explicit_values(): void
{
$instance = PlatformInstance::create([
'platform' => PlatformEnum::LEMMY,
'url' => 'https://lemmy.world',
'name' => 'Lemmy World',
'description' => 'A general purpose Lemmy instance',
'is_active' => false
]);
$this->assertEquals(PlatformEnum::LEMMY, $instance->platform);
$this->assertEquals('https://lemmy.world', $instance->url);
$this->assertEquals('Lemmy World', $instance->name);
$this->assertEquals('A general purpose Lemmy instance', $instance->description);
$this->assertFalse($instance->is_active);
}
public function test_instance_factory_states(): void
{
$inactiveInstance = PlatformInstance::factory()->inactive()->create();
$this->assertFalse($inactiveInstance->is_active);
$lemmyInstance = PlatformInstance::factory()->lemmy()->create();
$this->assertEquals(PlatformEnum::LEMMY, $lemmyInstance->platform);
$this->assertStringStartsWith('Lemmy ', $lemmyInstance->name);
$this->assertStringStartsWith('https://lemmy.', $lemmyInstance->url);
}
public function test_instance_update(): void
{
$instance = PlatformInstance::factory()->create([
'name' => 'Original Name',
'is_active' => true
]);
$instance->update([
'name' => 'Updated Name',
'is_active' => false
]);
$instance->refresh();
$this->assertEquals('Updated Name', $instance->name);
$this->assertFalse($instance->is_active);
}
public function test_instance_deletion(): void
{
$instance = PlatformInstance::factory()->create();
$instanceId = $instance->id;
$instance->delete();
$this->assertDatabaseMissing('platform_instances', ['id' => $instanceId]);
}
public function test_instance_can_have_null_description(): void
{
$instance = PlatformInstance::factory()->create(['description' => null]);
$this->assertNull($instance->description);
}
public function test_instance_can_have_empty_description(): void
{
$instance = PlatformInstance::factory()->create(['description' => '']);
$this->assertEquals('', $instance->description);
}
public function test_instance_url_validation(): void
{
$validUrls = [
'https://lemmy.world',
'https://lemmy.ml',
'https://beehaw.org',
'http://localhost:8080',
];
foreach ($validUrls as $url) {
$instance = PlatformInstance::factory()->create(['url' => $url]);
$this->assertEquals($url, $instance->url);
}
}
public function test_instance_timestamps(): void
{
$instance = PlatformInstance::factory()->create();
$this->assertNotNull($instance->created_at);
$this->assertNotNull($instance->updated_at);
$this->assertInstanceOf(\Carbon\Carbon::class, $instance->created_at);
$this->assertInstanceOf(\Carbon\Carbon::class, $instance->updated_at);
}
public function test_instance_can_have_multiple_languages(): void
{
$instance = PlatformInstance::factory()->create();
$language1 = Language::factory()->create();
$language2 = Language::factory()->create();
$language3 = Language::factory()->create();
// Attach multiple languages with different pivot data
$instance->languages()->attach([
$language1->id => ['platform_language_id' => 1, 'is_default' => true],
$language2->id => ['platform_language_id' => 2, 'is_default' => false],
$language3->id => ['platform_language_id' => 3, 'is_default' => false]
]);
$languages = $instance->languages;
$this->assertCount(3, $languages);
// Test that we can access pivot data
foreach ($languages as $language) {
$this->assertNotNull($language->pivot->platform_language_id);
$this->assertContains($language->pivot->is_default, [0, 1, true, false]); // Can be int or bool
}
// Only one should be default
$defaultLanguages = $languages->filter(fn($lang) => $lang->pivot->is_default);
$this->assertCount(1, $defaultLanguages);
}
public function test_instance_channels_relationship_is_empty_by_default(): void
{
$instance = PlatformInstance::factory()->create();
$this->assertCount(0, $instance->channels);
}
public function test_instance_languages_relationship_is_empty_by_default(): void
{
$instance = PlatformInstance::factory()->create();
$this->assertCount(0, $instance->languages);
}
public function test_multiple_instances_with_same_platform(): void
{
$instance1 = PlatformInstance::factory()->create([
'platform' => PlatformEnum::LEMMY,
'name' => 'Lemmy World'
]);
$instance2 = PlatformInstance::factory()->create([
'platform' => PlatformEnum::LEMMY,
'name' => 'Lemmy ML'
]);
$this->assertEquals(PlatformEnum::LEMMY, $instance1->platform);
$this->assertEquals(PlatformEnum::LEMMY, $instance2->platform);
$this->assertNotEquals($instance1->id, $instance2->id);
$this->assertNotEquals($instance1->name, $instance2->name);
}
public function test_instance_platform_enum_string_value(): void
{
$instance = PlatformInstance::factory()->create(['platform' => 'lemmy']);
$this->assertEquals('lemmy', $instance->platform->value);
$this->assertEquals(PlatformEnum::LEMMY, $instance->platform);
}
}