chore - Extract RegisterDiscoveredPageAction for shared Page::firstOrCreate logic

This commit is contained in:
myrmidex 2026-04-26 20:18:18 +02:00
parent dda5b0f770
commit 649aeb3627
4 changed files with 115 additions and 17 deletions

View file

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace App\Actions;
use App\Enums\PageStatusEnum;
use App\Models\Page;
class RegisterDiscoveredPageAction
{
public function __invoke(string $url, ?int $instanceId = null): Page
{
return Page::firstOrCreate(
['url' => $url],
[
'status' => PageStatusEnum::Discovered,
'instance_id' => $instanceId,
],
);
}
}

View file

@ -4,8 +4,7 @@
namespace App\Listeners;
use App\Enums\PageStatusEnum;
use App\Models\Page;
use App\Actions\RegisterDiscoveredPageAction;
use App\Models\PageLink;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\DB;
@ -13,22 +12,20 @@
class UrlDiscoveredListener implements ShouldQueue
{
public function __construct(
private RegisterDiscoveredPageAction $registerPage,
) {}
public function handle(UrlDiscovered $event): void
{
DB::transaction(function () use ($event) {
$targetPage = Page::firstOrCreate(
['url' => $event->url],
['status' => PageStatusEnum::Discovered, 'instance_id' => $event->instanceId],
);
$targetPage = ($this->registerPage)($event->url, $event->instanceId);
if ($event->postUrl === null || $event->postUrl === $event->url) {
return;
}
$sourcePage = Page::firstOrCreate(
['url' => $event->postUrl],
['status' => PageStatusEnum::Discovered, 'instance_id' => $event->instanceId],
);
$sourcePage = ($this->registerPage)($event->postUrl, $event->instanceId);
PageLink::firstOrCreate([
'source_page_id' => $sourcePage->id,

View file

@ -4,8 +4,7 @@
namespace App\Livewire;
use App\Enums\PageStatusEnum;
use App\Models\Page;
use App\Actions\RegisterDiscoveredPageAction;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\RateLimiter;
use Livewire\Component;
@ -16,7 +15,7 @@ class UrlSubmissionForm extends Component
public ?string $confirmedUrl = null;
public function submit(): void
public function submit(RegisterDiscoveredPageAction $registerPage): void
{
$key = 'submit-url:' . request()->ip();
@ -32,10 +31,7 @@ public function submit(): void
'url' => ['required', 'url:http,https'],
]);
Page::firstOrCreate(
['url' => $validated['url']],
['status' => PageStatusEnum::Discovered],
);
$registerPage($validated['url']);
$this->confirmedUrl = $validated['url'];
$this->reset('url');

View file

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Actions;
use App\Actions\RegisterDiscoveredPageAction;
use App\Enums\PageStatusEnum;
use App\Models\Page;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Lvl0\FediDiscover\Config\InstanceType;
use Lvl0\FediDiscover\Models\Instance;
use Tests\TestCase;
class RegisterDiscoveredPageActionTest extends TestCase
{
use RefreshDatabase;
public function test_creates_page_with_url_and_discovered_status(): void
{
$action = new RegisterDiscoveredPageAction;
$page = $action('https://example.com/article');
$this->assertInstanceOf(Page::class, $page);
$this->assertSame('https://example.com/article', $page->url);
$this->assertSame(PageStatusEnum::Discovered, $page->status);
$this->assertNull($page->instance_id);
$this->assertDatabaseHas('pages', ['url' => 'https://example.com/article']);
}
public function test_creates_page_with_provided_instance_id(): void
{
$instance = Instance::factory()
->type(InstanceType::Mastodon)
->enabled()
->create();
$action = new RegisterDiscoveredPageAction;
$page = $action('https://example.com/fediverse-post', instanceId: $instance->id);
$this->assertInstanceOf(Page::class, $page);
$this->assertSame($instance->id, $page->instance_id);
$this->assertDatabaseHas('pages', [
'url' => 'https://example.com/fediverse-post',
'instance_id' => $instance->id,
]);
}
public function test_returns_existing_page_when_url_already_exists(): void
{
$existing = Page::factory()->createQuietly([
'url' => 'https://example.com/seen-before',
'status' => PageStatusEnum::Discovered,
]);
$action = new RegisterDiscoveredPageAction;
$returned = $action('https://example.com/seen-before');
$this->assertSame($existing->id, $returned->id);
$this->assertDatabaseCount('pages', 1);
}
public function test_existing_page_status_not_overwritten_on_duplicate_call(): void
{
Page::factory()->createQuietly([
'url' => 'https://example.com/already-fetched',
'status' => PageStatusEnum::Fetched,
]);
$action = new RegisterDiscoveredPageAction;
$returned = $action('https://example.com/already-fetched');
$this->assertSame(PageStatusEnum::Fetched, $returned->status);
$this->assertDatabaseHas('pages', [
'url' => 'https://example.com/already-fetched',
'status' => PageStatusEnum::Fetched,
]);
}
}