Add extensive controller and model tests
This commit is contained in:
214
tests/Unit/AttachmentThumbnailServiceBranchesTest.php
Normal file
214
tests/Unit/AttachmentThumbnailServiceBranchesTest.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services {
|
||||
if (!isset($GLOBALS['attachment_thumbnail_overrides'])) {
|
||||
$GLOBALS['attachment_thumbnail_overrides'] = [
|
||||
'force_imagecreatetruecolor_fail' => false,
|
||||
'force_imagejpeg_fail' => false,
|
||||
'force_imagecreatefromjpeg_fail' => false,
|
||||
'fake_getimagesize' => null,
|
||||
];
|
||||
}
|
||||
|
||||
if (!function_exists(__NAMESPACE__ . '\\imagecreatetruecolor')) {
|
||||
function imagecreatetruecolor($width, $height)
|
||||
{
|
||||
if (!empty($GLOBALS['attachment_thumbnail_overrides']['force_imagecreatetruecolor_fail'])) {
|
||||
return false;
|
||||
}
|
||||
return \imagecreatetruecolor($width, $height);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists(__NAMESPACE__ . '\\imagecreatefromjpeg')) {
|
||||
function imagecreatefromjpeg($path)
|
||||
{
|
||||
if (!empty($GLOBALS['attachment_thumbnail_overrides']['force_imagecreatefromjpeg_fail'])) {
|
||||
return false;
|
||||
}
|
||||
return \imagecreatefromjpeg($path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists(__NAMESPACE__ . '\\getimagesize')) {
|
||||
function getimagesize($path)
|
||||
{
|
||||
$override = $GLOBALS['attachment_thumbnail_overrides']['fake_getimagesize'] ?? null;
|
||||
if ($override !== null) {
|
||||
return $override;
|
||||
}
|
||||
return \getimagesize($path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists(__NAMESPACE__ . '\\imagejpeg')) {
|
||||
function imagejpeg($image, $to = null, $quality = null)
|
||||
{
|
||||
if (!empty($GLOBALS['attachment_thumbnail_overrides']['force_imagejpeg_fail'])) {
|
||||
return false;
|
||||
}
|
||||
if ($quality === null) {
|
||||
return \imagejpeg($image, $to);
|
||||
}
|
||||
return \imagejpeg($image, $to, $quality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
use App\Models\Attachment;
|
||||
use App\Models\Forum;
|
||||
use App\Models\Post;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Thread;
|
||||
use App\Services\AttachmentThumbnailService;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
if (!function_exists('imagewebp')) {
|
||||
function imagewebp($image, $to = null, $quality = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(function (): void {
|
||||
$GLOBALS['attachment_thumbnail_overrides'] = [
|
||||
'force_imagecreatetruecolor_fail' => false,
|
||||
'force_imagejpeg_fail' => false,
|
||||
'force_imagecreatefromjpeg_fail' => false,
|
||||
'fake_getimagesize' => null,
|
||||
];
|
||||
});
|
||||
|
||||
it('uses misc scope for attachments without thread or post', function (): void {
|
||||
if (!function_exists('imagecreatetruecolor')) {
|
||||
$this->markTestSkipped('GD extension not available.');
|
||||
}
|
||||
|
||||
Storage::fake('local');
|
||||
|
||||
Setting::updateOrCreate(['key' => 'attachments.create_thumbnails'], ['value' => 'true']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_width'], ['value' => '100']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_height'], ['value' => '100']);
|
||||
|
||||
$image = UploadedFile::fake()->image('photo.jpg', 800, 600);
|
||||
$path = 'attachments/misc/photo.jpg';
|
||||
Storage::disk('local')->put($path, file_get_contents($image->getPathname()));
|
||||
|
||||
$attachment = Attachment::create([
|
||||
'thread_id' => null,
|
||||
'post_id' => null,
|
||||
'attachment_extension_id' => null,
|
||||
'attachment_group_id' => null,
|
||||
'user_id' => null,
|
||||
'disk' => 'local',
|
||||
'path' => $path,
|
||||
'original_name' => 'photo.jpg',
|
||||
'extension' => 'jpg',
|
||||
'mime_type' => 'image/jpeg',
|
||||
'size_bytes' => 1234,
|
||||
]);
|
||||
|
||||
$service = new AttachmentThumbnailService();
|
||||
$result = $service->createForAttachment($attachment, true);
|
||||
|
||||
expect($result)->not->toBeNull();
|
||||
expect($result['path'])->toContain('attachments/misc/thumbs/');
|
||||
});
|
||||
|
||||
it('returns null when image dimensions are zero', function (): void {
|
||||
Storage::fake('local');
|
||||
|
||||
Setting::updateOrCreate(['key' => 'attachments.create_thumbnails'], ['value' => 'true']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_width'], ['value' => '100']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_height'], ['value' => '100']);
|
||||
|
||||
$GLOBALS['attachment_thumbnail_overrides']['fake_getimagesize'] = [0, 0, IMAGETYPE_JPEG];
|
||||
|
||||
$service = new AttachmentThumbnailService();
|
||||
$file = UploadedFile::fake()->image('photo.jpg', 800, 600);
|
||||
|
||||
$result = $service->createForUpload($file, 'threads/1', 'local');
|
||||
|
||||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
it('returns null when thumbnail image creation fails', function (): void {
|
||||
if (!function_exists('imagecreatetruecolor')) {
|
||||
$this->markTestSkipped('GD extension not available.');
|
||||
}
|
||||
|
||||
Storage::fake('local');
|
||||
|
||||
Setting::updateOrCreate(['key' => 'attachments.create_thumbnails'], ['value' => 'true']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_width'], ['value' => '100']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_height'], ['value' => '100']);
|
||||
|
||||
$GLOBALS['attachment_thumbnail_overrides']['force_imagecreatetruecolor_fail'] = true;
|
||||
|
||||
$service = new AttachmentThumbnailService();
|
||||
$file = UploadedFile::fake()->image('photo.jpg', 800, 600);
|
||||
|
||||
$result = $service->createForUpload($file, 'threads/1', 'local');
|
||||
|
||||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
it('returns null when renderer fails to encode', function (): void {
|
||||
if (!function_exists('imagecreatetruecolor')) {
|
||||
$this->markTestSkipped('GD extension not available.');
|
||||
}
|
||||
|
||||
Storage::fake('local');
|
||||
|
||||
Setting::updateOrCreate(['key' => 'attachments.create_thumbnails'], ['value' => 'true']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_width'], ['value' => '100']);
|
||||
Setting::updateOrCreate(['key' => 'attachments.thumbnail_max_height'], ['value' => '100']);
|
||||
|
||||
$GLOBALS['attachment_thumbnail_overrides']['force_imagejpeg_fail'] = true;
|
||||
|
||||
$service = new AttachmentThumbnailService();
|
||||
$file = UploadedFile::fake()->image('photo.jpg', 800, 600);
|
||||
|
||||
$result = $service->createForUpload($file, 'threads/1', 'local');
|
||||
|
||||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
it('handles webp branch in image loader', function (): void {
|
||||
$service = new AttachmentThumbnailService();
|
||||
$ref = new ReflectionMethod($service, 'createImageFromFile');
|
||||
$ref->setAccessible(true);
|
||||
|
||||
$temp = tempnam(sys_get_temp_dir(), 'webp');
|
||||
file_put_contents($temp, 'not-a-real-webp');
|
||||
|
||||
$result = $ref->invoke($service, $temp, 'image/webp');
|
||||
expect($result === null || $result === false)->toBeTrue();
|
||||
|
||||
unlink($temp);
|
||||
});
|
||||
|
||||
it('handles webp branch in renderer when available', function (): void {
|
||||
$service = new AttachmentThumbnailService();
|
||||
$ref = new ReflectionMethod($service, 'renderImageBinary');
|
||||
$ref->setAccessible(true);
|
||||
|
||||
$image = \imagecreatetruecolor(10, 10);
|
||||
$data = $ref->invoke($service, $image, 'image/webp', 80);
|
||||
|
||||
expect($data === null || is_string($data))->toBeTrue();
|
||||
imagedestroy($image);
|
||||
});
|
||||
|
||||
it('returns default when setting is missing', function (): void {
|
||||
$service = new AttachmentThumbnailService();
|
||||
$ref = new ReflectionMethod($service, 'settingBool');
|
||||
$ref->setAccessible(true);
|
||||
|
||||
$result = $ref->invoke($service, 'attachments.missing_flag', true);
|
||||
|
||||
expect($result)->toBeTrue();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user