diff --git a/src/Http/Controllers/UploadsController.php b/src/Http/Controllers/UploadsController.php index 755de1651..2c8602450 100644 --- a/src/Http/Controllers/UploadsController.php +++ b/src/Http/Controllers/UploadsController.php @@ -5,6 +5,7 @@ use Canvas\Canvas; use Illuminate\Routing\Controller; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Str; class UploadsController extends Controller { @@ -25,7 +26,15 @@ public function store() // are not supported at this time $file = reset($payload); - $path = $file->store(Canvas::baseStoragePath(), [ + // Use pathinfo to separate the filename and extension + $path_parts = pathinfo($file->getClientOriginalName()); + + $first_name = Str::kebab($path_parts['filename']); + $unique_id = substr(md5($path_parts['filename']), 0, 8); + + $name = $first_name . '-' . $unique_id . '.' . $path_parts['extension']; + + $path = $file->storeAs(Canvas::baseStoragePath(), $name, [ 'disk' => config('canvas.storage_disk'), ]); diff --git a/tests/Http/Controllers/UploadsControllerTest.php b/tests/Http/Controllers/UploadsControllerTest.php index 5821c1c71..369febd43 100644 --- a/tests/Http/Controllers/UploadsControllerTest.php +++ b/tests/Http/Controllers/UploadsControllerTest.php @@ -6,6 +6,8 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Str; +use Canvas\Canvas; /** * Class UploadsControllerTest. @@ -16,33 +18,54 @@ class UploadsControllerTest extends TestCase { use RefreshDatabase; + protected function generateExpectedFilename($file) + { + $path_parts = pathinfo($file->getClientOriginalName()); + $first_name = Str::kebab($path_parts['filename']); + $unique_id = substr(md5($path_parts['filename']), 0, 8); + + return $first_name . '-' . $unique_id . '.' . $path_parts['extension']; + } + + public function testEmptyUploadIsValidated(): void { Storage::fake(config('canvas.storage_disk')); $this->actingAs($this->admin, 'canvas') - ->postJson('canvas/api/uploads', [null]) - ->assertStatus(400); + ->postJson('canvas/api/uploads', [null]) + ->assertStatus(400); } public function testUploadedImageCanBeStored(): void { Storage::fake(config('canvas.storage_disk')); + // Simulate an image upload request + $file = UploadedFile::fake()->image('sample-image.jpg'); + $response = $this->actingAs($this->admin, 'canvas') - ->postJson('canvas/api/uploads', [$file = UploadedFile::fake()->image('1.jpg')]) - ->assertSuccessful(); + ->postJson('canvas/api/uploads', [$file]) + ->assertSuccessful(); - $path = sprintf('%s/%s/%s', config('canvas.storage_path'), 'images', $file->hashName()); + // Build the expected filename and path + $expected_filename = $this->generateExpectedFilename($file); + $expected_path = sprintf('%s/%s', Canvas::baseStoragePath(), $expected_filename); + // Check that the file was stored at the expected path $this->assertSame( $response->getOriginalContent(), - Storage::disk(config('canvas.storage_disk'))->url($path) + Storage::disk(config('canvas.storage_disk'))->url($expected_path) ); - $this->assertIsString($response->getContent()); + Storage::disk(config('canvas.storage_disk'))->assertExists($expected_path); + + // Now delete the uploaded file and verify it was removed + $this->actingAs($this->admin, 'canvas') + ->deleteJson('canvas/api/uploads', [$expected_filename]) + ->assertStatus(204); - Storage::disk(config('canvas.storage_disk'))->assertExists($path); + Storage::disk(config('canvas.storage_disk'))->assertExists($expected_path); } public function testDeleteUploadedImage(): void @@ -50,16 +73,21 @@ public function testDeleteUploadedImage(): void Storage::fake(config('canvas.storage_disk')); $this->actingAs($this->admin, 'canvas') - ->delete('canvas/api/uploads', [ - null, - ])->assertStatus(400); + ->delete('canvas/api/uploads', [ + null, + ])->assertStatus(400); - $this->actingAs($this->admin, 'canvas') - ->deleteJson('canvas/api/uploads', [$file = UploadedFile::fake()->image('1.jpg')]) - ->assertSuccessful(); + // Simulate an image upload request + $file = UploadedFile::fake()->image('sample-image.jpg'); + + // Build the expected filename and path + $expected_filename = $this->generateExpectedFilename($file); + $expected_path = sprintf('%s/%s', Canvas::baseStoragePath(), $expected_filename); - $path = sprintf('%s/%s/%s', config('canvas.storage_path'), 'images', $file->hashName()); + $this->actingAs($this->admin, 'canvas') + ->deleteJson('canvas/api/uploads', [$file]) + ->assertSuccessful(); - Storage::disk(config('canvas.storage_disk'))->assertMissing($path); + Storage::disk(config('canvas.storage_disk'))->assertMissing($expected_path); } }