Files
landing-api/tests/Feature/Panel/DuplicateTest.php
Josep Piguillem 366568b793 Duplicate records as drafts, and preview them from the form
The copy keeps the content, stack and team, but is unpublished, out of any
review, and gets a title marked as a copy and a free slug. It replaces
Filament's replicate action, which left the copy without a slug and still
published. The same copy is available through the API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:14:51 +02:00

99 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Panel;
use App\Enums\PageStatus;
use App\Filament\Resources\Pages\Pages\EditPage;
use App\Filament\Resources\Projects\Pages\ListProjects;
use App\Models\Member;
use App\Models\Page;
use App\Models\Project;
use App\Models\Technology;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Tests\FakesPireon;
use Tests\TestCase;
/**
* Duplicating: a draft copy to start the next record from, from the panel or
* the API.
*/
class DuplicateTest extends TestCase
{
use FakesPireon, RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->seed(RolePermissionSeeder::class);
Queue::fake();
}
#[Test]
public function a_published_page_is_copied_as_a_draft_with_a_free_slug(): void
{
$this->actingAs($editor = $this->userWithRoles('editor'));
$page = Page::factory()->published()->create([
'title' => ['es' => 'Hola', 'en' => 'Hello'],
'slug' => ['es' => 'hola', 'en' => 'hello'],
]);
Page::factory()->draft()->create(['slug' => ['es' => 'hola-copia']]);
Livewire::test(EditPage::class, ['record' => $page->getRouteKey()])
->callAction('duplicate')
->assertHasNoActionErrors();
$copy = Page::query()->latest('id')->first();
$this->assertSame(PageStatus::Draft, $copy->status);
$this->assertNull($copy->published_at);
$this->assertSame('Hola (copia)', $copy->getTranslation('title', 'es'));
$this->assertSame('Hello (copy)', $copy->getTranslation('title', 'en'));
$this->assertSame('hola-copia-2', $copy->getTranslation('slug', 'es'));
$this->assertSame($editor->id, $copy->author_id);
$this->assertSame($page->body, $copy->body);
}
#[Test]
public function a_project_keeps_its_stack_and_team(): void
{
$this->actingAs($this->userWithRoles('editor'));
$project = Project::factory()->published()->create();
$project->technologies()->attach(Technology::factory()->create());
$project->members()->attach(Member::factory()->create(), ['role' => 'Responsable']);
Livewire::test(ListProjects::class)->callTableAction('duplicate', $project);
$copy = Project::query()->latest('id')->first();
$this->assertNotSame($project->id, $copy->id);
$this->assertNull($copy->published_at);
$this->assertCount(1, $copy->technologies);
$this->assertSame('Responsable', $copy->members()->first()->pivot->role);
}
#[Test]
public function the_api_duplicates_too_and_only_for_who_may_create(): void
{
$page = Page::factory()->create();
$this->withHeaders($this->apiHeadersFor($this->userWithRoles('viewer')));
$this->postJson("/api/v1/pages/{$page->id}/duplicate")->assertForbidden();
$this->withHeaders($this->apiHeadersFor($this->userWithRoles('editor')));
$this->postJson("/api/v1/pages/{$page->id}/duplicate")
->assertCreated()
->assertJsonPath('data.type', 'pages');
$this->assertSame(2, Page::query()->count());
}
}