From 138d37e83460f86077ee04f203356cdf791385c1 Mon Sep 17 00:00:00 2001 From: Josh Manders Date: Sun, 12 Oct 2025 23:50:46 -0500 Subject: [PATCH] Add unit tests for image, video, and widget components; refactor image and video rendering logic --- tests/Unit/ImageComponentTest.php | 68 ++++++++++++++++++++++++++++++ tests/Unit/VideoComponentTest.php | 20 +++++++++ tests/Unit/WidgetComponentTest.php | 19 +++++++++ views/components/image.blade.php | 39 ++++++++--------- views/components/video.blade.php | 16 +++++-- 5 files changed, 136 insertions(+), 26 deletions(-) create mode 100644 tests/Unit/ImageComponentTest.php create mode 100644 tests/Unit/VideoComponentTest.php create mode 100644 tests/Unit/WidgetComponentTest.php diff --git a/tests/Unit/ImageComponentTest.php b/tests/Unit/ImageComponentTest.php new file mode 100644 index 0000000..16720fd --- /dev/null +++ b/tests/Unit/ImageComponentTest.php @@ -0,0 +1,68 @@ +app->instance( + \Cloudinary\Cloudinary::class, + new \Cloudinary\Cloudinary('cloudinary://key:secret@demo') + ); +}); + +it('renders image component with both class and alt attributes', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'class' => 'img-fluid', + 'alt' => 'Parallax Background Image', + ])->render(); + + expect($html)->toContain('class="img-fluid"'); + expect($html)->toContain('alt="Parallax Background Image"'); +}); + +it('includes crop, width and height transformation when provided', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'crop' => 'fill', + 'width' => 300, + 'height' => 200, + ])->render(); + + expect($html)->toContain('w_'); + expect($html)->toContain('h_'); + expect($html)->toContain('c_'); +}); + +it('includes rotation when rotate attribute is provided', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'rotate' => 90, + ])->render(); + + expect($html)->toContain('a_'); +}); + +it('applies grayscale effect when requested', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'grayscale' => true, + ])->render(); + + expect($html)->toContain('e_grayscale'); +}); + +it('applies round corners when requested', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'roundCorners' => true, + ])->render(); + + expect($html)->toContain('r_'); +}); + +it('preserves multiple classes when provided', function () { + $html = view('cloudinary::components.image', [ + 'publicId' => 'example', + 'class' => 'img-fluid rounded mx-auto', + ])->render(); + + expect($html)->toContain('class="img-fluid rounded mx-auto"'); +}); diff --git a/tests/Unit/VideoComponentTest.php b/tests/Unit/VideoComponentTest.php new file mode 100644 index 0000000..72e2ae0 --- /dev/null +++ b/tests/Unit/VideoComponentTest.php @@ -0,0 +1,20 @@ +app->instance( + \Cloudinary\Cloudinary::class, + new \Cloudinary\Cloudinary('cloudinary://key:secret@demo') + ); +}); + +it('renders video component with default attributes and method', function () { + $html = view('cloudinary::components.video', [ + 'publicId' => 'example', + 'width' => 640, + 'height' => 360, + ])->render(); + + expect($html)->toContain('controls'); + expect($html)->toContain('preload'); + expect($html)->toContain('src="'); +}); diff --git a/tests/Unit/WidgetComponentTest.php b/tests/Unit/WidgetComponentTest.php new file mode 100644 index 0000000..a740f38 --- /dev/null +++ b/tests/Unit/WidgetComponentTest.php @@ -0,0 +1,19 @@ +app->instance( + \Cloudinary\Cloudinary::class, + new \Cloudinary\Cloudinary('cloudinary://key:secret@demo') + ); +}); + +it('renders widget component button with onclick and slot content', function () { + $html = view('cloudinary::components.widget', [ + 'slot' => 'Upload', + 'attributes' => '', + ])->render(); + + expect($html)->toContain('onclick="openWidget()"'); + expect($html)->toContain('Upload'); + expect($html)->toContain('cloudinary.com'); +}); diff --git a/views/components/image.blade.php b/views/components/image.blade.php index f1596ee..9cb1036 100644 --- a/views/components/image.blade.php +++ b/views/components/image.blade.php @@ -15,28 +15,22 @@ use Cloudinary\Transformation\ImproveMode; use Illuminate\Support\Str; - $retrieveFormattedImage = cloudinary()->imageTag($publicId ?? ''); + $retrieveFormattedImage = cloudinary()->imageTag($publicId ?? ''); + + $attrs = []; /** * SET ALT if provided */ if (isset($alt)) { - $retrieveFormattedImage = cloudinary() - ->imageTag($publicId ?? '') - ->setAttributes([ - 'alt' => $alt ?? $publicId, - ]); + $attrs['alt'] = $alt ?? $publicId; } /** * SET CLASS if provided */ if (isset($class)) { - $retrieveFormattedImage = cloudinary() - ->imageTag($publicId ?? '') - ->setAttributes([ - 'class' => $class, - ]); + $attrs['class'] = $class; } /** @@ -85,13 +79,11 @@ $cropFactor = 'minimumPad'; } - $retrieveFormattedImage = cloudinary() - ->imageTag($publicId ?? '') - ->resize( - Resize::$cropFactor() - ->width($width ?? '') - ->height($height ?? ''), - ); + $retrieveFormattedImage = $retrieveFormattedImage->resize( + Resize::$cropFactor() + ->width($width ?? '') + ->height($height ?? ''), + ); /** * If the attribute is "gravity" @@ -123,9 +115,7 @@ ->gravity(Gravity::focusOn(FocusOn::$gravity())); } - $retrieveFormattedImage = cloudinary() - ->imageTag($publicId ?? '') - ->resize($gravityImplementation); + $retrieveFormattedImage = $retrieveFormattedImage->resize($gravityImplementation); } } } @@ -484,6 +474,11 @@ } } - echo $retrieveFormattedImage->serialize(); + // Apply collected attributes once so we don't overwrite previous attributes. + if (!empty($attrs)) { + $retrieveFormattedImage = $retrieveFormattedImage->setAttributes($attrs); + } + + echo $retrieveFormattedImage->serialize(); @endphp diff --git a/views/components/video.blade.php b/views/components/video.blade.php index 09e1d5b..7cc06ad 100644 --- a/views/components/video.blade.php +++ b/views/components/video.blade.php @@ -1,8 +1,16 @@ @php $defaultFormatMethod = 'scale'; $retrieveFormattedVideo = cloudinary() - ->videoTag($publicId ?? '') - ->setAttributes(['controls', 'loop', 'preload']) - ->fallback('Your browser does not support HTML5 video tagsssss.') - ->$defaultFormatMethod($width ?? '', $height ?? ''); + ->videoTag($publicId ?? '') + ->setAttributes([ + 'controls' => true, + 'loop' => true, + 'preload' => 'auto', + ]) + ->fallback('Your browser does not support HTML5 video tags.') + ->$defaultFormatMethod($width ?? '', $height ?? ''); +@endphp + +@php + echo $retrieveFormattedVideo->serialize(); @endphp