From c0138e2b0aaca1e7d7f641e10d83f75800d62b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20=C4=8Cupi=C4=87?= Date: Tue, 17 Sep 2024 21:57:06 +0200 Subject: [PATCH] Fix unit tests --- .../NetgenRemoteMediaExtension.php | 5 -- .../Cloudinary/Resolver/SearchExpression.php | 3 +- .../NetgenRemoteMediaExtensionTest.php | 16 ++-- .../Cloudinary/CloudinaryProviderTest.php | 2 + .../Cloudinary/CloudinaryRemoteIdTest.php | 35 ++++++++ .../Cloudinary/Factory/RemoteResourceTest.php | 78 ++++++++++++++++-- .../Gateway/Cache/Psr6CachedGatewayTest.php | 3 + .../Gateway/CloudinaryApiGatewayTest.php | 3 + .../Resolver/SearchExpressionTest.php | 62 +++++++++++--- .../Cloudinary/Resolver/UploadOptionsTest.php | 80 +++++++++++++++++-- 10 files changed, 250 insertions(+), 37 deletions(-) diff --git a/bundle/DependencyInjection/NetgenRemoteMediaExtension.php b/bundle/DependencyInjection/NetgenRemoteMediaExtension.php index e7bdc4a9..0ecf75d0 100644 --- a/bundle/DependencyInjection/NetgenRemoteMediaExtension.php +++ b/bundle/DependencyInjection/NetgenRemoteMediaExtension.php @@ -4,7 +4,6 @@ namespace Netgen\Bundle\RemoteMediaBundle\DependencyInjection; -use InvalidArgumentException; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\Loader\LoaderResolver; @@ -40,10 +39,6 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - if (!isset($config['provider'])) { - throw new InvalidArgumentException('The "provider" option must be set'); - } - $container->setParameter('netgen_remote_media.remove_unused_resources', $config['remove_unused']); $container->setAlias('netgen_remote_media.provider', 'netgen_remote_media.provider.' . $config['provider']); diff --git a/lib/Core/Provider/Cloudinary/Resolver/SearchExpression.php b/lib/Core/Provider/Cloudinary/Resolver/SearchExpression.php index e35ee17d..b9eb29ae 100644 --- a/lib/Core/Provider/Cloudinary/Resolver/SearchExpression.php +++ b/lib/Core/Provider/Cloudinary/Resolver/SearchExpression.php @@ -256,9 +256,10 @@ private function resolveResourceIds(Query $query): ?string return null; } + $folderMode = $this->folderMode; $resourceIds = array_unique( array_map( - static fn ($remoteId) => CloudinaryRemoteId::fromRemoteId($remoteId, $this->folderMode)->getResourceId(), + static fn ($remoteId) => CloudinaryRemoteId::fromRemoteId($remoteId, $folderMode)->getResourceId(), $query->getRemoteIds(), ), ); diff --git a/tests/bundle/DependencyInjection/NetgenRemoteMediaExtensionTest.php b/tests/bundle/DependencyInjection/NetgenRemoteMediaExtensionTest.php index 542357a7..320c6cfe 100644 --- a/tests/bundle/DependencyInjection/NetgenRemoteMediaExtensionTest.php +++ b/tests/bundle/DependencyInjection/NetgenRemoteMediaExtensionTest.php @@ -4,10 +4,10 @@ namespace Netgen\Bundle\RemoteMediaBundle\Tests\DependencyInjection; -use InvalidArgumentException; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; use Netgen\Bundle\RemoteMediaBundle\DependencyInjection\NetgenRemoteMediaExtension; use PHPUnit\Framework\Attributes\CoversClass; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; #[CoversClass(NetgenRemoteMediaExtension::class)] final class NetgenRemoteMediaExtensionTest extends AbstractExtensionTestCase @@ -17,10 +17,10 @@ public function testItSetsValidContainerParameters(): void $this->setParameter('kernel.bundles', []); $this->load(); - $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.testprovider.account_name', 'testname'); - $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.testprovider.account_key', 'testkey'); - $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.testprovider.account_secret', 'testsecret'); - $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.testprovider.upload_prefix', 'testprefix'); + $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.cloudinary.account_name', 'testname'); + $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.cloudinary.account_key', 'testkey'); + $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.cloudinary.account_secret', 'testsecret'); + $this->assertContainerBuilderHasParameter('netgen_remote_media.parameters.cloudinary.upload_prefix', 'testprefix'); $this->assertContainerBuilderHasParameter('netgen_remote_media.remove_unused_resources', false); $this->assertContainerBuilderHasParameter('netgen_remote_media.cache.pool_name', 'cache.app'); $this->assertContainerBuilderHasParameter('netgen_remote_media.cache.ttl', 3600); @@ -46,12 +46,12 @@ public function testItSetsValidContainerParameters(): void $this->assertContainerBuilderHasAlias('netgen_remote_media.provider.cloudinary.gateway.inner', 'netgen_remote_media.provider.cloudinary.gateway.api'); $this->assertContainerBuilderHasAlias('netgen_remote_media.provider.cloudinary.gateway', 'netgen_remote_media.provider.cloudinary.gateway.cached'); - $this->assertContainerBuilderHasAlias('netgen_remote_media.provider', 'netgen_remote_media.provider.testprovider'); + $this->assertContainerBuilderHasAlias('netgen_remote_media.provider', 'netgen_remote_media.provider.cloudinary'); } public function testWithoutProviderParameter(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(InvalidConfigurationException::class); $this->load(['provider' => null]); } @@ -102,7 +102,7 @@ protected function getContainerExtensions(): array protected function getMinimalConfiguration(): array { return [ - 'provider' => 'testprovider', + 'provider' => 'cloudinary', 'account_name' => 'testname', 'account_key' => 'testkey', 'account_secret' => 'testsecret', diff --git a/tests/lib/Core/Provider/Cloudinary/CloudinaryProviderTest.php b/tests/lib/Core/Provider/Cloudinary/CloudinaryProviderTest.php index 2d6e3221..d363032f 100644 --- a/tests/lib/Core/Provider/Cloudinary/CloudinaryProviderTest.php +++ b/tests/lib/Core/Provider/Cloudinary/CloudinaryProviderTest.php @@ -76,11 +76,13 @@ protected function setUp(): void new DateTimeFactory(), new UploadOptionsResolver( new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_FIXED, ['image', 'video'], $this->mimeTypes, ), [], [], + CloudinaryProvider::FOLDER_MODE_FIXED, $this->logger, false, ); diff --git a/tests/lib/Core/Provider/Cloudinary/CloudinaryRemoteIdTest.php b/tests/lib/Core/Provider/Cloudinary/CloudinaryRemoteIdTest.php index c75e7984..414fe260 100644 --- a/tests/lib/Core/Provider/Cloudinary/CloudinaryRemoteIdTest.php +++ b/tests/lib/Core/Provider/Cloudinary/CloudinaryRemoteIdTest.php @@ -5,8 +5,10 @@ namespace Netgen\RemoteMedia\Tests\Core\Provider\Cloudinary; use Netgen\RemoteMedia\API\Values\Folder; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryRemoteId; use Netgen\RemoteMedia\Exception\Cloudinary\InvalidRemoteIdException; +use Netgen\RemoteMedia\Exception\NotSupportedException; use Netgen\RemoteMedia\Tests\AbstractTestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -78,6 +80,39 @@ public function testFromRemoteId(): void ); } + public function testFromRemoteIdInDynamicFolderMode(): void + { + $remoteId = CloudinaryRemoteId::fromRemoteId( + 'private|video|media/videos/my_test_video.mp4', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, + ); + + self::assertSame( + 'private|video|media/videos/my_test_video.mp4', + $remoteId->getRemoteId(), + ); + + self::assertSame( + 'media/videos/my_test_video.mp4', + $remoteId->getResourceId(), + ); + + self::assertSame( + 'video', + $remoteId->getResourceType(), + ); + + self::assertSame( + 'private', + $remoteId->getType(), + ); + + self::expectException(NotSupportedException::class); + self::expectExceptionMessage('Provider "Cloudinary" does not support "fetching folder from path in "dynamic" folder mode".'); + + $remoteId->getFolder(); + } + public function testFromInvalidRemoteId(): void { self::expectException(InvalidRemoteIdException::class); diff --git a/tests/lib/Core/Provider/Cloudinary/Factory/RemoteResourceTest.php b/tests/lib/Core/Provider/Cloudinary/Factory/RemoteResourceTest.php index e84ee236..b3bf3607 100644 --- a/tests/lib/Core/Provider/Cloudinary/Factory/RemoteResourceTest.php +++ b/tests/lib/Core/Provider/Cloudinary/Factory/RemoteResourceTest.php @@ -7,6 +7,7 @@ use Netgen\RemoteMedia\API\Factory\FileHash as FileHashFactoryInterface; use Netgen\RemoteMedia\API\Values\Folder; use Netgen\RemoteMedia\API\Values\RemoteResource; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\ResourceType as ResourceTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\VisibilityType as VisibilityTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory\CloudinaryConfiguration; @@ -20,7 +21,9 @@ #[CoversClass(RemoteResourceFactory::class)] final class RemoteResourceTest extends AbstractTestCase { - protected RemoteResourceFactory $remoteResourceFactory; + protected RemoteResourceFactory $fixedFolderModeRemoteResourceFactory; + + protected RemoteResourceFactory $dynamicFolderModeRemoteResourceFactory; protected FileHashFactoryInterface|MockObject $fileHashFactoryMock; @@ -38,15 +41,23 @@ protected function setUp(): void $cloudinaryConfigurationFactory->create(); - $this->remoteResourceFactory = new RemoteResourceFactory( + $this->fixedFolderModeRemoteResourceFactory = new RemoteResourceFactory( + new ResourceTypeConverter(), + new VisibilityTypeConverter(), + $this->fileHashFactoryMock, + CloudinaryProvider::FOLDER_MODE_FIXED, + ); + + $this->dynamicFolderModeRemoteResourceFactory = new RemoteResourceFactory( new ResourceTypeConverter(), new VisibilityTypeConverter(), $this->fileHashFactoryMock, + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ); } #[DataProvider('createDataProvider')] - public function testCreate(array $cloudinaryResponse, RemoteResource $expectedResource): void + public function testCreate(array $cloudinaryResponse, RemoteResource $expectedResource, string $folderMode = CloudinaryProvider::FOLDER_MODE_FIXED): void { if (!($cloudinaryResponse['etag'] ?? null)) { $this->fileHashFactoryMock @@ -56,7 +67,9 @@ public function testCreate(array $cloudinaryResponse, RemoteResource $expectedRe ->willReturn('a522f23sf81aa0afd03387c37e2b6eax'); } - $resource = $this->remoteResourceFactory->create($cloudinaryResponse); + $resource = $folderMode === CloudinaryProvider::FOLDER_MODE_FIXED + ? $this->fixedFolderModeRemoteResourceFactory->create($cloudinaryResponse) + : $this->dynamicFolderModeRemoteResourceFactory->create($cloudinaryResponse); self::assertRemoteResourceSame( $expectedResource, @@ -69,7 +82,7 @@ public function testCreateMissingPublicId(): void self::expectException(InvalidDataException::class); self::expectExceptionMessage('Missing required "public_id" property!'); - $this->remoteResourceFactory->create(['test' => 'test']); + $this->fixedFolderModeRemoteResourceFactory->create(['test' => 'test']); } public function testCreateMissingUrls(): void @@ -77,7 +90,7 @@ public function testCreateMissingUrls(): void self::expectException(InvalidDataException::class); self::expectExceptionMessage('Missing required "secure_url" or "url" property!'); - $this->remoteResourceFactory->create(['public_id' => 'test']); + $this->dynamicFolderModeRemoteResourceFactory->create(['public_id' => 'test']); } public static function createDataProvider(): array @@ -139,6 +152,7 @@ public static function createDataProvider(): array 'source' => 'user_upload', ], ), + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ [ @@ -177,6 +191,7 @@ public static function createDataProvider(): array 'created_at' => '2013-06-23T13:59:18Z', ], ), + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ [ @@ -223,6 +238,7 @@ public static function createDataProvider(): array 'overwritten' => 'false', ], ), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ [ @@ -245,6 +261,7 @@ public static function createDataProvider(): array 'variation1', 'variation2', ], + 'asset_folder' => 'media/test', ], new RemoteResource( remoteId: 'authenticated|video|c87hg9xfxrd4itiim3t0', @@ -255,6 +272,7 @@ public static function createDataProvider(): array originalFilename: 'c87hg9xfxrd4itiim3t0.mp4', version: '1371995958', visibility: 'protected', + folder: Folder::fromPath('media/test'), size: 120253, tags: ['tag1', 'tag2'], metadata: [ @@ -266,6 +284,7 @@ public static function createDataProvider(): array 'overwritten' => 'false', ], ), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ [ @@ -309,6 +328,7 @@ public static function createDataProvider(): array 'test' => 'test', ], ), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ [ @@ -352,6 +372,52 @@ public static function createDataProvider(): array 'test2' => 'test2', ], ), + CloudinaryProvider::FOLDER_MODE_FIXED, + ], + [ + [ + 'public_id' => 'c87hg9xfxrd4itiim3t0', + 'version' => 1371995958, + 'signature' => 'f8645b000be7d717599affc89a068157e4748276', + 'format' => 'zip', + 'resource_type' => 'raw', + 'created_at' => '2011-06-23T13:59:18Z', + 'bytes' => 12025, + 'type' => 'test', + 'secure_url' => 'https://res.cloudinary.com/testcloud/v1371995958/raw/media/raw/new/c87hg9xfxrd4itiim3t0', + 'etag' => 'e522f43cf89aa0afd03387c38e2b6e29', + 'context' => [ + 'test' => 'test', + 'custom' => [ + 'test2' => 'test2', + ], + 'original_filename' => 'test.mp4', + ], + 'asset_folder' => 'media/raw/new', + ], + new RemoteResource( + remoteId: 'test|raw|c87hg9xfxrd4itiim3t0', + type: 'other', + url: 'https://res.cloudinary.com/testcloud/raw/test/c87hg9xfxrd4itiim3t0', + md5: 'e522f43cf89aa0afd03387c38e2b6e29', + name: 'c87hg9xfxrd4itiim3t0', + originalFilename: 'test.mp4', + version: '1371995958', + visibility: 'public', + folder: Folder::fromPath('media/raw/new'), + size: 12025, + tags: [], + metadata: [ + 'signature' => 'f8645b000be7d717599affc89a068157e4748276', + 'format' => 'zip', + 'created_at' => '2011-06-23T13:59:18Z', + ], + context: [ + 'test' => 'test', + 'test2' => 'test2', + ], + ), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], ]; } diff --git a/tests/lib/Core/Provider/Cloudinary/Gateway/Cache/Psr6CachedGatewayTest.php b/tests/lib/Core/Provider/Cloudinary/Gateway/Cache/Psr6CachedGatewayTest.php index d4b58ba4..7ebc099e 100644 --- a/tests/lib/Core/Provider/Cloudinary/Gateway/Cache/Psr6CachedGatewayTest.php +++ b/tests/lib/Core/Provider/Cloudinary/Gateway/Cache/Psr6CachedGatewayTest.php @@ -10,6 +10,7 @@ use Netgen\RemoteMedia\API\Values\AuthToken; use Netgen\RemoteMedia\API\Values\RemoteResource; use Netgen\RemoteMedia\API\Values\StatusData; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryRemoteId; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Gateway\Cache\Psr6CachedGateway; use Netgen\RemoteMedia\Core\Provider\Cloudinary\GatewayInterface; @@ -51,12 +52,14 @@ protected function setUp(): void $this->taggableCachedGateway = new Psr6CachedGateway( $this->apiGatewayMock, $this->taggableCache, + CloudinaryProvider::FOLDER_MODE_FIXED, self::CACHE_TTL, ); $this->nonTaggableCachedGateway = new Psr6CachedGateway( $this->apiGatewayMock, $this->nonTaggableCache, + CloudinaryProvider::FOLDER_MODE_DYNAMIC, self::CACHE_TTL, ); } diff --git a/tests/lib/Core/Provider/Cloudinary/Gateway/CloudinaryApiGatewayTest.php b/tests/lib/Core/Provider/Cloudinary/Gateway/CloudinaryApiGatewayTest.php index 80359447..085e0195 100644 --- a/tests/lib/Core/Provider/Cloudinary/Gateway/CloudinaryApiGatewayTest.php +++ b/tests/lib/Core/Provider/Cloudinary/Gateway/CloudinaryApiGatewayTest.php @@ -18,6 +18,7 @@ use Netgen\RemoteMedia\API\Values\AuthToken; use Netgen\RemoteMedia\API\Values\RemoteResource; use Netgen\RemoteMedia\API\Values\StatusData; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryRemoteId; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\ResourceType as ResourceTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\VisibilityType as VisibilityTypeConverter; @@ -61,6 +62,7 @@ protected function setUp(): void new SearchExpressionResolver( new ResourceTypeConverter(), new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_FIXED, ), new AuthTokenResolver(CloudinaryConfigurationInitializer::ENCRYPTION_KEY), ); @@ -239,6 +241,7 @@ public function testIsEncryptionEnabled(): void new SearchExpressionResolver( new ResourceTypeConverter(), new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_FIXED, ), new AuthTokenResolver(), ); diff --git a/tests/lib/Core/Provider/Cloudinary/Resolver/SearchExpressionTest.php b/tests/lib/Core/Provider/Cloudinary/Resolver/SearchExpressionTest.php index 57afdea8..35f3b2c4 100644 --- a/tests/lib/Core/Provider/Cloudinary/Resolver/SearchExpressionTest.php +++ b/tests/lib/Core/Provider/Cloudinary/Resolver/SearchExpressionTest.php @@ -5,6 +5,8 @@ namespace Netgen\RemoteMedia\Tests\Core\Provider\Cloudinary\Resolver; use Netgen\RemoteMedia\API\Search\Query; +use Netgen\RemoteMedia\API\Values\Folder; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\ResourceType as ResourceTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\VisibilityType as VisibilityTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Resolver\SearchExpression as SearchExpressionResolver; @@ -15,22 +17,35 @@ #[CoversClass(SearchExpressionResolver::class)] final class SearchExpressionTest extends TestCase { - protected SearchExpressionResolver $resolver; + protected SearchExpressionResolver $fixedFolderModeResolver; + + protected SearchExpressionResolver $dynamicFolderModeResolver; protected function setUp(): void { - $this->resolver = new SearchExpressionResolver( + $this->fixedFolderModeResolver = new SearchExpressionResolver( + new ResourceTypeConverter(), + new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_FIXED, + ); + + $this->dynamicFolderModeResolver = new SearchExpressionResolver( new ResourceTypeConverter(), new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ); } #[DataProvider('dataProvider')] - public function testResolve(Query $query, string $expression): void + public function testResolve(Query $query, string $expression, string $folderMode = CloudinaryProvider::FOLDER_MODE_FIXED): void { + $actualExpression = $folderMode === CloudinaryProvider::FOLDER_MODE_FIXED + ? $this->fixedFolderModeResolver->resolve($query) + : $this->dynamicFolderModeResolver->resolve($query); + self::assertSame( $expression, - $this->resolver->resolve($query), + $actualExpression, ); } @@ -40,45 +55,62 @@ public static function dataProvider(): array [ new Query(), '', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(query: 'search term'), 'search term*', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ - new Query(folders: ['root/images/1']), - '(folder:"root/images/1")', + new Query(folders: [Folder::fromPath('root/images/1')]), + '(asset_folder:"root/images/1")', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query( - folders: ['root/images/1', 'root/videos/2'], + folders: [Folder::fromPath('root/images/1'), Folder::fromPath('root/videos/2')], context: ['type' => ['product_image', 'category_image'], 'source' => 'user_upload'], ), '(folder:"root/images/1" OR folder:"root/videos/2") AND ((context.type="product_image" OR context.type="category_image") AND (context.source="user_upload"))', + CloudinaryProvider::FOLDER_MODE_FIXED, + ], + [ + new Query( + folders: [Folder::fromPath('root/images/1'), Folder::fromPath('root/videos/2')], + context: ['type' => ['product_image', 'category_image'], 'source' => 'user_upload'], + ), + '(asset_folder:"root/images/1" OR asset_folder:"root/videos/2") AND ((context.type="product_image" OR context.type="category_image") AND (context.source="user_upload"))', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query(remoteIds: ['upload|image|root/test/picture1', 'upload|image|root/test/picture2', 'upload|image|root/test/picture3']), '(public_id:"root/test/picture1" OR public_id:"root/test/picture2" OR public_id:"root/test/picture3")', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query(md5s: ['hash1', 'hash2']), '(etag="hash1" OR etag="hash2")', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(types: ['video']), '(resource_type:"video")' . ' AND (((!format="aac") AND (!format="aiff") AND (!format="amr") AND (!format="flac")' . ' AND (!format="m4a") AND (!format="mp3") AND (!format="ogg") AND (!format="opus") AND (!format="wav")))', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(types: ['document']), '(resource_type:"image" OR resource_type:"raw")' . ' AND ((format="pdf" OR format="doc" OR format="docx" OR format="ppt" OR format="pptx" OR format="txt"))', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(types: ['document', 'raw']), '(resource_type:"image" OR resource_type:"raw")' . ' AND ((format="pdf" OR format="doc" OR format="docx" OR format="ppt" OR format="pptx" OR format="txt"))', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query( @@ -90,28 +122,33 @@ public static function dataProvider(): array . ' AND (!format="mp3") AND (!format="ogg") AND (!format="opus") AND (!format="wav") AND (!format="pdf")' . ' AND (!format="doc") AND (!format="docx") AND (!format="ppt") AND (!format="pptx") AND (!format="txt")))' . ' AND ((context.source="user_upload"))', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query(visibilities: ['public']), '(type:"upload")', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(visibilities: ['protected']), '(type:"authenticated")', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query(tags: ['tech']), '(tags:"tech")', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query(tags: ['tech', 'nature']), '(tags:"tech" OR tags:"nature")', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query( query: 'android', types: ['video'], - folders: ['root/videos'], + folders: [Folder::fromPath('root/videos')], visibilities: ['public'], tags: ['tech'], ), @@ -122,26 +159,28 @@ public static function dataProvider(): array . ' AND (folder:"root/videos")' . ' AND (type:"upload")' . ' AND (tags:"tech")', + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new Query( query: 'podcast', types: ['audio'], - folders: ['root/audio'], + folders: [Folder::fromPath('root/audio')], visibilities: ['protected'], ), '(resource_type:"video")' . ' AND ((format="aac" OR format="aiff" OR format="amr" OR format="flac" OR format="m4a"' . ' OR format="mp3" OR format="ogg" OR format="opus" OR format="wav"))' . ' AND podcast*' - . ' AND (folder:"root/audio")' + . ' AND (asset_folder:"root/audio")' . ' AND (type:"authenticated")', + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new Query( query: 'search term', types: ['image', 'video', 'document', 'audio'], - folders: ['root', 'root/test'], + folders: [Folder::fromPath('root'), Folder::fromPath('root/test')], tags: ['tech', 'nature'], remoteIds: ['upload|image|root/test/picture1', 'upload|image|root/test/picture2', 'upload|image|root/test/picture3'], md5s: ['hash1', 'hash2'], @@ -157,6 +196,7 @@ public static function dataProvider(): array . ' AND (public_id:"root/test/picture1" OR public_id:"root/test/picture2" OR public_id:"root/test/picture3")' . ' AND (etag="hash1" OR etag="hash2")' . ' AND ((context.original_filename="picture_*") AND (context.type="product_image" OR context.type="category_image"))', + CloudinaryProvider::FOLDER_MODE_FIXED, ], ]; } diff --git a/tests/lib/Core/Provider/Cloudinary/Resolver/UploadOptionsTest.php b/tests/lib/Core/Provider/Cloudinary/Resolver/UploadOptionsTest.php index d075d82e..1ec96f6a 100644 --- a/tests/lib/Core/Provider/Cloudinary/Resolver/UploadOptionsTest.php +++ b/tests/lib/Core/Provider/Cloudinary/Resolver/UploadOptionsTest.php @@ -7,6 +7,7 @@ use Netgen\RemoteMedia\API\Upload\FileStruct; use Netgen\RemoteMedia\API\Upload\ResourceStruct; use Netgen\RemoteMedia\API\Values\Folder; +use Netgen\RemoteMedia\Core\Provider\Cloudinary\CloudinaryProvider; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\VisibilityType as VisibilityTypeConverter; use Netgen\RemoteMedia\Core\Provider\Cloudinary\Resolver\UploadOptions as UploadOptionsResolver; use PHPUnit\Framework\Attributes\CoversClass; @@ -18,7 +19,9 @@ #[CoversClass(UploadOptionsResolver::class)] final class UploadOptionsTest extends TestCase { - protected UploadOptionsResolver $resolver; + protected UploadOptionsResolver $fixedFolderModeResolver; + + protected UploadOptionsResolver $dynamicFolderModeResolver; protected MockObject $mimeTypes; @@ -26,16 +29,29 @@ protected function setUp(): void { $this->mimeTypes = $this->createMock(MimeTypesInterface::class); - $this->resolver = new UploadOptionsResolver( + $this->fixedFolderModeResolver = new UploadOptionsResolver( + new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_FIXED, + ['image', 'video'], + $this->mimeTypes, + ); + + $this->dynamicFolderModeResolver = new UploadOptionsResolver( new VisibilityTypeConverter(), + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ['image', 'video'], $this->mimeTypes, ); } #[DataProvider('dataProvider')] - public function testResolve(ResourceStruct $resourceStruct, string $mimeType, array $options, bool $hasExtension = true): void - { + public function testResolve( + ResourceStruct $resourceStruct, + string $mimeType, + array $options, + string $folderMode = CloudinaryProvider::FOLDER_MODE_FIXED, + bool $hasExtension = true, + ): void { if ($hasExtension) { $this->mimeTypes ->expects(self::once()) @@ -44,7 +60,9 @@ public function testResolve(ResourceStruct $resourceStruct, string $mimeType, ar ->willReturn($mimeType); } - $resolvedOptions = $this->resolver->resolve($resourceStruct); + $resolvedOptions = $folderMode === CloudinaryProvider::FOLDER_MODE_FIXED + ? $this->fixedFolderModeResolver->resolve($resourceStruct) + : $this->dynamicFolderModeResolver->resolve($resourceStruct); self::assertSame($options, $resolvedOptions); } @@ -73,6 +91,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'anonymous']], 'tags' => [], ], + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new ResourceStruct( @@ -95,6 +114,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'anonymous']], 'tags' => [], ], + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new ResourceStruct( @@ -134,6 +154,48 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'token']], 'tags' => ['backup'], ], + CloudinaryProvider::FOLDER_MODE_FIXED, + ], + [ + new ResourceStruct( + FileStruct::fromPath('/var/storage/backup.zip'), + 'raw', + Folder::fromPath('files/backups'), + 'protected', + 'latest_backup.zip', + false, + false, + null, + null, + ['backup'], + [ + 'alt' => 'test', + 'original_filename' => 'something.jpg', + 'type' => 'product_image', + 'test' => 'test_value', + ], + ), + 'application/zip', + [ + 'public_id' => 'latest_backup_zip.zip', + 'overwrite' => false, + 'invalidate' => false, + 'discard_original_filename' => true, + 'context' => [ + 'alt' => '', + 'caption' => '', + 'original_filename' => 'latest_backup.zip', + 'type' => 'product_image', + 'test' => 'test_value', + ], + 'type' => 'authenticated', + 'resource_type' => 'raw', + 'access_mode' => 'authenticated', + 'access_control' => [['access_type' => 'token']], + 'tags' => ['backup'], + 'folder' => 'files/backups', + ], + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new ResourceStruct( @@ -166,6 +228,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'token']], 'tags' => ['backup', 'archive'], ], + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new ResourceStruct( @@ -187,6 +250,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'anonymous']], 'tags' => [], ], + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new ResourceStruct( @@ -217,6 +281,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'anonymous']], 'tags' => [], ], + CloudinaryProvider::FOLDER_MODE_FIXED, ], [ new ResourceStruct( @@ -230,7 +295,7 @@ public static function dataProvider(): array ), 'video/mp4', [ - 'public_id' => 'videos/my_video', + 'public_id' => 'my_video', 'overwrite' => true, 'invalidate' => true, 'discard_original_filename' => true, @@ -244,7 +309,9 @@ public static function dataProvider(): array 'access_mode' => 'authenticated', 'access_control' => [['access_type' => 'token']], 'tags' => [], + 'folder' => 'videos', ], + CloudinaryProvider::FOLDER_MODE_DYNAMIC, ], [ new ResourceStruct( @@ -269,6 +336,7 @@ public static function dataProvider(): array 'access_control' => [['access_type' => 'anonymous']], 'tags' => [], ], + CloudinaryProvider::FOLDER_MODE_FIXED, false, ], ];