@@ -137,16 +137,107 @@ def test_generates_optimization_results_for_large_images(
137137 assert any ("large_unoptimized.png" in path for path in optimizable_paths )
138138 assert any ("large_photo.jpg" in path for path in optimizable_paths )
139139
140- def test_excludes_app_icons_and_sticker_packs (
140+ def test_excludes_loose_app_icons_and_sticker_packs (
141141 self , insight : ImageOptimizationInsight , insights_input : InsightsInput
142142 ) -> None :
143- """Test that App Icons and sticker pack images are excluded from optimization."""
143+ """Test that loose AppIcon files and sticker pack images are excluded from optimization."""
144144 result = insight .generate (insights_input )
145145 assert result is not None
146146 optimizable_paths = {f .file_path for f in result .optimizable_files }
147+ # Loose AppIcon files should be excluded
147148 assert not any ("AppIcon" in path for path in optimizable_paths )
148149 assert not any ("stickerpack" in path for path in optimizable_paths )
149150
151+ def test_includes_appicon_display_variants_from_asset_catalogs (
152+ self , insight : ImageOptimizationInsight , temp_images : Dict [str , Any ]
153+ ) -> None :
154+ """Test that AppIcon display variants inside asset catalogs ARE included."""
155+ # Create an asset catalog with an AppIcon display variant
156+ car_path = temp_images ["temp_dir" ] / "Assets.car"
157+
158+ # Create an alternate icon display variant (should be included)
159+ alternate_icon_display = temp_images ["temp_dir" ] / "AppIconFuzz_display.png"
160+ icon_img = Image .new ("RGB" , (1024 , 1024 ), (255 , 0 , 0 ))
161+ icon_img .save (alternate_icon_display , format = "PNG" , optimize = False , compress_level = 0 )
162+
163+ # Create an actual alternate icon (should be excluded)
164+ actual_icon = temp_images ["temp_dir" ] / "AppIconFuzz.png"
165+ actual_icon_img = Image .new ("RGB" , (1024 , 1024 ), (0 , 255 , 0 ))
166+ actual_icon_img .save (actual_icon , format = "PNG" , optimize = False , compress_level = 0 )
167+
168+ # Create a mock asset catalog file entry
169+ car_file_info = FileInfo (
170+ path = "Assets.car" ,
171+ full_path = car_path ,
172+ size = 1024 ,
173+ file_type = "car" ,
174+ hash = "test_hash" ,
175+ treemap_type = TreemapType .ASSETS ,
176+ is_dir = False ,
177+ children = [
178+ FileInfo (
179+ path = "Assets.car/AppIconFuzz_display/AppIconFuzz_display.png" ,
180+ full_path = alternate_icon_display ,
181+ size = alternate_icon_display .stat ().st_size ,
182+ file_type = "png" ,
183+ hash = calculate_file_hash (alternate_icon_display ),
184+ treemap_type = TreemapType .ASSETS ,
185+ is_dir = False ,
186+ children = [],
187+ ),
188+ FileInfo (
189+ path = "Assets.car/AppIconFuzz/AppIconFuzz.png" ,
190+ full_path = actual_icon ,
191+ size = actual_icon .stat ().st_size ,
192+ file_type = "png" ,
193+ hash = calculate_file_hash (actual_icon ),
194+ treemap_type = TreemapType .ASSETS ,
195+ is_dir = False ,
196+ children = [],
197+ ),
198+ ],
199+ )
200+
201+ file_analysis = FileAnalysis (files = [car_file_info ], directories = [])
202+
203+ test_input = InsightsInput (
204+ app_info = AppleAppInfo (
205+ name = "TestApp" ,
206+ app_id = "com.test.app" ,
207+ version = "1.0" ,
208+ build = "1" ,
209+ executable = "TestApp" ,
210+ minimum_os_version = "15.0" ,
211+ supported_platforms = ["iphoneos" ],
212+ sdk_version = None ,
213+ is_simulator = False ,
214+ codesigning_type = None ,
215+ profile_name = None ,
216+ profile_expiration_date = None ,
217+ certificate_expiration_date = None ,
218+ main_binary_uuid = None ,
219+ is_code_signature_valid = True ,
220+ code_signature_errors = [],
221+ primary_icon_name = None ,
222+ alternate_icon_names = ["AppIconFuzz" ], # This is the actual icon
223+ ),
224+ file_analysis = file_analysis ,
225+ binary_analysis = [],
226+ treemap = None ,
227+ hermes_reports = {},
228+ )
229+
230+ result = insight .generate (test_input )
231+ assert result is not None
232+ assert len (result .optimizable_files ) > 0
233+
234+ # The display variant should be included, but not the actual icon
235+ optimizable_paths = {f .file_path for f in result .optimizable_files }
236+ assert any ("AppIconFuzz_display" in path for path in optimizable_paths ), "Display variant should be included"
237+ assert not any (path .endswith ("AppIconFuzz/AppIconFuzz.png" ) for path in optimizable_paths ), (
238+ "Actual icon should be excluded"
239+ )
240+
150241 def test_respects_minimum_savings_threshold (
151242 self , insight : ImageOptimizationInsight , insights_input : InsightsInput
152243 ) -> None :
0 commit comments