From d50348562b65689ad5c3522c83c9bac1e5080e8a Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Fri, 15 May 2026 16:16:42 -0300 Subject: [PATCH] refactor(media): atomic upload_token via transaction and tighten test assertions --- app/Http/Controllers/Api/UploadController.php | 11 ++++++++--- app/Http/Requests/Api/StoreUploadRequest.php | 3 +++ tests/Feature/Api/UploadControllerTest.php | 11 ++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Api/UploadController.php b/app/Http/Controllers/Api/UploadController.php index 84b122c4..f5b63daf 100644 --- a/app/Http/Controllers/Api/UploadController.php +++ b/app/Http/Controllers/Api/UploadController.php @@ -10,6 +10,7 @@ use App\Models\Workspace; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; use Symfony\Component\HttpFoundation\Response; class UploadController extends Controller @@ -29,9 +30,13 @@ public function store(StoreUploadRequest $request, string $token): JsonResponse $workspace = Workspace::findOrFail((string) $request->query('ws')); - $media = $workspace->addMedia($request->file('media'), 'assets'); - $media->upload_token = $token; - $media->save(); + $media = DB::transaction(function () use ($workspace, $request, $token): Media { + $media = $workspace->addMedia($request->file('media'), 'assets'); + $media->upload_token = $token; + $media->save(); + + return $media; + }); return response()->json([ 'upload_token' => $token, diff --git a/app/Http/Requests/Api/StoreUploadRequest.php b/app/Http/Requests/Api/StoreUploadRequest.php index f21caf5c..11706af5 100644 --- a/app/Http/Requests/Api/StoreUploadRequest.php +++ b/app/Http/Requests/Api/StoreUploadRequest.php @@ -14,6 +14,9 @@ public function authorize(): bool return true; } + /** + * @return array + */ public function rules(): array { $allowed = implode(',', array_merge( diff --git a/tests/Feature/Api/UploadControllerTest.php b/tests/Feature/Api/UploadControllerTest.php index 90082581..bee8a9ed 100644 --- a/tests/Feature/Api/UploadControllerTest.php +++ b/tests/Feature/Api/UploadControllerTest.php @@ -38,13 +38,18 @@ function signedUploadUrl(Workspace $ws, string $token, ?int $expiresInMinutes = 'media' => $file, ]); - $response->assertCreated() - ->assertJsonStructure(['upload_token', 'media_id', 'type', 'mime_type', 'original_filename']); - $media = Media::where('upload_token', $token)->first(); expect($media)->not->toBeNull(); expect($media->mediable_id)->toBe($this->workspace->id); expect($media->mediable_type)->toBe('workspace'); + + $response->assertCreated() + ->assertJson([ + 'upload_token' => $token, + 'media_id' => $media->id, + 'mime_type' => $media->mime_type, + 'original_filename' => $media->original_filename, + ]); }); test('rejects unsigned request', function () {