From fc1c8ba0202020b86d3a4639bacb3b2408501db8 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Thu, 23 Apr 2026 23:26:53 +0200 Subject: [PATCH] 2 - Add Instance Eloquent model with factory --- ...7_create_fedi_discover_instances_table.php | 2 +- .../Database/Factories/InstanceFactory.php | 26 ++++++ .../Lvl0/FediDiscover/src/Models/Instance.php | 38 ++++++++ .../tests/Feature/InstanceModelTest.php | 88 +++++++++++++++++++ 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 packages/Lvl0/FediDiscover/src/Database/Factories/InstanceFactory.php create mode 100644 packages/Lvl0/FediDiscover/src/Models/Instance.php create mode 100644 packages/Lvl0/FediDiscover/tests/Feature/InstanceModelTest.php diff --git a/packages/Lvl0/FediDiscover/database/migrations/2026_04_23_205027_create_fedi_discover_instances_table.php b/packages/Lvl0/FediDiscover/database/migrations/2026_04_23_205027_create_fedi_discover_instances_table.php index eee4cc8..841949d 100644 --- a/packages/Lvl0/FediDiscover/database/migrations/2026_04_23_205027_create_fedi_discover_instances_table.php +++ b/packages/Lvl0/FediDiscover/database/migrations/2026_04_23_205027_create_fedi_discover_instances_table.php @@ -17,7 +17,7 @@ public function up(): void $table->string('url'); $table->boolean('enabled')->default(true); $table->unsignedInteger('interval_seconds')->default(300); - $table->json('config')->default('{}'); + $table->json('extras')->default('{}'); $table->timestampTz('last_polled_at')->nullable(); $table->timestamps(); diff --git a/packages/Lvl0/FediDiscover/src/Database/Factories/InstanceFactory.php b/packages/Lvl0/FediDiscover/src/Database/Factories/InstanceFactory.php new file mode 100644 index 0000000..f6dc60d --- /dev/null +++ b/packages/Lvl0/FediDiscover/src/Database/Factories/InstanceFactory.php @@ -0,0 +1,26 @@ + + */ +class InstanceFactory extends Factory +{ + protected $model = Instance::class; + + /** + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/packages/Lvl0/FediDiscover/src/Models/Instance.php b/packages/Lvl0/FediDiscover/src/Models/Instance.php new file mode 100644 index 0000000..a9be464 --- /dev/null +++ b/packages/Lvl0/FediDiscover/src/Models/Instance.php @@ -0,0 +1,38 @@ + */ + use HasFactory; + + protected $table = 'fedi_discover_instances'; + + protected $fillable = ['type', 'url', 'enabled', 'interval_seconds', 'extras', 'last_polled_at']; + + protected $casts = [ + 'type' => InstanceType::class, + 'enabled' => 'boolean', + 'extras' => 'array', + 'last_polled_at' => 'datetime', + ]; + + public function scopeEnabled($query) + { + return $query->where('enabled', true); + } + + protected static function newFactory(): Factory + { + return InstanceFactory::new(); + } +} diff --git a/packages/Lvl0/FediDiscover/tests/Feature/InstanceModelTest.php b/packages/Lvl0/FediDiscover/tests/Feature/InstanceModelTest.php new file mode 100644 index 0000000..ae0634e --- /dev/null +++ b/packages/Lvl0/FediDiscover/tests/Feature/InstanceModelTest.php @@ -0,0 +1,88 @@ + InstanceType::Mastodon, + 'url' => 'https://mastodon.social', + 'enabled' => true, + 'interval_seconds' => 600, + 'extras' => ['token' => 'abc123'], + ]); + + $instance = Instance::first(); + + $this->assertNotNull($instance); + $this->assertSame(InstanceType::Mastodon, $instance->type); + $this->assertSame('https://mastodon.social', $instance->url); + $this->assertTrue($instance->enabled); + $this->assertSame(600, $instance->interval_seconds); + $this->assertSame(['token' => 'abc123'], $instance->extras); + } + + public function test_enabled_is_fillable_and_cast_to_boolean(): void + { + $instance = Instance::create([ + 'type' => InstanceType::Mastodon, + 'url' => 'https://mastodon.social', + 'enabled' => false, + 'interval_seconds' => 600, + ]); + + $this->assertFalse($instance->fresh()->enabled); + } + + public function test_last_polled_at_is_fillable_and_cast_to_datetime(): void + { + $polledAt = Carbon::parse('2026-04-23 12:00:00'); + + $instance = Instance::create([ + 'type' => InstanceType::Mastodon, + 'url' => 'https://mastodon.social', + 'enabled' => true, + 'interval_seconds' => 600, + 'last_polled_at' => $polledAt, + ]); + + $fresh = $instance->fresh(); + + $this->assertInstanceOf(Carbon::class, $fresh->last_polled_at); + $this->assertTrue($fresh->last_polled_at->equalTo($polledAt)); + } + + public function test_enabled_scope_returns_only_enabled_instances(): void + { + Instance::create([ + 'type' => InstanceType::Mastodon, + 'url' => 'https://enabled.example', + 'enabled' => true, + 'interval_seconds' => 600, + ]); + + Instance::create([ + 'type' => InstanceType::Mastodon, + 'url' => 'https://disabled.example', + 'enabled' => false, + 'interval_seconds' => 600, + ]); + + $enabled = Instance::enabled()->get(); + + $this->assertCount(1, $enabled); + $this->assertSame('https://enabled.example', $enabled->first()->url); + } +}