Add project duplication flow
This commit is contained in:
@@ -3,7 +3,11 @@
|
||||
namespace Tests\Feature\Api;
|
||||
|
||||
use App\Actions\ProjectTicketMetadata\InitializeProjectTicketMetadata;
|
||||
use App\Actions\Projects\DuplicateProjectConfiguration;
|
||||
use App\Models\BoardColumn;
|
||||
use App\Models\Project;
|
||||
use App\Models\TicketStatus;
|
||||
use App\Models\TicketType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
@@ -51,6 +55,86 @@ class ProjectApiTest extends TestCase
|
||||
$this->assertSame(1, $project->ticketStatuses()->count());
|
||||
}
|
||||
|
||||
public function test_users_can_duplicate_projects_via_api(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->syncGlobalPermissions($user, ['create']);
|
||||
|
||||
$sourceProject = Project::factory()->create([
|
||||
'key' => 'SRC1',
|
||||
'show_author' => false,
|
||||
]);
|
||||
$this->syncProjectPermissions($sourceProject, $user, ['view']);
|
||||
|
||||
$sourceProject->ticketTypes()->delete();
|
||||
$sourceProject->ticketStatuses()->delete();
|
||||
$sourceProject->boardColumns()->delete();
|
||||
|
||||
$column = BoardColumn::factory()->create([
|
||||
'project_id' => $sourceProject->id,
|
||||
'name' => 'In Progress',
|
||||
'position' => 1,
|
||||
]);
|
||||
$backlogStatus = TicketStatus::factory()->create([
|
||||
'project_id' => $sourceProject->id,
|
||||
'name' => 'Queued',
|
||||
'position' => 1,
|
||||
]);
|
||||
$activeStatus = TicketStatus::factory()->create([
|
||||
'project_id' => $sourceProject->id,
|
||||
'board_column_id' => $column->id,
|
||||
'name' => 'Active',
|
||||
'position' => 1,
|
||||
]);
|
||||
$backlogStatus->allowedTargetStatuses()->sync([$activeStatus->id]);
|
||||
TicketType::factory()->create([
|
||||
'project_id' => $sourceProject->id,
|
||||
'name' => 'Spike',
|
||||
'position' => 1,
|
||||
]);
|
||||
|
||||
$this->withApplicationKey($user)
|
||||
->postJson(route('api.projects.store'), [
|
||||
'key' => 'dup2',
|
||||
'name' => 'Duplicated API Project',
|
||||
'creation_mode' => 'duplicate',
|
||||
'source_project_id' => $sourceProject->id,
|
||||
'copy_areas' => [
|
||||
DuplicateProjectConfiguration::COPY_PROJECT_SETTINGS,
|
||||
DuplicateProjectConfiguration::COPY_BOARD_WORKFLOW,
|
||||
DuplicateProjectConfiguration::COPY_TICKET_TYPES,
|
||||
],
|
||||
])
|
||||
->assertCreated()
|
||||
->assertJsonPath('data.key', 'DUP2')
|
||||
->assertJsonPath('data.name', 'Duplicated API Project');
|
||||
|
||||
$project = Project::query()->where('key', 'DUP2')->firstOrFail();
|
||||
|
||||
$this->assertFalse($project->show_author);
|
||||
$this->assertSame(['In Progress'], $project->boardColumns()->pluck('name')->all());
|
||||
$this->assertSame(['Queued', 'Active'], $project->ticketStatuses()->pluck('name')->all());
|
||||
$this->assertSame(['Spike'], $project->ticketTypes()->pluck('name')->all());
|
||||
$this->assertSame(['Active'], $project->ticketStatuses()->where('name', 'Queued')->firstOrFail()->allowedTargetStatuses()->pluck('name')->all());
|
||||
}
|
||||
|
||||
public function test_project_duplication_via_api_requires_visible_source_project(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->syncGlobalPermissions($user, ['create']);
|
||||
$sourceProject = Project::factory()->create();
|
||||
|
||||
$this->withApplicationKey($user)
|
||||
->postJson(route('api.projects.store'), [
|
||||
'key' => 'nope',
|
||||
'name' => 'No Access',
|
||||
'creation_mode' => 'duplicate',
|
||||
'source_project_id' => $sourceProject->id,
|
||||
])
|
||||
->assertStatus(422)
|
||||
->assertJsonValidationErrors(['source_project_id']);
|
||||
}
|
||||
|
||||
public function test_project_show_and_delete_enforce_permissions(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
Reference in New Issue
Block a user