diff --git a/app/Livewire/Project/CloneMe.php b/app/Livewire/Project/CloneMe.php index 013e66901..e236124e9 100644 --- a/app/Livewire/Project/CloneMe.php +++ b/app/Livewire/Project/CloneMe.php @@ -187,6 +187,7 @@ public function clone(string $type) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $newDatabase->id, @@ -315,6 +316,7 @@ public function clone(string $type) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $application->id, @@ -369,6 +371,7 @@ public function clone(string $type) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $database->id, diff --git a/app/Livewire/Project/Shared/ResourceOperations.php b/app/Livewire/Project/Shared/ResourceOperations.php index a26b43026..301c51be9 100644 --- a/app/Livewire/Project/Shared/ResourceOperations.php +++ b/app/Livewire/Project/Shared/ResourceOperations.php @@ -142,6 +142,7 @@ public function cloneTo($destination_id) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $new_resource->id, @@ -280,6 +281,7 @@ public function cloneTo($destination_id) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $application->id, @@ -322,6 +324,7 @@ public function cloneTo($destination_id) 'id', 'created_at', 'updated_at', + 'uuid', ])->forceFill([ 'name' => $newName, 'resource_id' => $database->id, diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php index fbcedf277..4af6ac90a 100644 --- a/bootstrap/helpers/applications.php +++ b/bootstrap/helpers/applications.php @@ -300,6 +300,7 @@ function clone_application(Application $source, $destination, array $overrides = 'id', 'created_at', 'updated_at', + 'uuid', ])->fill([ 'name' => $newName, 'resource_id' => $newApplication->id, diff --git a/tests/Feature/ClonePersistentVolumeUuidTest.php b/tests/Feature/ClonePersistentVolumeUuidTest.php new file mode 100644 index 000000000..f1ae8dd26 --- /dev/null +++ b/tests/Feature/ClonePersistentVolumeUuidTest.php @@ -0,0 +1,84 @@ +user = User::factory()->create(); + $this->team = Team::factory()->create(); + $this->user->teams()->attach($this->team, ['role' => 'owner']); + + $this->server = Server::factory()->create(['team_id' => $this->team->id]); + $this->destination = StandaloneDocker::factory()->create(['server_id' => $this->server->id]); + $this->project = Project::factory()->create(['team_id' => $this->team->id]); + $this->environment = Environment::factory()->create(['project_id' => $this->project->id]); + + $this->application = Application::factory()->create([ + 'environment_id' => $this->environment->id, + 'destination_id' => $this->destination->id, + 'destination_type' => $this->destination->getMorphClass(), + ]); + + $this->actingAs($this->user); + session(['currentTeam' => $this->team]); +}); + +test('cloning application generates new uuid for persistent volumes', function () { + $volume = LocalPersistentVolume::create([ + 'name' => $this->application->uuid.'-data', + 'mount_path' => '/data', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $originalUuid = $volume->uuid; + + $newApp = clone_application($this->application, $this->destination, [ + 'environment_id' => $this->environment->id, + ]); + + $clonedVolume = $newApp->persistentStorages()->first(); + + expect($clonedVolume)->not->toBeNull(); + expect($clonedVolume->uuid)->not->toBe($originalUuid); + expect($clonedVolume->mount_path)->toBe('/data'); +}); + +test('cloning application with multiple persistent volumes generates unique uuids', function () { + $volume1 = LocalPersistentVolume::create([ + 'name' => $this->application->uuid.'-data', + 'mount_path' => '/data', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $volume2 = LocalPersistentVolume::create([ + 'name' => $this->application->uuid.'-config', + 'mount_path' => '/config', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $newApp = clone_application($this->application, $this->destination, [ + 'environment_id' => $this->environment->id, + ]); + + $clonedVolumes = $newApp->persistentStorages()->get(); + + expect($clonedVolumes)->toHaveCount(2); + + $clonedUuids = $clonedVolumes->pluck('uuid')->toArray(); + $originalUuids = [$volume1->uuid, $volume2->uuid]; + + // All cloned UUIDs should be unique and different from originals + expect($clonedUuids)->each->not->toBeIn($originalUuids); + expect(array_unique($clonedUuids))->toHaveCount(2); +});