Browse Source

compelete file update (without validation test)

pull/2/head
Mohammad Khazaee 2 years ago
parent
commit
eb3dd48b31
  1. 28
      app/Http/Controllers/FileController.php
  2. 2
      app/Http/Middleware/BindCollectionModelMiddleware.php
  3. 24
      app/Http/Middleware/BindFileModelMiddleware.php
  4. 3
      app/Http/Requests/FileStoreRequest.php
  5. 34
      app/Http/Requests/FileUpdateRequest.php
  6. 1
      app/Providers/RouteServiceProvider.php
  7. 2
      routes/api.php
  8. 75
      tests/Feature/FileUpdateTest.php
  9. 26
      tests/Feature/Traits/FileTraits.php

28
app/Http/Controllers/FileController.php

@ -3,6 +3,7 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Http\Requests\FileStoreRequest; use App\Http\Requests\FileStoreRequest;
use App\Http\Requests\FileUpdateRequest;
use App\Http\Resources\FileResource; use App\Http\Resources\FileResource;
use App\Image\ImageProcessor; use App\Image\ImageProcessor;
use App\Jobs\FileConversionQueue; use App\Jobs\FileConversionQueue;
@ -22,19 +23,19 @@ class FileController extends Controller
if ($request->castParams == 'resource') { if ($request->castParams == 'resource') {
return new FileResource(app()->file); return new FileResource(app()->file);
} }
if (!is_null(array_intersect(array_keys($request->all()), $this->availableParams))) { if (!is_null(array_intersect(array_keys($request->all()), $this->availableParams))) {
$imageProcessor->process(app()->file->getPath(), app()->file->getModifiedPath(), $request->all()); $imageProcessor->process(app()->file->getPath(), app()->file->getModifiedPath(), $request->all());
return response()->file(app()->file->getModifiedPath()); return response()->file(app()->file->getModifiedPath());
} }
return response()->file(app()->file->getPath()); return response()->file(app()->file->getPath());
} }
public function private($collection, $path)
{
Storage::disk('local')->download($path);
}
// for local private we didn't talk about it
// public function private($collection, $path)
// {
// Storage::disk('local')->download($path);
// }
public function store(FileStoreRequest $request, ImageProcessor $imageProcessor) public function store(FileStoreRequest $request, ImageProcessor $imageProcessor)
{ {
@ -43,9 +44,8 @@ class FileController extends Controller
$request->file = $imageProcessor->process($request->file->path(), '/tmp/' . app()->uuid . '.' . app()->collection->ext, app()->collection->process); $request->file = $imageProcessor->process($request->file->path(), '/tmp/' . app()->uuid . '.' . app()->collection->ext, app()->collection->process);
} }
$fileResource = null; $fileResource = null;
DB::transaction(function () use ($request,&$fileResource) {
DB::transaction(function () use ($request, &$fileResource) {
$uuid = app()->uuid; $uuid = app()->uuid;
$fileResource = File::create([ $fileResource = File::create([
'uuid' => $uuid, 'uuid' => $uuid,
@ -77,13 +77,17 @@ class FileController extends Controller
return new FileResource($fileResource); return new FileResource($fileResource);
} }
public function update(Request $request, $id)
public function update(FileUpdateRequest $request)
{ {
//
app()->file->update($request->all());
return new FileResource(app()->file);
} }
public function destroy($id)
public function destroy()
{ {
//
if (app()->file->trashed()) {
return app()->file->restore();
}
return app()->file->delete();
} }
} }

2
app/Http/Middleware/BindCollectionModelMiddleware.php

@ -18,7 +18,7 @@ class BindCollectionModelMiddleware
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
if (($request->route()->action['as'] == 'api.files.store') || ($request->route()->action['as'] == "api.files.show")) {
if (($request->route()->action['as'] == 'api.files.store') || ($request->route()->action['as'] == "api.files.show") || ($request->route()->action['as'] == 'api.files.update')) {
app()->singleton('collection', function () use ($request) { app()->singleton('collection', function () use ($request) {
return Collection::where('name', $request->route('collection_name'))->firstOrFail(); return Collection::where('name', $request->route('collection_name'))->firstOrFail();
}); });

24
app/Http/Middleware/BindFileModelMiddleware.php

@ -44,6 +44,30 @@ class BindFileModelMiddleware
} }
} }
if ($request->route()->action['as'] == 'api.files.update') {
$file = File::findOrFail($request->route('uuid'));
$Collection = Collection::where('name', $request->route('collection_name'))->firstOrFail();
if (Storage::disk($Collection->disk)->exists($file->server_path . $file->uuid . '.' . $Collection->ext)) {
app()->bind('file', function () use ($file) {
return $file;
});
}else{
abort(404);
}
}
if ($request->route()->action['as'] == 'api.files.destroy') {
$file = File::findOrFail($request->route('uuid'));
$Collection = Collection::withTrashed()->where('name', $request->route('collection_name'))->firstOrFail();
if (Storage::disk($Collection->disk)->exists($file->server_path . $file->uuid . '.' . $Collection->ext)) {
app()->bind('file', function () use ($file) {
return $file;
});
}else{
abort(404);
}
}
return $next($request); return $next($request);
} }
} }

3
app/Http/Requests/FileStoreRequest.php

@ -30,7 +30,7 @@ class FileStoreRequest extends FormRequest
return false; return false;
} }
if (app()->collection->count !== 1 && (app()->collection->count <= File::where('user_id', auth()->id())->where('collction_id',app()->collection->id)->count()) && !app()->collection->tmp_support) {
if (app()->collection->count !== 1 && (app()->collection->count <= File::where('user_id', auth()->id())->where('collection_id',app()->collection->id)->count()) && !app()->collection->tmp_support) {
return false; return false;
} }
if (!app()->bound('file') && is_null($this->file('file'))) { if (!app()->bound('file') && is_null($this->file('file'))) {
@ -65,7 +65,6 @@ class FileStoreRequest extends FormRequest
"alts.*" => [app()->collection->alt_required ? "required" : "nullable", 'max:1000'], "alts.*" => [app()->collection->alt_required ? "required" : "nullable", 'max:1000'],
"description" => [app()->collection->description_required ? "required" : "nullable", 'max:300'], "description" => [app()->collection->description_required ? "required" : "nullable", 'max:300'],
'original_name' => ["string", "nullable", 'max:300'], 'original_name' => ["string", "nullable", 'max:300'],
'public' => ['boolean', 'nullable'],
'published_at' => ['date_format:Y-m-d H:i:s', 'nullable'], 'published_at' => ['date_format:Y-m-d H:i:s', 'nullable'],
]; ];
} }

34
app/Http/Requests/FileUpdateRequest.php

@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class FileUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
"alts" => [app()->collection->alt_required ? "required" : "nullable", 'array'],
"alts.*" => [app()->collection->alt_required ? "required" : "nullable", 'max:1000'],
"description" => [app()->collection->description_required ? "required" : "nullable", 'max:300'],
'original_name' => ["string", "nullable", 'max:300'],
'published_at' => ['date_format:Y-m-d H:i:s', 'nullable'],
];
}
}

1
app/Providers/RouteServiceProvider.php

@ -2,6 +2,7 @@
namespace App\Providers; namespace App\Providers;
use App\Models\File;
use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request; use Illuminate\Http\Request;

2
routes/api.php

@ -34,4 +34,6 @@ Route::group(['as' => 'api.'], function () {
Route::get('{collection_name}/{uuid}.{extention}', [FileController::class, 'show'])->name('files.show'); Route::get('{collection_name}/{uuid}.{extention}', [FileController::class, 'show'])->name('files.show');
// Route::get('{collection_name}/{path}', [FileController::class, 'private'])->name('files.private'); // Route::get('{collection_name}/{path}', [FileController::class, 'private'])->name('files.private');
Route::post('{collection_name}/{model_id?}', [FileController::class, 'store'])->name('files.store'); Route::post('{collection_name}/{model_id?}', [FileController::class, 'store'])->name('files.store');
Route::put('{collection_name}/{uuid}.{extention}',[FileController::class,'update'])->name('files.update');
Route::delete('{collection_name}/{uuid}.{extention}',[FileController::class,'destroy'])->withTrashed()->name('files.destroy');
}); });

75
tests/Feature/FileUpdateTest.php

@ -2,20 +2,81 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Image\ImageProcessor;
use App\Models\Collection;
use App\Models\File;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Storage;
use Tests\Feature\Traits\FileTraits;
use Tests\TestCase; use Tests\TestCase;
class FileUpdateTest extends TestCase class FileUpdateTest extends TestCase
{ {
/**
* A basic feature test example.
*
* @return void
*/
public function test_example()
use FileTraits;
public function test_user_can_not_access_update_without_permission()
{ {
$this->assertTrue(true);
$this->assertFalse("it's not mohammad's fault, I'm waiting for dynamic policy");
}
public function test_user_update_not_exits_files_not_found()
{
$data = [
"original_name" => 'original name is very bad',
"description" => 'this is a description for file and has beed updated',
];
$response = $this->loginAs()->putJson(route('api.files.update', ['collection_name' => 'not_exits', 'uuid' => app()->uuid, 'extention' => 'jpg']), $data);
$response->assertNotFound();
}
// /**
// * @dataProvider updateValidationTestProvider
// */
// public function test_user_send_unproccable_fileds($collectionFields, $dataFields)
// {
// $collection = Collection::factory()->create($collectionFields);
// $uuid = app()->uuid;
// $file = File::factory()->createQuietly([
// 'uuid' => $uuid,
// 'server_path' => '/' . date('y') . '/' . date('m') . '/',
// 'user_id' => auth()->id(),
// 'collection_id' => $collection->id
// ]);
// $response = $this->loginAs()->postJson(route('api.files.update', ['collection_name' => $collection->name, 'uuid' => $file->uuid, 'ext' => $collection->ext]), $dataFields);
// $response->assertUnprocessable();
// }
public function test_user_can_update_file()
{
$collection = Collection::factory()->createQuietly([
'alt_required' => false,
'description_required' => false,
'tmp_support' => true,
'max_width' => 2000,
'max_height' => 2000,
'min_width' => 1,
'min_height' => 1,
'min_file_size' => 0
]);
$uuid = app()->uuid;
$file = File::factory()->createQuietly([
'uuid' => $uuid,
'server_path' => '/' . date('y') . '/' . date('m') . '/',
'user_id' => auth()->id(),
'collection_id' => $collection->id
]);
$imageProcessor = new ImageProcessor;
$imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext));
$data = [
"original_name" => 'original name is very bad',
"description" => 'this is a description for file and has beed updated',
];
$response = $this->loginAs()->putJson(route('api.files.update', ['collection_name' => $collection->name, 'uuid' => $file->uuid, 'extention' => $collection->ext]), $data);
$response->assertok()->assertJson(['data' => $data]);
} }
} }

26
tests/Feature/Traits/FileTraits.php

@ -27,6 +27,22 @@ trait FileTraits
]; ];
} }
private function defaultArrayForUpdate()
{
return [
[
'alt_required' => false,
'description_required' => false,
'tmp_support' => true,
'max_width' => 2000,
'max_height' => 2000,
'min_width' => 1,
'min_height' => 1,
'min_file_size' => 0
]
];
}
private function changeDefaultArrayAndReturn($defaultArray, $key, $value): array private function changeDefaultArrayAndReturn($defaultArray, $key, $value): array
{ {
$defaultArray[$key[0]][$key[1]] = $value; $defaultArray[$key[0]][$key[1]] = $value;
@ -60,4 +76,14 @@ trait FileTraits
]; ];
return $data; return $data;
} }
public function updateValidationTestProvider()
{
$data = [
$this->changeDefaultArrayAndReturn($this->defaultArrayForUpdate(), [0, 'alt_required'], true),
$this->changeDefaultArrayAndReturn($this->defaultArrayForUpdate(), [0, 'description_required'], true),
];
return $data;
}
} }
Loading…
Cancel
Save