3 - Add UrlDiscovered event

This commit is contained in:
myrmidex 2026-04-24 21:55:57 +02:00
parent 52d6b493cb
commit 3eff919945
9 changed files with 121 additions and 2 deletions

View file

@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use App\Models\Page;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Page>
*/
class PageFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
];
}
}

View file

@ -19,6 +19,7 @@ public function up(): void
$table->unsignedInteger('interval_seconds')->default(300);
$table->json('extras')->default('{}');
$table->timestampTz('last_polled_at')->nullable();
$table->string('last_seen_id')->nullable();
$table->timestamps();
$table->unique(['type', 'url']);

View file

@ -26,6 +26,7 @@ public function definition(): array
'enabled' => null,
'interval_seconds' => 600,
'extras' => [],
'last_seen_id' => null,
'last_polled_at' => now(),
];
}

View file

@ -0,0 +1,26 @@
<?php
namespace Lvl0\FediDiscover\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class UrlDiscovered
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public string $url,
public ?string $postUrl,
public ?string $postBody
) {}
public function broadcastOn(): array
{
return [
new PrivateChannel('discovery'),
];
}
}

View file

@ -4,8 +4,10 @@
namespace Lvl0\FediDiscover;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
use Lvl0\FediDiscover\Console\Commands\ValidateInstancesCommand;
use Lvl0\FediDiscover\Events\UrlDiscovered;
class FediDiscoverServiceProvider extends ServiceProvider
{
@ -18,6 +20,10 @@ public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
Event::listen(
UrlDiscovered::class,
);
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__ . '/../config/fedi-discover.php' => config_path('fedi-discover.php'),

View file

@ -19,6 +19,7 @@
* @property bool $enabled
* @property int $interval_seconds
* @property array<string, mixed> $extras
* @property int $last_seen_id
* @property Carbon|null $last_polled_at
* @property Carbon $created_at
* @property Carbon $updated_at
@ -30,7 +31,7 @@ class Instance extends Model
protected $table = 'fedi_discover_instances';
protected $fillable = ['type', 'url', 'enabled', 'interval_seconds', 'extras', 'last_polled_at'];
protected $fillable = ['type', 'url', 'enabled', 'interval_seconds', 'extras', 'last_seen_id', 'last_polled_at'];
protected $casts = [
'type' => InstanceType::class,

View file

@ -14,7 +14,7 @@ class InstanceConfigPersistenceTest extends TestCase
{
use RefreshDatabase;
public function test_instance_config_toArray_is_mass_assignable_on_the_model(): void
public function test_instance_config_to_array_is_mass_assignable_on_the_model(): void
{
$config = InstanceConfig::fromArray([
'type' => InstanceType::Mastodon->value,

View file

@ -64,6 +64,31 @@ public function test_last_polled_at_is_fillable_and_cast_to_datetime(): void
$this->assertTrue($fresh->last_polled_at->equalTo($polledAt));
}
public function test_last_seen_id_defaults_to_null(): void
{
$instance = Instance::create([
'type' => InstanceType::Mastodon,
'url' => 'https://mastodon.social',
'enabled' => true,
'interval_seconds' => 600,
]);
$this->assertNull($instance->fresh()->last_seen_id);
}
public function test_last_seen_id_is_fillable_and_persists_as_string(): void
{
$instance = Instance::create([
'type' => InstanceType::Mastodon,
'url' => 'https://mastodon.social',
'enabled' => true,
'interval_seconds' => 600,
'last_seen_id' => '109876543210',
]);
$this->assertSame('109876543210', $instance->fresh()->last_seen_id);
}
public function test_enabled_scope_returns_only_enabled_instances(): void
{
Instance::create([

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Lvl0\FediDiscover\Tests\Unit;
use Lvl0\FediDiscover\Events\UrlDiscovered;
use PHPUnit\Framework\TestCase;
class UrlDiscoveredTest extends TestCase
{
public function test_it_exposes_all_payload_fields(): void
{
$event = new UrlDiscovered(
url: 'https://example.com/article',
postUrl: 'https://mastodon.social/@alice/109876543210',
postBody: 'Check out this article: https://example.com/article'
);
$this->assertSame('https://example.com/article', $event->url);
$this->assertSame('https://mastodon.social/@alice/109876543210', $event->postUrl);
$this->assertSame('Check out this article: https://example.com/article', $event->postBody);
}
public function test_post_body_is_nullable(): void
{
$event = new UrlDiscovered(
url: 'https://example.com/article',
postUrl: 'https://mastodon.social/@alice/109876543210',
postBody: null
);
$this->assertNull($event->postBody);
}
}