diff --git a/composer.json b/composer.json index 2448bafb..6f415060 100644 --- a/composer.json +++ b/composer.json @@ -16,15 +16,17 @@ "illuminate/filesystem": ">6.0", "illuminate/database": ">6.0", "league/flysystem": "^1.0.23", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0", + "intervention/image": "^2.5", + "guzzlehttp/guzzle": "^6.5|^7.1" }, "require-dev": { - "orchestra/testbench": "^3.3|^4.0|^5.0|^6.0", + "orchestra/testbench": "^4.0|^5.0|^6.0", "phpunit/phpunit": "^8.2.4|^9.0", - "vlucas/phpdotenv": "^3.3|^4.0|^5.0", + "vlucas/phpdotenv": "^4.0|^5.0", "league/flysystem-aws-s3-v3" : "^1.0.23", "guzzlehttp/promises": "^1.3", - "aws/aws-sdk-php": "^3.29.0", + "aws/aws-sdk-php": "^3.128.0", "php-coveralls/php-coveralls": "^2.1", "laravel/legacy-factories": "^1.0.4" }, diff --git a/phpunit.xml b/phpunit.xml index a2f5af27..f2f4de41 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,8 +1,8 @@ - - - - ./tests/integration/ - - - - - ./src/ - - - - - + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + + + ./src/ + + + + + ./tests/Integration/ + + + + + diff --git a/src/Exceptions/ImageManipulationException.php b/src/Exceptions/ImageManipulationException.php new file mode 100644 index 00000000..40b21165 --- /dev/null +++ b/src/Exceptions/ImageManipulationException.php @@ -0,0 +1,28 @@ + 'image/jpeg', + self::FORMAT_PNG => 'image/png', + self::FORMAT_GIF => 'image/gif', + self::FORMAT_TIFF => 'image/tiff', + self::FORMAT_BMP => 'image/bmp', + self::FORMAT_WEBP => 'image/webp' + ]; + + /** @var callable */ + private $callback; + + /** @var string|null */ + private $outputFormat; + + /** @var int */ + private $outputQuality = 90; + + /** @var callable|null */ + private $beforeSave; + + public function __construct(callable $callback) + { + $this->callback = $callback; + } + + public static function make(callable $callback) + { + return new self($callback); + } + + /** + * @return \Closure + */ + public function getCallback(): \Closure + { + return $this->callback; + } + + /** + * @return int + */ + public function getOutputQuality(): int + { + return $this->outputQuality; + } + + /** + * @param int $outputQuality + * @return $this + */ + public function setOutputQuality(int $outputQuality): self + { + $this->outputQuality = min(100, max(0, $outputQuality)); + + return $this; + } + + /** + * @return string|null + */ + public function getOutputFormat(): ?string + { + return $this->outputFormat; + } + + /** + * @param string|null $outputFormat + * @return $this + */ + public function setOutputFormat(?string $outputFormat): self + { + $this->outputFormat = $outputFormat; + + return $this; + } + + /** + * @return $this + */ + public function toJpegFormat(): self + { + $this->setOutputFormat(self::FORMAT_JPG); + + return $this; + } + + /** + * @return $this + */ + public function toPngFormat(): self + { + $this->setOutputFormat(self::FORMAT_PNG); + + return $this; + } + + /** + * @return $this + */ + public function toGifFormat(): self + { + $this->setOutputFormat(self::FORMAT_GIF); + + return $this; + } + + /** + * @return $this + */ + public function toTiffFormat(): self + { + $this->setOutputFormat(self::FORMAT_TIFF); + + return $this; + } + + /** + * @return $this + */ + public function toBmpFormat(): self + { + $this->setOutputFormat(self::FORMAT_BMP); + + return $this; + } + + /** + * @return $this + */ + public function toWebpFormat(): self + { + $this->setOutputFormat(self::FORMAT_WEBP); + + return $this; + } + + /** + * @return callable + */ + public function getBeforeSave(): ?callable + { + return $this->beforeSave; + } + + /** + * @param callable $beforeSave + * @return $this + */ + public function beforeSave(callable $beforeSave): self + { + $this->beforeSave = $beforeSave; + + return $this; + } +} diff --git a/src/ImageManipulator.php b/src/ImageManipulator.php new file mode 100644 index 00000000..d5d35ea8 --- /dev/null +++ b/src/ImageManipulator.php @@ -0,0 +1,142 @@ +imageManager = $imageManager; + $this->filesystem = $filesystem; + } + + public function addVariantManipulation( + string $variantName, + ImageManipulation $manipulation + ) { + $this->variantManipulations[$variantName] = $manipulation; + } + + /** + * @param ImageManipulation $manipulation + * @param Media $media + * @return StreamInterface + * @throws ImageManipulationException + */ + public function createVariant(string $variantName, Media $media): Media + { + if ($media->aggregate_type != Media::TYPE_IMAGE) { + throw ImageManipulationException::invalidMediaType($media->aggregate_type); + } + + $manipulation = $this->getVariantManipulation($variantName); + + $outputFormat = $this->determineOutputFormat($manipulation, $media); + $image = $this->imageManager->make($media->stream()); + + $callback = $manipulation->getCallback(); + $callback($image); + + $outputStream = $image->stream( + $outputFormat, + $manipulation->getOutputQuality() + ); + + $modelClass = config('mediable.model'); + /** @var Media $newMedia */ + $newMedia = new $modelClass(); + $newMedia->disk = $media->disk; + $newMedia->directory = $media->directory; + $newMedia->filename = sprintf('%s-%s', $media->filename, $variantName); + $newMedia->extension = $outputFormat; + $newMedia->mime_type = $this->getMimeTypeForOutputFormat($outputFormat); + $newMedia->aggregate_type = Media::TYPE_IMAGE; + $newMedia->size = $outputStream->getSize(); + + if ($beforeSave = $manipulation->getBeforeSave()) { + $beforeSave($newMedia); + } + + $this->filesystem->disk($newMedia->disk) + ->writeStream($newMedia->getDiskPath(), $outputStream->detach()); + + $newMedia->save(); + + return $newMedia; + } + + /** + * @param string $variantName + * @return ImageManipulation + * @throws ImageManipulationException + */ + private function getVariantManipulation(string $variantName): ImageManipulation + { + if (isset($this->variantManipulations[$variantName])) { + return $this->variantManipulations[$variantName]; + } + + throw ImageManipulationException::unknownVariant($variantName); + } + + private function getMimeTypeForOutputFormat(string $outputFormat): string + { + return ImageManipulation::MIME_TYPE_MAP[$outputFormat]; + } + + /** + * @param ImageManipulation $manipulation + * @param Media $media + * @return string + * @throws ImageManipulationException + */ + private function determineOutputFormat( + ImageManipulation $manipulation, + Media $media + ): string { + if ($format = $manipulation->getOutputFormat()) { + return $format; + } + + // attempt to infer the format from the mime type + $mime = strtolower($media->mime_type); + $format = array_search($mime, ImageManipulation::MIME_TYPE_MAP); + if ($format !== false) { + return $format; + } + + // attempt to infer the format from the file extension + $extension = strtolower($media->extension); + if (in_array($extension, ImageManipulation::VALID_IMAGE_FORMATS)) { + return $extension; + } + if ($extension === 'jpeg') { + return ImageManipulation::FORMAT_JPG; + } + if ($extension === 'tiff') { + return ImageManipulation::FORMAT_TIFF; + } + + throw ImageManipulationException::unknownOutputFormat(); + } +} diff --git a/src/Jobs/ProcessImageVariant.php b/src/Jobs/ProcessImageVariant.php new file mode 100644 index 00000000..c0ba23aa --- /dev/null +++ b/src/Jobs/ProcessImageVariant.php @@ -0,0 +1,55 @@ +variantName = $variantName; + $this->model = $model; + } + + public function handle() + { + app(ImageManipulator::class)->createVariant( + $this->getVariantName(), + $this->getModel() + ); + } + + /** + * @return string + */ + public function getVariantName(): string + { + return $this->variantName; + } + + /** + * @return Media + */ + public function getModel(): Media + { + return $this->model; + } +} diff --git a/src/Media.php b/src/Media.php index 656fc202..b3d55d56 100644 --- a/src/Media.php +++ b/src/Media.php @@ -14,6 +14,7 @@ use Plank\Mediable\Exceptions\MediaUrlException; use Plank\Mediable\Helpers\File; use Plank\Mediable\UrlGenerators\UrlGeneratorInterface; +use Psr\Http\Message\StreamInterface; /** * Media Model. @@ -248,6 +249,17 @@ public function contents(): string return $this->storage()->get($this->getDiskPath()); } + /** + * Get a read stream to the file + * @return StreamInterface + */ + public function stream() + { + return \GuzzleHttp\Psr7\stream_for( + $this->storage()->readStream($this->getDiskPath()) + ); + } + /** * Move the file to a new location on disk. * diff --git a/src/MediableServiceProvider.php b/src/MediableServiceProvider.php index dee79593..6be983d5 100644 --- a/src/MediableServiceProvider.php +++ b/src/MediableServiceProvider.php @@ -54,6 +54,7 @@ public function register(): void $this->registerMover(); $this->registerUrlGeneratorFactory(); $this->registerConsoleCommands(); + $this->registerImageManipulator(); } /** @@ -129,6 +130,11 @@ public function registerUrlGeneratorFactory(): void $this->app->alias('mediable.url.factory', UrlGeneratorFactory::class); } + public function registerImageManipulator(): void + { + $this->app->singleton(ImageManipulator::class); + } + /** * Add package commands to artisan console. * @return void diff --git a/tests/Integration/Commands/ImportMediaCommandTest.php b/tests/Integration/Commands/ImportMediaCommandTest.php index 4cdc6099..b8856274 100644 --- a/tests/Integration/Commands/ImportMediaCommandTest.php +++ b/tests/Integration/Commands/ImportMediaCommandTest.php @@ -35,14 +35,21 @@ public function test_it_creates_media_for_unmatched_files() $artisan->call('media:import', ['disk' => 'tmp']); $this->assertEquals("Imported 1 file(s).\n", $artisan->output()); - $this->assertEquals(['bar', 'foo'], Media::orderBy('filename')->pluck('filename')->toArray()); + $this->assertEquals( + ['bar', 'foo'], + Media::orderBy('filename')->pluck('filename')->toArray() + ); } public function test_it_creates_media_for_unmatched_files_in_directory() { $artisan = $this->getArtisan(); - $media1 = factory(Media::class)->make(['disk' => 'tmp', 'directory' => 'a', 'filename' => 'foo']); - $media2 = factory(Media::class)->make(['disk' => 'tmp', 'directory' => 'a/b', 'filename' => 'bar']); + $media1 = factory(Media::class)->make( + ['disk' => 'tmp', 'directory' => 'a', 'filename' => 'foo'] + ); + $media2 = factory(Media::class)->make( + ['disk' => 'tmp', 'directory' => 'a/b', 'filename' => 'bar'] + ); $this->seedFileForMedia($media1); $this->seedFileForMedia($media2); @@ -55,12 +62,19 @@ public function test_it_creates_media_for_unmatched_files_in_directory() public function test_it_creates_media_for_unmatched_files_non_recursively() { $artisan = $this->getArtisan(); - $media1 = factory(Media::class)->make(['disk' => 'tmp', 'directory' => 'a', 'filename' => 'foo']); - $media2 = factory(Media::class)->make(['disk' => 'tmp', 'directory' => 'a/b', 'filename' => 'bar']); + $media1 = factory(Media::class)->make( + ['disk' => 'tmp', 'directory' => 'a', 'filename' => 'foo'] + ); + $media2 = factory(Media::class)->make( + ['disk' => 'tmp', 'directory' => 'a/b', 'filename' => 'bar'] + ); $this->seedFileForMedia($media1); $this->seedFileForMedia($media2); - $artisan->call('media:import', ['disk' => 'tmp', '--directory' => 'a', '--non-recursive' => true]); + $artisan->call( + 'media:import', + ['disk' => 'tmp', '--directory' => 'a', '--non-recursive' => true] + ); $this->assertEquals("Imported 1 file(s).\n", $artisan->output()); $this->assertEquals(['foo'], Media::pluck('filename')->toArray()); @@ -76,39 +90,54 @@ public function test_it_skips_files_of_unmatched_aggregate_type() $uploader->setAllowedAggregateTypes(['image']); $command = new ImportMediaCommand($filesystem, $uploader); - $media = factory(Media::class)->make(['disk' => 'tmp', 'extension' => 'foo', 'mime_type' => 'bar']); + $media = factory(Media::class)->make( + ['disk' => 'tmp', 'extension' => 'foo', 'mime_type' => 'bar'] + ); $this->seedFileForMedia($media); $artisan->registerCommand($command); $artisan->call('media:import', ['disk' => 'tmp']); - $this->assertEquals("Imported 0 file(s).\nSkipped 1 file(s).\n", $artisan->output()); + $this->assertEquals( + "Imported 0 file(s).\nSkipped 1 file(s).\n", + $artisan->output() + ); } public function test_it_updates_existing_media() { $artisan = $this->getArtisan(); - $media1 = factory(Media::class)->create([ - 'disk' => 'tmp', - 'filename' => 'bar', - 'extension' => 'png', - 'mime_type' => 'image/png', - 'aggregate_type' => 'foo' - ]); - $media2 = factory(Media::class)->create([ - 'disk' => 'tmp', - 'filename' => 'bar', - 'extension' => 'png', - 'size' => 7173, - 'mime_type' => 'image/png', - 'aggregate_type' => 'image' - ]); + $media1 = factory(Media::class)->create( + [ + 'disk' => 'tmp', + 'filename' => 'bar', + 'extension' => 'png', + 'mime_type' => 'image/png', + 'aggregate_type' => 'foo' + ] + ); + $media2 = factory(Media::class)->create( + [ + 'disk' => 'tmp', + 'filename' => 'bar', + 'extension' => 'png', + 'size' => 7173, + 'mime_type' => 'image/png', + 'aggregate_type' => 'image' + ] + ); $this->seedFileForMedia($media1, fopen($this->sampleFilePath(), 'r')); $this->seedFileForMedia($media2, fopen($this->sampleFilePath(), 'r')); $artisan->call('media:import', ['disk' => 'tmp', '--force' => true]); - $this->assertEquals(['image', 'image'], Media::pluck('aggregate_type')->toArray()); - $this->assertEquals("Imported 0 file(s).\nUpdated 1 record(s).\nSkipped 1 file(s).\n", $artisan->output()); + $this->assertEquals( + ['image', 'image'], + Media::pluck('aggregate_type')->toArray() + ); + $this->assertEquals( + "Imported 0 file(s).\nUpdated 1 record(s).\nSkipped 1 file(s).\n", + $artisan->output() + ); } protected function getArtisan() diff --git a/tests/Integration/Commands/PruneMediaCommandTest.php b/tests/Integration/Commands/PruneMediaCommandTest.php index bb8e66fa..b583de1d 100644 --- a/tests/Integration/Commands/PruneMediaCommandTest.php +++ b/tests/Integration/Commands/PruneMediaCommandTest.php @@ -31,8 +31,12 @@ public function test_it_deletes_media_without_files() public function test_it_prunes_directory() { $artisan = $this->getArtisan(); - $media1 = factory(Media::class)->create(['id' => 1, 'disk' => 'tmp', 'directory' => '']); - $media2 = factory(Media::class)->create(['id' => 2, 'disk' => 'tmp', 'directory' => 'foo']); + $media1 = factory(Media::class)->create( + ['id' => 1, 'disk' => 'tmp', 'directory' => ''] + ); + $media2 = factory(Media::class)->create( + ['id' => 2, 'disk' => 'tmp', 'directory' => 'foo'] + ); $artisan->call('media:prune', ['disk' => 'tmp', '--directory' => 'foo']); @@ -43,8 +47,12 @@ public function test_it_prunes_directory() public function test_it_prunes_non_recursively() { $artisan = $this->getArtisan(); - $media1 = factory(Media::class)->create(['id' => 1, 'disk' => 'tmp', 'directory' => '']); - $media2 = factory(Media::class)->create(['id' => 2, 'disk' => 'tmp', 'directory' => 'foo']); + $media1 = factory(Media::class)->create( + ['id' => 1, 'disk' => 'tmp', 'directory' => ''] + ); + $media2 = factory(Media::class)->create( + ['id' => 2, 'disk' => 'tmp', 'directory' => 'foo'] + ); $artisan->call('media:prune', ['disk' => 'tmp', '--non-recursive' => true]); diff --git a/tests/Integration/ImageManipulationTest.php b/tests/Integration/ImageManipulationTest.php new file mode 100644 index 00000000..81b944c8 --- /dev/null +++ b/tests/Integration/ImageManipulationTest.php @@ -0,0 +1,64 @@ +getCallback(); + $manipulation = new ImageManipulation($callback); + $this->assertSame($callback, $manipulation->getCallback()); + } + + public function test_can_get_set_output_quality() + { + $manipulation = new ImageManipulation($this->getCallback()); + $this->assertEquals(90, $manipulation->getOutputQuality()); + $manipulation->setOutputQuality(-100); + $this->assertEquals(0, $manipulation->getOutputQuality()); + $manipulation->setOutputQuality(500); + $this->assertEquals(100, $manipulation->getOutputQuality()); + $manipulation->setOutputQuality(50); + $this->assertEquals(50, $manipulation->getOutputQuality()); + } + + public function test_can_get_set_output_format() + { + $manipulation = new ImageManipulation($this->getCallback()); + $this->assertNull($manipulation->getOutputFormat()); + $manipulation->setOutputFormat('jpg'); + $this->assertEquals('jpg', $manipulation->getOutputFormat()); + $manipulation->toBmpFormat(); + $this->assertEquals('bmp', $manipulation->getOutputFormat()); + $manipulation->toGifFormat(); + $this->assertEquals('gif', $manipulation->getOutputFormat()); + $manipulation->toPngFormat(); + $this->assertEquals('png', $manipulation->getOutputFormat()); + $manipulation->toTiffFormat(); + $this->assertEquals('tif', $manipulation->getOutputFormat()); + $manipulation->toWebpFormat(); + $this->assertEquals('webp', $manipulation->getOutputFormat()); + $manipulation->toJpegFormat(); + $this->assertEquals('jpg', $manipulation->getOutputFormat()); + } + + public function test_can_get_set_before_save_callback() + { + $callback = $this->getCallback(); + $manipulation = new ImageManipulation($this->getCallback()); + + $this->assertNull($manipulation->getBeforeSave()); + $manipulation->beforeSave($callback); + $this->assertSame($callback, $manipulation->getBeforeSave()); + } + + private function getCallback() + { + return function () { + }; + } +} diff --git a/tests/Integration/ImageManipulatorTest.php b/tests/Integration/ImageManipulatorTest.php new file mode 100644 index 00000000..72e244db --- /dev/null +++ b/tests/Integration/ImageManipulatorTest.php @@ -0,0 +1,165 @@ +expectException(ImageManipulationException::class); + $this->expectErrorMessage( + "Cannot manipulate media with an aggregate type other than 'image', got 'document'." + ); + $this->getManipulator()->createVariant( + 'variant', + $this->makeMedia(['aggregate_type' => 'document']) + ); + } + + public function test_it_throws_for_unknown_variants() + { + $this->expectException(ImageManipulationException::class); + $this->expectErrorMessage("Unknown variant 'invalid'."); + $this->getManipulator()->createVariant( + 'invalid', + $this->makeMedia(['aggregate_type' => 'image']) + ); + } + + public function test_it_throws_for_indeterminate_output_format() + { + $this->useFilesystem('tmp'); + $this->expectException(ImageManipulationException::class); + $this->expectErrorMessage("Unable to determine valid output format for file."); + $manipulation = ImageManipulation::make( + function (Image $image) { + } + ); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'filename' => 'foo', + 'extension' => 'psd', + 'aggregate_type' => 'image' + ] + ); + $this->seedFileForMedia($media); + $manipulator = $this->getManipulator(); + $manipulator->addVariantManipulation('foo', $manipulation); + $manipulator->createVariant('foo', $media); + } + + public function test_it_can_create_a_variant() + { + $this->useFilesystem('tmp'); + $this->useDatabase(); + + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'png', + 'aggregate_type' => 'image' + ] + ); + $this->seedFileForMedia($media, $this->sampleFile()); + + $beforeSave = $this->getMockCallback(); + $beforeSave->expects($this->once()) + ->method('__invoke') + ->with( + $this->callback( + function (Media $media) { + $result = $media->directory === 'foo'; + $media->directory = 'baz'; + return $result; + } + ) + ); + + $manipulation = ImageManipulation::make( + function (Image $image) { + $image->resize(16, 16); + } + )->beforeSave($beforeSave); + + $imageManipulator = $this->getManipulator(); + $imageManipulator->addVariantManipulation('test', $manipulation); + $result = $imageManipulator->createVariant('test', $media); + + $this->assertTrue($result->exists); + $this->assertEquals('tmp', $result->disk); + $this->assertEquals('baz', $result->directory); + $this->assertEquals('bar-test', $result->filename); + $this->assertEquals('png', $result->extension); + $this->assertEquals('image/png', $result->mime_type); + $this->assertEquals('image', $result->aggregate_type); + $this->assertEquals(449, $result->size); + $this->assertTrue($media->fileExists()); + } + + public function formatProvider() + { + return [ + ['jpg', 'image/jpeg', 100], + ['jpg', 'image/jpeg', 10], + ['gif', 'image/gif', 90], + ]; + } + + /** + * @dataProvider formatProvider + */ + public function test_it_can_create_a_variant_of_a_different_format( + string $format, + string $mime, + int $quality + ) { + $this->useFilesystem('tmp'); + $this->useDatabase(); + + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'png', + 'aggregate_type' => 'image' + ] + ); + $this->seedFileForMedia($media, $this->sampleFile()); + + $manipulation = ImageManipulation::make( + function (Image $image) { + $image->resize(16, 16); + } + )->setOutputFormat($format)->setOutputQuality($quality); + + $imageManipulator = $this->getManipulator(); + $imageManipulator->addVariantManipulation('test', $manipulation); + $result = $imageManipulator->createVariant('test', $media); + + $this->assertEquals($format, $result->extension); + $this->assertEquals($mime, $result->mime_type); + $this->assertEquals('image', $result->aggregate_type); + $this->assertTrue($media->fileExists()); + } + + public function getManipulator(): ImageManipulator + { + return new ImageManipulator( + new ImageManager(['driver' => 'gd']), + app(FilesystemManager::class) + ); + } +} diff --git a/tests/Integration/Jobs/ProcessImageVariantTest.php b/tests/Integration/Jobs/ProcessImageVariantTest.php new file mode 100644 index 00000000..b83a7023 --- /dev/null +++ b/tests/Integration/Jobs/ProcessImageVariantTest.php @@ -0,0 +1,25 @@ +makeMedia([]); + $variant = 'foo'; + $job = new ProcessImageVariant($variant, $model); + + $manipulator = $this->createMock(ImageManipulator::class); + $manipulator->expects($this->once()) + ->method('createVariant') + ->with($variant, $model); + app()->instance(ImageManipulator::class, $manipulator); + + $job->handle(); + } +} diff --git a/tests/Integration/MediaTest.php b/tests/Integration/MediaTest.php index 6efd5d47..056fa9ce 100644 --- a/tests/Integration/MediaTest.php +++ b/tests/Integration/MediaTest.php @@ -14,14 +14,19 @@ class MediaTest extends TestCase { public function test_it_has_path_accessors() { - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'a/b/c', - 'filename' => 'foo.bar', - 'extension' => 'jpg', - ]); - - $this->assertEquals(storage_path('tmp/a/b/c/foo.bar.jpg'), $media->getAbsolutePath()); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'a/b/c', + 'filename' => 'foo.bar', + 'extension' => 'jpg', + ] + ); + + $this->assertEquals( + storage_path('tmp/a/b/c/foo.bar.jpg'), + $media->getAbsolutePath() + ); $this->assertEquals('a/b/c/foo.bar.jpg', $media->getDiskPath()); $this->assertEquals('a/b/c', $media->directory); $this->assertEquals('foo.bar.jpg', $media->basename); @@ -71,27 +76,34 @@ public function test_it_can_be_queried_by_path_on_disk() { $this->useDatabase(); - $this->createMedia([ - 'id' => 4, - 'disk' => 'tmp', - 'directory' => 'foo/bar/baz', - 'filename' => 'bat', - 'extension' => 'jpg' - ]); - $this->assertEquals(4, Media::forPathOnDisk('tmp', 'foo/bar/baz/bat.jpg')->first()->id); + $this->createMedia( + [ + 'id' => 4, + 'disk' => 'tmp', + 'directory' => 'foo/bar/baz', + 'filename' => 'bat', + 'extension' => 'jpg' + ] + ); + $this->assertEquals( + 4, + Media::forPathOnDisk('tmp', 'foo/bar/baz/bat.jpg')->first()->id + ); } public function test_it_can_be_queried_by_path_on_disk_when_directory_is_empty() { $this->useDatabase(); - $this->createMedia([ - 'id' => 4, - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'bat', - 'extension' => 'jpg' - ]); + $this->createMedia( + [ + 'id' => 4, + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'bat', + 'extension' => 'jpg' + ] + ); $this->assertEquals(4, Media::forPathOnDisk('tmp', 'bat.jpg')->first()->id); } @@ -155,12 +167,14 @@ public function test_it_can_be_checked_for_public_visibility_s3() public function test_it_can_generate_a_url_to_the_local_file() { - $media = $this->makeMedia([ - 'disk' => 'uploads', - 'directory' => 'foo/bar', - 'filename' => 'baz', - 'extension' => 'jpg' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'uploads', + 'directory' => 'foo/bar', + 'filename' => 'baz', + 'extension' => 'jpg' + ] + ); $this->seedFileForMedia($media); $this->assertEquals('http://localhost/uploads/foo/bar/baz.jpg', $media->getUrl()); } @@ -168,12 +182,14 @@ public function test_it_can_generate_a_url_to_the_local_file() public function test_it_can_generate_a_custom_url_to_the_local_file() { $this->app['config']->set('filesystems.disks.uploads.url', 'http://example.com'); - $media = $this->makeMedia([ - 'disk' => 'uploads', - 'directory' => 'foo/bar', - 'filename' => 'baz', - 'extension' => 'jpg' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'uploads', + 'directory' => 'foo/bar', + 'filename' => 'baz', + 'extension' => 'jpg' + ] + ); $this->seedFileForMedia($media); $this->assertEquals('http://example.com/foo/bar/baz.jpg', $media->getUrl()); } @@ -183,16 +199,22 @@ public function test_it_can_generate_a_url_to_the_file_on_s3() if (!$this->s3ConfigLoaded()) { $this->markTestSkipped('S3 Credentials not available.'); } - $media = $this->makeMedia([ - 'disk' => 's3', - 'directory' => 'foo/bar', - 'filename' => 'baz', - 'extension' => 'jpg' - ]); + $media = $this->makeMedia( + [ + 'disk' => 's3', + 'directory' => 'foo/bar', + 'filename' => 'baz', + 'extension' => 'jpg' + ] + ); $this->seedFileForMedia($media); try { $this->assertEquals( - sprintf('https://%s.s3.%s.amazonaws.com/foo/bar/baz.jpg', env('S3_BUCKET'), env('S3_REGION')), + sprintf( + 'https://%s.s3.%s.amazonaws.com/foo/bar/baz.jpg', + env('S3_BUCKET'), + env('S3_REGION') + ), $media->getUrl() ); } finally { @@ -215,12 +237,14 @@ public function test_it_can_be_moved_on_disk() $this->useFilesystem('tmp'); $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media); $media->move('alpha/beta'); @@ -238,12 +262,14 @@ public function test_it_can_be_copied_on_disk() $this->useFilesystem('tmp'); $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media); // copy the file and make some checks @@ -269,18 +295,22 @@ public function test_it_throws_an_exception_if_moving_to_existing_file() { $this->useFilesystem('tmp'); - $media1 = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'foo', - 'extension' => 'baz' - ]); - $media2 = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media1 = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'foo', + 'extension' => 'baz' + ] + ); + $media2 = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media1); $this->seedFileForMedia($media2); @@ -295,12 +325,14 @@ public function test_it_can_be_moved_to_another_disk_public() $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $original_path = $media->getAbsolutePath(); $this->seedFileForMedia($media); $media->makePublic(); @@ -320,12 +352,14 @@ public function test_it_can_be_moved_to_another_disk_private() $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $original_path = $media->getAbsolutePath(); $this->seedFileForMedia($media); $media->makePrivate(); @@ -345,12 +379,14 @@ public function test_it_can_be_copied_to_another_disk_public() $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media); $media->makePublic(); @@ -374,12 +410,14 @@ public function test_it_can_be_copied_to_another_disk_private() $this->useDatabase(); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media); $media->makePrivate(); @@ -400,10 +438,12 @@ public function test_it_can_access_file_contents() { $this->useFilesystem('tmp'); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'extension' => 'html' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'extension' => 'html' + ] + ); $this->seedFileForMedia($media, '

Hello World

'); $this->assertEquals('

Hello World

', $media->contents()); } @@ -413,12 +453,14 @@ public function test_it_deletes_its_file_on_deletion() $this->useDatabase(); $this->useFilesystem('tmp'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'file', - 'extension' => 'txt' - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'file', + 'extension' => 'txt' + ] + ); $this->seedFileForMedia($media); $path = $media->getAbsolutePath(); @@ -491,8 +533,8 @@ public function test_it_retrieves_models_via_custom_mediables_table() $this->assertCount(1, $media->models(SampleMediable::class)->get()); } - public function test_it_cascades_relationships_on_soft_delete_with_config_via_custom_mediables_table() - { + public function test_it_cascades_relationships_on_soft_delete_with_config_via_custom_mediables_table( + ) { $this->useDatabase(); config()->set('mediable.mediables_table', 'prefixed_mediables'); @@ -511,12 +553,14 @@ public function test_it_can_stream_contents() { $this->useFilesystem('tmp'); - $media = $this->makeMedia([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'baz' - ]); + $media = $this->makeMedia( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'baz' + ] + ); $this->seedFileForMedia($media, 'test'); $stream = $media->stream(); diff --git a/tests/Integration/MediaUploaderTest.php b/tests/Integration/MediaUploaderTest.php index 503705b6..36d44753 100644 --- a/tests/Integration/MediaUploaderTest.php +++ b/tests/Integration/MediaUploaderTest.php @@ -32,16 +32,28 @@ public function test_it_can_be_instantiated_via_facade() public function test_it_can_set_on_duplicate_behavior_via_facade() { $uploader = Facade::onDuplicateError(); - $this->assertEquals(MediaUploader::ON_DUPLICATE_ERROR, $uploader->getOnDuplicateBehavior()); + $this->assertEquals( + MediaUploader::ON_DUPLICATE_ERROR, + $uploader->getOnDuplicateBehavior() + ); $uploader = Facade::onDuplicateIncrement(); - $this->assertEquals(MediaUploader::ON_DUPLICATE_INCREMENT, $uploader->getOnDuplicateBehavior()); + $this->assertEquals( + MediaUploader::ON_DUPLICATE_INCREMENT, + $uploader->getOnDuplicateBehavior() + ); $uploader = Facade::onDuplicateReplace(); - $this->assertEquals(MediaUploader::ON_DUPLICATE_REPLACE, $uploader->getOnDuplicateBehavior()); + $this->assertEquals( + MediaUploader::ON_DUPLICATE_REPLACE, + $uploader->getOnDuplicateBehavior() + ); $uploader = Facade::onDuplicateUpdate(); - $this->assertEquals(MediaUploader::ON_DUPLICATE_UPDATE, $uploader->getOnDuplicateBehavior()); + $this->assertEquals( + MediaUploader::ON_DUPLICATE_UPDATE, + $uploader->getOnDuplicateBehavior() + ); } public function test_it_can_determine_media_type_by_extension_and_mime() @@ -53,7 +65,11 @@ public function test_it_can_determine_media_type_by_extension_and_mime() $uploader->setTypeDefinition('bat', ['text/bat'], ['bat']); $uploader->setAllowUnrecognizedTypes(true); - $this->assertEquals('foo', $uploader->inferAggregateType('text/foo', 'foo'), 'Double match'); + $this->assertEquals( + 'foo', + $uploader->inferAggregateType('text/foo', 'foo'), + 'Double match' + ); $this->assertEquals( 'bat', $uploader->inferAggregateType('text/bat', 'foo'), @@ -82,10 +98,18 @@ public function test_it_validates_allowed_types() $uploader->setTypeDefinition('foo', ['text/foo'], ['foo']); $uploader->setTypeDefinition('bar', ['text/bar'], ['bar']); - $this->assertEquals('foo', $uploader->inferAggregateType('text/foo', 'foo'), 'No restrictions'); + $this->assertEquals( + 'foo', + $uploader->inferAggregateType('text/foo', 'foo'), + 'No restrictions' + ); $uploader->setAllowedAggregateTypes(['bar']); - $this->assertEquals('bar', $uploader->inferAggregateType('text/bar', 'bar'), 'With Restriction'); + $this->assertEquals( + 'bar', + $uploader->inferAggregateType('text/bar', 'bar'), + 'With Restriction' + ); $this->expectException(FileNotSupportedException::class); $uploader->inferAggregateType('text/foo', 'bar'); @@ -96,7 +120,10 @@ public function test_it_can_restrict_to_known_types() $uploader = $this->getUploader(); $uploader->setAllowUnrecognizedTypes(true); - $this->assertEquals(Media::TYPE_OTHER, $uploader->inferAggregateType('text/foo', 'bar')); + $this->assertEquals( + Media::TYPE_OTHER, + $uploader->inferAggregateType('text/foo', 'bar') + ); $uploader->setAllowUnrecognizedTypes(false); $this->expectException(FileNotSupportedException::class); $uploader->inferAggregateType('text/foo', 'bar'); @@ -173,10 +200,18 @@ public function test_it_validates_allowed_mime_types() $uploader = $this->getUploader(); $method = $this->getPrivateMethod($uploader, 'verifyMimeType'); - $this->assertEquals('text/foo', $method->invoke($uploader, 'text/foo'), 'No restrictions'); + $this->assertEquals( + 'text/foo', + $method->invoke($uploader, 'text/foo'), + 'No restrictions' + ); $uploader->setAllowedMimeTypes(['text/bar']); - $this->assertEquals('text/bar', $method->invoke($uploader, 'text/bar'), 'With Restriction'); + $this->assertEquals( + 'text/bar', + $method->invoke($uploader, 'text/bar'), + 'With Restriction' + ); $this->expectException(FileNotSupportedException::class); $method->invoke($uploader, 'text/foo'); @@ -215,7 +250,6 @@ public function test_it_can_disable_file_size_limits() $this->assertEquals(99999, $method->invoke($uploader, 99999)); } - public function test_it_can_error_on_duplicate_files() { $uploader = $this->getUploader(); @@ -254,12 +288,14 @@ public function test_it_can_replace_duplicate_files() $uploader = $this->getUploader()->onDuplicateReplace(); $method = $this->getPrivateMethod($uploader, 'handleDuplicate'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'plank', - 'extension' => 'png' - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'plank', + 'extension' => 'png' + ] + ); $this->seedFileForMedia($media, $this->sampleFilePath()); $method->invoke($uploader, $media); @@ -273,13 +309,15 @@ public function test_it_can_update_duplicate_files() $this->useDatabase(); $this->useFilesystem('tmp'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'plank', - 'extension' => 'png', - 'aggregate_type' => 'bar' - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'plank', + 'extension' => 'png', + 'aggregate_type' => 'bar' + ] + ); $this->seedFileForMedia($media, fopen($this->sampleFilePath(), 'r')); @@ -303,17 +341,18 @@ public function test_it_can_increment_filename_on_duplicate_files() $uploader = $this->getUploader()->onDuplicateIncrement(); $method = $this->getPrivateMethod($uploader, 'handleDuplicate'); - $media = factory(Media::class)->make([ - 'disk' => 'tmp', - 'directory' => '', - 'filename' => 'duplicate', - 'extension' => 'png' - ]); + $media = factory(Media::class)->make( + [ + 'disk' => 'tmp', + 'directory' => '', + 'filename' => 'duplicate', + 'extension' => 'png' + ] + ); $this->seedFileForMedia($media); $method->invoke($uploader, $media); - $this->assertEquals('duplicate-1', $media->filename); } @@ -425,13 +464,15 @@ public function test_it_imports_existing_files() $this->useFilesystem('tmp'); $this->useDatabase(); - $media = factory(Media::class)->make([ - 'disk' => 'tmp', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'png', - 'mime_type' => 'image/png' - ]); + $media = factory(Media::class)->make( + [ + 'disk' => 'tmp', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'png', + 'mime_type' => 'image/png' + ] + ); $this->seedFileForMedia($media, $this->sampleFile()); $media = Facade::importPath('tmp', 'foo/bar.png'); @@ -448,13 +489,15 @@ public function test_it_updates_existing_media() $this->useDatabase(); $this->useFilesystem('tmp'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'extension' => 'png', - 'mime_type' => 'video/mpeg', - 'aggregate_type' => 'video', - 'size' => 999, - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'extension' => 'png', + 'mime_type' => 'video/mpeg', + 'aggregate_type' => 'video', + 'size' => 999, + ] + ); $this->seedFileForMedia($media, $this->sampleFile()); $result = Facade::update($media); @@ -470,11 +513,13 @@ public function test_it_replaces_existing_media() $this->useDatabase(); $this->useFilesystem('tmp'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'extension' => 'png', - 'size' => 999 - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'extension' => 'png', + 'size' => 999 + ] + ); $this->seedFileForMedia($media, $this->sampleFile()); $result = Facade::fromSource($this->alternateFilePath())->replace($media); @@ -511,9 +556,11 @@ public function test_it_uploads_files_with_altered_model() $media = Facade::fromSource($this->sampleFilePath()) ->toDestination('tmp', 'foo') ->useFilename('bar') - ->beforeSave(function ($model) { - $model->id = 9876; - }) + ->beforeSave( + function ($model) { + $model->id = 9876; + } + ) ->upload(); $this->assertInstanceOf(Media::class, $media); @@ -531,12 +578,14 @@ public function test_it_uploads_files_with_altered_destination() $this->useDatabase(); $this->useFilesystem('tmp'); - $media = $this->createMedia([ - 'disk' => 'tmp', - 'directory' => 'baz', - 'filename' => 'buzz', - 'extension' => 'png', - ]); + $media = $this->createMedia( + [ + 'disk' => 'tmp', + 'directory' => 'baz', + 'filename' => 'buzz', + 'extension' => 'png', + ] + ); $this->seedFileForMedia($media, fopen($this->alternateFilePath(), 'r')); @@ -544,10 +593,12 @@ public function test_it_uploads_files_with_altered_destination() ->toDestination('tmp', 'foo') ->useFilename('bar') ->onDuplicateReplace() - ->beforeSave(function (Media $model) { - $model->directory = 'baz'; - $model->filename = 'buzz'; - }) + ->beforeSave( + function (Media $model) { + $model->directory = 'baz'; + $model->filename = 'buzz'; + } + ) ->upload(); $this->assertInstanceOf(Media::class, $media); @@ -557,7 +608,10 @@ public function test_it_uploads_files_with_altered_destination() $this->assertEquals('image/png', $media->mime_type); $this->assertEquals(self::TEST_FILE_SIZE, $media->size); $this->assertEquals('image', $media->aggregate_type); - $this->assertEquals(file_get_contents($this->sampleFilePath()), $media->contents()); + $this->assertEquals( + file_get_contents($this->sampleFilePath()), + $media->contents() + ); } protected function getUploader(): MediaUploader diff --git a/tests/Integration/MediableTest.php b/tests/Integration/MediableTest.php index 9ec99b43..b8524804 100644 --- a/tests/Integration/MediableTest.php +++ b/tests/Integration/MediableTest.php @@ -51,7 +51,11 @@ public function test_it_can_attach_one_media_to_multiple_tags() $this->assertEquals([2], $mediable->getMedia('foo')->pluck('id')->toArray()); $this->assertEquals([2], $mediable->getMedia('bar')->pluck('id')->toArray()); - $this->assertEquals(0, $mediable->getMedia('baz')->count(), 'Found media for non-existent tag'); + $this->assertEquals( + 0, + $mediable->getMedia('baz')->count(), + 'Found media for non-existent tag' + ); } public function test_it_can_attach_multiple_media_to_multiple_tags_simultaneously() @@ -102,7 +106,12 @@ public function test_it_can_find_media_matching_any_tags() $mediable->attachMedia($media2, 'bar'); $mediable->attachMedia($media3, 'baz'); - $this->assertEquals([1, 2], $mediable->getMedia(['foo', 'bar'], false)->pluck('id')->toArray()); + $this->assertEquals( + [1, 2], + $mediable->getMedia(['foo', 'bar'], false)->pluck( + 'id' + )->toArray() + ); } public function test_it_can_find_media_matching_multiple_tags() @@ -117,7 +126,12 @@ public function test_it_can_find_media_matching_multiple_tags() $mediable->attachMedia($media2, 'bar'); $mediable->attachMedia($media3, 'baz'); - $this->assertEquals([1], $mediable->getMedia(['foo', 'bar'], true)->pluck('id')->toArray()); + $this->assertEquals( + [1], + $mediable->getMedia(['foo', 'bar'], true)->pluck( + 'id' + )->toArray() + ); $this->assertEquals(0, $mediable->getMedia(['foo', 'bat'], true)->count()); } @@ -134,8 +148,14 @@ public function test_it_can_check_presence_of_attached_media() $this->assertTrue($mediable->hasMedia('foo')); $this->assertTrue($mediable->hasMedia('bar')); $this->assertFalse($mediable->hasMedia('baz')); - $this->assertTrue($mediable->hasMedia(['bar', 'baz'], false), 'Failed to find model matching one of many tag'); - $this->assertFalse($mediable->hasMedia(['bar', 'baz'], true), 'Failed to match all tags'); + $this->assertTrue( + $mediable->hasMedia(['bar', 'baz'], false), + 'Failed to find model matching one of many tag' + ); + $this->assertFalse( + $mediable->hasMedia(['bar', 'baz'], true), + 'Failed to match all tags' + ); } public function test_it_can_list_media_by_tag() @@ -187,7 +207,11 @@ public function test_it_can_sync_media_by_tag() $mediable->syncMedia($media1, 'foo'); $this->assertEquals(1, $mediable->getMedia('foo')->count()); - $this->assertEquals([3], $mediable->getMedia('bar')->pluck('id')->toArray(), 'Modified other tags'); + $this->assertEquals( + [3], + $mediable->getMedia('bar')->pluck('id')->toArray(), + 'Modified other tags' + ); } public function test_it_can_sync_media_to_multiple_tags() @@ -214,7 +238,11 @@ public function test_it_can_be_queried_by_tag() $mediable->attachMedia($media, 'foo'); $this->assertEquals(1, SampleMediable::whereHasMedia('foo', false)->count()); - $this->assertEquals(0, SampleMediable::whereHasMedia('bar', false)->count(), 'Queriable by non-existent group'); + $this->assertEquals( + 0, + SampleMediable::whereHasMedia('bar', false)->count(), + 'Queriable by non-existent group' + ); } public function test_it_can_be_queried_by_tag_matching_all() @@ -226,8 +254,18 @@ public function test_it_can_be_queried_by_tag_matching_all() $mediable->attachMedia($media1, ['foo', 'bar']); $mediable->attachMedia($media2, ['foo']); - $this->assertEquals([1], SampleMediable::whereHasMediaMatchAll(['foo', 'bar'])->get()->pluck('id')->toArray()); - $this->assertEquals([1], SampleMediable::whereHasMedia(['foo', 'bar'], true)->get()->pluck('id')->toArray()); + $this->assertEquals( + [1], + SampleMediable::whereHasMediaMatchAll(['foo', 'bar'])->get()->pluck( + 'id' + )->toArray() + ); + $this->assertEquals( + [1], + SampleMediable::whereHasMedia(['foo', 'bar'], true)->get()->pluck( + 'id' + )->toArray() + ); } public function test_it_can_list_the_tags_a_media_is_attached_to() @@ -335,7 +373,6 @@ public function test_it_uses_custom_collection() $this->assertInstanceOf(MediableCollection::class, $mediable->newCollection([])); } - public function test_it_cascades_relationship_on_delete() { $mediable = factory(SampleMediable::class)->create(); @@ -405,7 +442,13 @@ public function test_it_increments_order() [2 => 1, 3 => 2, 1 => 3], $mediable->getMedia('foo')->pluck('pivot.order', 'id')->toArray() ); - $this->assertEquals([1 => 1], $mediable->getMedia('bar')->pluck('pivot.order', 'id')->toArray()); + $this->assertEquals( + [1 => 1], + $mediable->getMedia('bar')->pluck( + 'pivot.order', + 'id' + )->toArray() + ); } public function test_it_increments_order_when_attaching_multiple() diff --git a/tests/Integration/SourceAdapters/SourceAdapterFactoryTest.php b/tests/Integration/SourceAdapters/SourceAdapterFactoryTest.php index 696099f6..8dcf00f3 100644 --- a/tests/Integration/SourceAdapters/SourceAdapterFactoryTest.php +++ b/tests/Integration/SourceAdapters/SourceAdapterFactoryTest.php @@ -68,6 +68,9 @@ public function test_it_returns_adapters_unmodified() public function test_it_is_accessible_via_the_container() { - $this->assertInstanceOf(SourceAdapterFactory::class, app('mediable.source.factory')); + $this->assertInstanceOf( + SourceAdapterFactory::class, + app('mediable.source.factory') + ); } } diff --git a/tests/Integration/SourceAdapters/SourceAdapterTest.php b/tests/Integration/SourceAdapters/SourceAdapterTest.php index 35e6005f..d9eb4787 100644 --- a/tests/Integration/SourceAdapters/SourceAdapterTest.php +++ b/tests/Integration/SourceAdapters/SourceAdapterTest.php @@ -35,6 +35,7 @@ class SourceAdapterTest extends TestCase 'c+t' => true, 'a+' => true ]; + public function setUp(): void { parent::setUp(); @@ -52,7 +53,13 @@ public function adapterProvider() $string = file_get_contents($file); $url = $this->remoteFilePath() . '?foo=bar.baz'; - $uploadedFile = new UploadedFile($file, 'plank.png', 'image/png', UPLOAD_ERR_OK, true); + $uploadedFile = new UploadedFile( + $file, + 'plank.png', + 'image/png', + UPLOAD_ERR_OK, + true + ); $fileResource = fopen($file, 'rb'); $fileStream = new Stream(fopen($file, 'rb')); @@ -69,16 +76,53 @@ public function adapterProvider() $data = [ 'FileAdapter' => [FileAdapter::class, new File($file), $file, 'plank'], - 'UploadedFileAdapter' => [UploadedFileAdapter::class, $uploadedFile, $file,'plank'], + 'UploadedFileAdapter' => [ + UploadedFileAdapter::class, + $uploadedFile, + $file, + 'plank' + ], 'LocalPathAdapter' => [LocalPathAdapter::class, $file, $file, 'plank'], 'RemoteUrlAdapter' => [RemoteUrlAdapter::class, $url, $url, 'plank'], 'RawContentAdapter' => [RawContentAdapter::class, $string, null, '', false], - 'StreamResourceAdapter_Local' => [StreamResourceAdapter::class, $fileResource, $file, 'plank'], - 'StreamAdapter_Local' => [StreamAdapter::class, $fileStream, $file, 'plank', false], - 'StreamResourceAdapter_Remote' => [StreamResourceAdapter::class, $httpResource, $url, 'plank'], - 'StreamAdapter_Remote' => [StreamAdapter::class, $httpStream, $url, 'plank', false], - 'StreamResourceAdapter_Memory' => [StreamResourceAdapter::class, $memoryResource, 'php://memory', ''], - 'StreamAdapter_Memory' => [StreamAdapter::class, $memoryStream, 'php://memory', ''], + 'StreamResourceAdapter_Local' => [ + StreamResourceAdapter::class, + $fileResource, + $file, + 'plank' + ], + 'StreamAdapter_Local' => [ + StreamAdapter::class, + $fileStream, + $file, + 'plank', + false + ], + 'StreamResourceAdapter_Remote' => [ + StreamResourceAdapter::class, + $httpResource, + $url, + 'plank' + ], + 'StreamAdapter_Remote' => [ + StreamAdapter::class, + $httpStream, + $url, + 'plank', + false + ], + 'StreamResourceAdapter_Memory' => [ + StreamResourceAdapter::class, + $memoryResource, + 'php://memory', + '' + ], + 'StreamAdapter_Memory' => [ + StreamAdapter::class, + $memoryStream, + 'php://memory', + '' + ], ]; return $data; } @@ -209,8 +253,9 @@ public function test_it_verifies_file_validity($adapterClass, $source) /** * @dataProvider invalidAdapterProvider */ - public function test_it_verifies_file_validity_failure(SourceAdapterInterface $adapter) - { + public function test_it_verifies_file_validity_failure( + SourceAdapterInterface $adapter + ) { $this->assertFalse($adapter->valid()); } } diff --git a/tests/Integration/UrlGenerators/LocalUrlGeneratorTest.php b/tests/Integration/UrlGenerators/LocalUrlGeneratorTest.php index 2fb0116f..d0cda04e 100644 --- a/tests/Integration/UrlGenerators/LocalUrlGeneratorTest.php +++ b/tests/Integration/UrlGenerators/LocalUrlGeneratorTest.php @@ -13,7 +13,10 @@ class LocalUrlGeneratorTest extends TestCase public function test_it_generates_absolute_path() { $generator = $this->setupGenerator(); - $this->assertEquals(public_path('uploads/foo/bar.jpg'), $generator->getAbsolutePath()); + $this->assertEquals( + public_path('uploads/foo/bar.jpg'), + $generator->getAbsolutePath() + ); } public function test_it_generates_url() @@ -68,26 +71,32 @@ public function test_it_checks_public_visibility_mock_disk() ); $generator = new LocalUrlGenerator(config(), $filesystem); - $media = factory(Media::class)->make([ - 'disk' => 'uploads', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'jpg' - ]); + $media = factory(Media::class)->make( + [ + 'disk' => 'uploads', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'jpg' + ] + ); $this->seedFileForMedia($media); $generator->setMedia($media); $this->assertTrue($generator->isPubliclyAccessible()); } - protected function setupGenerator($disk = 'uploads', bool $public = null): LocalUrlGenerator - { + protected function setupGenerator( + $disk = 'uploads', + bool $public = null + ): LocalUrlGenerator { /** @var Media $media */ - $media = factory(Media::class)->make([ - 'disk' => $disk, - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'jpg' - ]); + $media = factory(Media::class)->make( + [ + 'disk' => $disk, + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'jpg' + ] + ); $this->useFilesystem($disk); $this->seedFileForMedia($media); diff --git a/tests/Integration/UrlGenerators/S3UrlGeneratorTest.php b/tests/Integration/UrlGenerators/S3UrlGeneratorTest.php index 521c54e9..3580d2c8 100644 --- a/tests/Integration/UrlGenerators/S3UrlGeneratorTest.php +++ b/tests/Integration/UrlGenerators/S3UrlGeneratorTest.php @@ -30,7 +30,11 @@ public function test_it_generates_absolute_path() { $generator = $this->setupGenerator(); $this->assertEquals( - sprintf('https://%s.s3.%s.amazonaws.com/foo/bar.jpg', env('S3_BUCKET'), env('S3_REGION')), + sprintf( + 'https://%s.s3.%s.amazonaws.com/foo/bar.jpg', + env('S3_BUCKET'), + env('S3_REGION') + ), $generator->getAbsolutePath() ); } @@ -39,7 +43,11 @@ public function test_it_generates_url() { $generator = $this->setupGenerator(); $this->assertEquals( - sprintf('https://%s.s3.%s.amazonaws.com/foo/bar.jpg', env('S3_BUCKET'), env('S3_REGION')), + sprintf( + 'https://%s.s3.%s.amazonaws.com/foo/bar.jpg', + env('S3_BUCKET'), + env('S3_REGION') + ), $generator->getUrl() ); } @@ -61,11 +69,13 @@ protected function setupGenerator() private function getMedia(): Media { - return $this->makeMedia([ - 'disk' => 's3', - 'directory' => 'foo', - 'filename' => 'bar', - 'extension' => 'jpg' - ]); + return $this->makeMedia( + [ + 'disk' => 's3', + 'directory' => 'foo', + 'filename' => 'bar', + 'extension' => 'jpg' + ] + ); } } diff --git a/tests/Mocks/MockClosure.php b/tests/Mocks/MockClosure.php new file mode 100644 index 00000000..031630ad --- /dev/null +++ b/tests/Mocks/MockClosure.php @@ -0,0 +1,10 @@ +create($attributes); } + + protected function getMockCallback() + { + return $this->createPartialMock(MockClosure::class, ['__invoke']); + } }