'local', 'root' => storage_path('framework/testing/disks/fake_cdn'), 'url' => 'https://cdn.test/assets', ]); AssetStorage::flush(); } protected function tearDown(): void { AssetStorage::flush(); HookManager::resetAll(); parent::tearDown(); } #[Test] public function product_image_falls_back_to_api_url_for_local_disk_row(): void { $image = new ProductImage([ 'hash' => 'aaaabbbbcccc', 'disk' => 'modules', 'path' => 'products/P001/a.jpg', ]); $this->assertSame( '/api/modules/sirsoft-ecommerce/product-image/aaaabbbbcccc', $image->download_url ); } #[Test] public function product_image_returns_direct_url_for_cdn_disk_row(): void { $image = new ProductImage([ 'hash' => 'aaaabbbbcccc', 'disk' => 'fake_cdn', 'path' => 'products/P001/a.jpg', ]); $this->assertSame( 'https://cdn.test/assets/sirsoft-ecommerce/images/products/P001/a.jpg', $image->download_url ); } /** * @scenario consumer=category, disk_setting=public, e2e=ecommerce_settings_field, hook=supply, override=module_override, row_state=new_remote_row * * @effects download_url_falls_back_to_api_path_when_direct_unavailable */ #[Test] public function category_and_review_images_resolve_direct_url_and_fallback(): void { $cdnCategory = new CategoryImage([ 'hash' => 'ccc111222333', 'disk' => 'fake_cdn', 'path' => 'category/2026/01/01/c.jpg', ]); $localReview = new ProductReviewImage([ 'hash' => 'rrr111222333', 'disk' => 'modules', 'path' => 'reviews/1/r.jpg', ]); $this->assertSame( 'https://cdn.test/assets/sirsoft-ecommerce/images/category/2026/01/01/c.jpg', $cdnCategory->download_url ); $this->assertSame( '/api/modules/sirsoft-ecommerce/review-image/rrr111222333', $localReview->download_url ); } /** * @effects mixed_rows_resolve_per_row_disk */ #[Test] public function mixed_rows_resolve_urls_per_row_disk(): void { // 혼재 운용 — 디스크 전환 이전 로컬 행과 이후 원격 행이 각자 disk 기준으로 해석 $localRow = new ProductImage(['hash' => 'llllllllllll', 'disk' => 'modules', 'path' => 'products/P001/old.jpg']); $remoteRow = new ProductImage(['hash' => 'rrrrrrrrrrrr', 'disk' => 'fake_cdn', 'path' => 'products/P001/new.jpg']); $this->assertStringStartsWith('/api/modules/sirsoft-ecommerce/product-image/', $localRow->download_url); $this->assertStringStartsWith('https://cdn.test/assets/', $remoteRow->download_url); } /** * @scenario consumer=review, disk_setting=s3_without_url, e2e=ecommerce_settings_field, hook=unregistered, override=follow_core, row_state=new_remote_row * * @effects download_url_falls_back_to_api_path_when_direct_unavailable */ #[Test] public function blank_disk_or_path_falls_back_to_api_url(): void { $noDisk = new ProductImage(['hash' => 'aaaabbbbcccc', 'disk' => '', 'path' => 'products/P001/a.jpg']); $noPath = new ProductImage(['hash' => 'aaaabbbbcccc', 'disk' => 'fake_cdn', 'path' => '']); $this->assertSame('/api/modules/sirsoft-ecommerce/product-image/aaaabbbbcccc', $noDisk->download_url); $this->assertSame('/api/modules/sirsoft-ecommerce/product-image/aaaabbbbcccc', $noPath->download_url); } /** * @scenario consumer=category, disk_setting=none, e2e=ecommerce_settings_field, hook=block, override=follow_core, row_state=legacy_local_row * * @effects download_url_falls_back_to_api_path_when_direct_unavailable */ #[Test] public function hook_block_falls_back_to_api_url(): void { HookManager::addFilter('core.storage.filter_url', fn ($url) => ''); $image = new ProductImage([ 'hash' => 'aaaabbbbcccc', 'disk' => 'fake_cdn', 'path' => 'products/P001/a.jpg', ]); $this->assertSame( '/api/modules/sirsoft-ecommerce/product-image/aaaabbbbcccc', $image->download_url ); } }