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>
99 lines
3.2 KiB
PHP
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());
|
|
}
|
|
}
|