Skip to content

Commit

Permalink
Test a queued job can upload and resize an image
Browse files Browse the repository at this point in the history
  • Loading branch information
unclexo committed Jan 27, 2023
1 parent 4191243 commit b49cd29
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 9 deletions.
15 changes: 15 additions & 0 deletions app/Http/Controllers/MediaUploaderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,28 @@ public function download($filename)
return response()->download($privateFilepath, $filename);
}

public function uploader()
{
return view('upload.uploader');
}

public function uploadAndResizing()
{
\request()->validate([
'image' => ['required', 'mimes:jpg,png', 'max:1024'],
]);

$image = request()->file('image');

if ($image instanceof UploadedFile) {
ImageUploadAndResizingJob::dispatch($image->getMimeType(), base64_encode($image->getContent()))
->delay(now()->addSeconds(5));

return redirect()->route('uploader')->with([
'message' => 'Image upload and resizing may take few moments.'
]);
}

return redirect()->route('uploader')->with(['failed' => 'Could not upload the image.']);
}
}
50 changes: 46 additions & 4 deletions app/Jobs/ImageUploadAndResizingJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,70 @@
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

class ImageUploadAndResizingJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public string $mimeType;

public string $imageContent;

public array $resolutions = [
'50x50' => [50, 50],
'640x480' => [640, 480],
];

/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
public function __construct(string $mimeType, string $imageContent)
{
//
$this->mimeType = $mimeType;
$this->imageContent = $imageContent;
}

/**
* Execute the job.
*
* @return void
* @return array
*/
public function handle()
{
//
$storage = Storage::disk('public');

$path = 'fake-image-name.jpg';

$storage->put($path, base64_decode($this->imageContent));

$paths = [];

foreach ($this->resolutions as $key => $resolution) {
$image = Image::make($absolutePath = $storage->path($path))
->resize($resolution[0], $resolution[1])
->save($this->absolutePathWithResolutionKey($absolutePath, $key));

$paths[] = $image->basename;
}

return $paths;
}

/**
* Modify an absolute path for renaming image name with resolution key
*
* @param string $absoluteFilePath
* @param string $resolutionKey
* @return string
*/
private function absolutePathWithResolutionKey(string $absoluteFilePath, string $resolutionKey)
{
[$path, $extension] = explode('.', $absoluteFilePath);

return $path . '-' . $resolutionKey . '.' . $extension;
}
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"laravel/framework": "^9.19",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7",
"laravel/ui": "^4.1"
"laravel/ui": "^4.1",
"predis/predis": "^2.1"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
Expand Down
72 changes: 71 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion config/database.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@

'redis' => [

'client' => env('REDIS_CLIENT', 'phpredis'),
'client' => env('REDIS_CLIENT', 'predis'),

'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
Expand Down
8 changes: 7 additions & 1 deletion resources/views/layouts/app.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav me-auto">
@if(\Illuminate\Support\Facades\Route::has('posts.index'))
@if(Route::has('posts.index'))
<a href="{{ route('posts.index') }}">{{ __('Posts') }}</a>
@endif

&nbsp;&nbsp;

@if(Route::has('uploader'))
<a href="{{ route('uploader') }}">{{ __('Uploader') }}</a>
@endif
</ul>

<!-- Right Side Of Navbar -->
Expand Down
48 changes: 48 additions & 0 deletions resources/views/upload/uploader.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<div>{{ __('Image Uploader') }}</div>
</div>

<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

@if (session('failed'))
<div class="alert alert-warning">
{{ session('failed') }}
</div>
@endif

@if (session('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
@endif

<form method="POST" action="{{ route('upload.resize.via.queue') }}" enctype="multipart/form-data" class="flex items-center space-x-6">
@csrf

<div class="input-group">
<input type="file" name="image" class="form-control" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04" aria-label="Upload">
<button class="btn btn-primary" type="submit" id="inputGroupFileAddon04">{{ __('Upload') }}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
2 changes: 2 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
Route::post('/upload/private', 'uploadPrivate')->name('upload.private');

Route::get('/upload/download/{filename}', 'download')->name('upload.download');

Route::get('/uploader', 'uploader')->name('uploader');
});

Route::prefix('mailable')->group(function() {
Expand Down
17 changes: 16 additions & 1 deletion tests/Feature/JobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class JobTest extends TestCase
Expand All @@ -23,7 +24,7 @@ public function a_job_is_dispatchable()
$this->assertTrue(in_array(Dispatchable::class, $job->getTraitNames()));

$this->assertTrue(method_exists(
app(ImageUploadAndResizingJob::class),
app(ImageUploadAndResizingJob::class, ['mimeType' => 'image/jpeg', 'imageContent' => 'content']),
'handle'
));
}
Expand All @@ -43,4 +44,18 @@ public function queue_api_can_be_instructed_to_dispatch_image_upload_and_resizin

Queue::assertPushed(ImageUploadAndResizingJob::class);
}

/** @test */
public function an_image_can_be_uploaded_and_resized_via_a_queued_job()
{
Storage::fake('public');

$image = UploadedFile::fake()
->image('a-large-image.jpg', 1000, 1000) // Increase width and height to upload a large image
->mimeType('image/jpeg');

$job = new ImageUploadAndResizingJob($image->getMimeType(), base64_encode($image->getContent()));

Storage::disk('public')->assertExists($job->handle());
}
}

0 comments on commit b49cd29

Please sign in to comment.