fix(KAN-14): preserve template inheritance and project data
CI/CD / preconditions (pull_request) Successful in 4s
CI/CD / test_and_check_app (pull_request) Failing after 2m14s
CI/CD / Publish immutable image (pull_request) Skipped

This commit is contained in:
2026-10-15 11:38:17 +02:00
parent 5769d84526
commit 1291a0fcad
61 changed files with 2696 additions and 335 deletions
@@ -31,11 +31,13 @@ class ProjectTemplateOverrideTest extends TestCase
$project = Project::factory()->create();
$status = TicketStatus::factory()->for($project)->create(['name' => 'Todo', 'position' => 1]);
$project->forceFill(['project_template_id' => $template->id])->saveQuietly();
app(DuplicateProjectConfiguration::class)->apply($project, $template->configuration_snapshot, adoptExisting: true);
$ticket = $this->createTicket($project, $status);
$sourceStatus->update(['name' => 'Ready']);
app(UpdateProjectTemplate::class)->handle($template, [
'name' => $template->name,
'configuration_snapshot' => app(DuplicateProjectConfiguration::class)->export($template->sourceProject, DuplicateProjectConfiguration::copyableAreas()),
'copy_areas' => [DuplicateProjectConfiguration::COPY_TICKET_STATUSES],
]);
@@ -62,6 +64,7 @@ class ProjectTemplateOverrideTest extends TestCase
$sourceStatus->update(['name' => 'Ready']);
app(UpdateProjectTemplate::class)->handle($template, [
'name' => $template->name,
'configuration_snapshot' => app(DuplicateProjectConfiguration::class)->export($template->sourceProject, DuplicateProjectConfiguration::copyableAreas()),
'copy_areas' => [DuplicateProjectConfiguration::COPY_TICKET_STATUSES],
]);
@@ -76,6 +79,7 @@ class ProjectTemplateOverrideTest extends TestCase
$project = Project::factory()->create();
$status = TicketStatus::factory()->for($project)->create(['name' => 'Todo', 'position' => 1]);
$project->forceFill(['project_template_id' => $template->id])->saveQuietly();
app(DuplicateProjectConfiguration::class)->apply($project, $template->configuration_snapshot, adoptExisting: true);
$status->update(['name' => 'Project only']);
$status->update(['name' => 'Todo']);
@@ -86,6 +90,7 @@ class ProjectTemplateOverrideTest extends TestCase
$sourceStatus->update(['name' => 'Ready']);
app(UpdateProjectTemplate::class)->handle($template, [
'name' => $template->name,
'configuration_snapshot' => app(DuplicateProjectConfiguration::class)->export($template->sourceProject, DuplicateProjectConfiguration::copyableAreas()),
'copy_areas' => [DuplicateProjectConfiguration::COPY_TICKET_STATUSES],
]);
@@ -106,7 +111,7 @@ class ProjectTemplateOverrideTest extends TestCase
'project_template_id' => $template->id,
'template_overrides' => [DuplicateProjectConfiguration::COPY_TICKET_STATUSES],
]);
$replacementStatus = TicketStatus::factory()->for($project)->create(['name' => 'Old template status', 'position' => 1]);
$replacementStatus = TicketStatus::factory()->for($project)->create(['name' => 'Old template status', 'position' => 1, 'configuration_key' => $template->configuration_snapshot['ticket_statuses'][0]['configuration_key']]);
$localStatus = TicketStatus::factory()->for($project)->create(['name' => 'Local status', 'position' => 2]);
$ticket = $this->createTicket($project, $localStatus);
$this->syncProjectPermissions($project, $user, ['admin']);
@@ -171,9 +176,11 @@ class ProjectTemplateOverrideTest extends TestCase
$project = Project::factory()->create();
TicketType::factory()->for($project)->create(['name' => 'Local type', 'position' => 1]);
$project->forceFill(['project_template_id' => $template->id])->saveQuietly();
app(DuplicateProjectConfiguration::class)->apply($project, $template->configuration_snapshot, adoptExisting: true);
app(UpdateProjectTemplate::class)->handle($template, [
'name' => $template->name,
'configuration_snapshot' => app(DuplicateProjectConfiguration::class)->export($template->sourceProject, DuplicateProjectConfiguration::copyableAreas()),
'copy_areas' => [
DuplicateProjectConfiguration::COPY_PROJECT_SETTINGS,
DuplicateProjectConfiguration::COPY_TICKET_TYPES,
@@ -199,6 +206,7 @@ class ProjectTemplateOverrideTest extends TestCase
'field_type' => 'number', 'label' => 'Estimate', 'position' => 1,
]);
$project->forceFill(['project_template_id' => $template->id])->saveQuietly();
app(DuplicateProjectConfiguration::class)->apply($project, $template->configuration_snapshot, adoptExisting: true);
$status = TicketStatus::factory()->for($project)->create();
$ticket = $this->createTicket($project, $status);
$fieldValue = TicketFieldValue::factory()->create([
@@ -210,6 +218,7 @@ class ProjectTemplateOverrideTest extends TestCase
$sourceField->update(['label' => 'Story points']);
app(UpdateProjectTemplate::class)->handle($template, [
'name' => $template->name,
'configuration_snapshot' => app(DuplicateProjectConfiguration::class)->export($template->sourceProject, DuplicateProjectConfiguration::copyableAreas()),
'copy_areas' => [DuplicateProjectConfiguration::COPY_TICKET_FIELDS],
]);