1- #!/usr/bin/env python3
2-
3- # This file is part of python-libzim
4- # (see https://github.com/libzim/python-libzim)
5- #
6- # Copyright (c) 2025 Benoit Arnaud <[email protected] > 7- #
8- # This program is free software: you can redistribute it and/or modify
9- # it under the terms of the GNU General Public License as published by
10- # the Free Software Foundation, either version 3 of the License, or
11- # (at your option) any later version.
12- #
13- # This program is distributed in the hope that it will be useful,
14- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16- # GNU General Public License for more details.
17- #
18- # You should have received a copy of the GNU General Public License
19- # along with this program. If not, see <http://www.gnu.org/licenses/>.
20-
211import pytest
222
233from libzim .illustration import ( # pyright: ignore [reportMissingModuleSource]
288
299
3010@pytest .fixture (scope = "function" )
31- def zim_with_varied_illustrations (tmp_path , favicon_data ):
11+ def zim_with_varied_illustrations (
12+ tmp_path ,
13+ favicon_data_48 ,
14+ favicon_data_96 ,
15+ favicon_data_144 ,
16+ favicon_data_192 ,
17+ favicon_data_128_64 ,
18+ favicon_data_64_128 ,
19+ favicon_data_256 ,
20+ ):
3221 """Create a ZIM file with various illustration sizes and scales."""
3322 fpath = tmp_path / "test_illustrations.zim"
3423 with Creator (fpath ) as c :
3524 c .add_metadata ("Title" , "Test ZIM" )
3625
3726 # Add multiple illustrations with different dimensions and scales
3827 # 48x48 at different scales
39- c .add_illustration (IllustrationInfo (48 , 48 , 1.0 ), favicon_data )
40- c .add_illustration (IllustrationInfo (48 , 48 , 2.0 ), favicon_data )
41- c .add_illustration (IllustrationInfo (48 , 48 , 3.0 ), favicon_data )
28+ c .add_illustration (IllustrationInfo (48 , 48 , 1.0 ), favicon_data_48 ) # 48x48 PNG
29+ c .add_illustration (
30+ IllustrationInfo (48 , 48 , 2.0 ), favicon_data_96
31+ ) # 96x96 PNG (48*2)
32+ c .add_illustration (
33+ IllustrationInfo (48 , 48 , 3.0 ), favicon_data_144
34+ ) # 144x144 PNG (48*3)
4235
4336 # 96x96 at different scales
44- c .add_illustration (IllustrationInfo (96 , 96 , 1.0 ), favicon_data )
45- c .add_illustration (IllustrationInfo (96 , 96 , 2.0 ), favicon_data )
37+ c .add_illustration (IllustrationInfo (96 , 96 , 1.0 ), favicon_data_96 ) # 96x96 PNG
38+ c .add_illustration (
39+ IllustrationInfo (96 , 96 , 2.0 ), favicon_data_192
40+ ) # 192x192 PNG (96*2)
4641
4742 # Non-square illustrations
48- c .add_illustration (IllustrationInfo (128 , 64 , 1.0 ), favicon_data )
49- c .add_illustration (IllustrationInfo (64 , 128 , 1.0 ), favicon_data )
43+ c .add_illustration (IllustrationInfo (128 , 64 , 1.0 ), favicon_data_128_64 )
44+ c .add_illustration (IllustrationInfo (64 , 128 , 1.0 ), favicon_data_64_128 )
5045
5146 # Large illustration
52- c .add_illustration (IllustrationInfo (256 , 256 , 1.0 ), favicon_data )
47+ c .add_illustration (IllustrationInfo (256 , 256 , 1.0 ), favicon_data_256 )
5348
5449 return fpath
5550
@@ -169,29 +164,51 @@ class TestArchiveGetIllustrationItem:
169164 """Test Archive.get_illustration_item() with IllustrationInfo."""
170165
171166 def test_get_illustration_item_with_info (
172- self , zim_with_varied_illustrations , favicon_data
167+ self ,
168+ zim_with_varied_illustrations ,
169+ favicon_data_48 ,
170+ favicon_data_96 ,
171+ favicon_data_144 ,
172+ favicon_data_192 ,
173+ favicon_data_128_64 ,
174+ favicon_data_64_128 ,
175+ favicon_data_256 ,
173176 ):
174177 """Test getting illustration item using IllustrationInfo."""
175178 zim = Archive (zim_with_varied_illustrations )
176179 infos = zim .get_illustration_infos ()
177180
181+ # Map (width, height, scale) to expected PNG data
182+ # Physical pixels = CSS pixels * scale
183+ expected_data = {
184+ (48 , 48 , 1.0 ): favicon_data_48 , # 48x48 PNG
185+ (48 , 48 , 2.0 ): favicon_data_96 , # 96x96 PNG (48*2)
186+ (48 , 48 , 3.0 ): favicon_data_144 , # 144x144 PNG (48*3)
187+ (96 , 96 , 1.0 ): favicon_data_96 , # 96x96 PNG
188+ (96 , 96 , 2.0 ): favicon_data_192 , # 192x192 PNG (96*2)
189+ (128 , 64 , 1.0 ): favicon_data_128_64 , # 128x64 PNG
190+ (64 , 128 , 1.0 ): favicon_data_64_128 , # 64x128 PNG
191+ (256 , 256 , 1.0 ): favicon_data_256 , # 256x256 PNG
192+ }
193+
178194 # Get item for each illustration
179195 for info in infos :
180- item = zim .get_illustration_item (info = info )
181- assert bytes (item .content ) == favicon_data
196+ item = zim .get_illustration_item (info )
197+ expected = expected_data [(info .width , info .height , info .scale )]
198+ assert bytes (item .content ) == expected
182199 # Verify path contains the illustration metadata name
183200 assert "Illustration" in item .path
184201
185202 def test_get_illustration_item_specific_scale (
186- self , zim_with_varied_illustrations , favicon_data
203+ self , zim_with_varied_illustrations , favicon_data_96
187204 ):
188205 """Test getting specific scale illustration."""
189206 zim = Archive (zim_with_varied_illustrations )
190207
191- # Get the 48x48@2 illustration specifically
208+ # Get the 48x48@2 illustration specifically (96x96 physical pixels)
192209 info = IllustrationInfo (48 , 48 , 2.0 )
193- item = zim .get_illustration_item (info = info )
194- assert bytes (item .content ) == favicon_data
210+ item = zim .get_illustration_item (info )
211+ assert bytes (item .content ) == favicon_data_96
195212
196213 def test_get_illustration_item_nonexistent (self , zim_with_varied_illustrations ):
197214 """Test getting non-existent illustration raises error."""
@@ -200,20 +217,31 @@ def test_get_illustration_item_nonexistent(self, zim_with_varied_illustrations):
200217 # Try to get illustration that doesn't exist
201218 info = IllustrationInfo (999 , 999 , 1.0 )
202219 with pytest .raises (KeyError ):
203- zim .get_illustration_item (info = info )
220+ zim .get_illustration_item (info )
221+
222+ def test_get_illustration_item_default (
223+ self , zim_with_varied_illustrations , favicon_data_48
224+ ):
225+ """Test that get_illustration_item() without argument defaults to size 48."""
226+ zim = Archive (zim_with_varied_illustrations )
227+
228+ # No argument should default to 48x48@1
229+ item = zim .get_illustration_item ()
230+ assert bytes (item .content ) == favicon_data_48
231+ assert "Illustration_48x48@1" in item .path
204232
205233 def test_get_illustration_item_old_api_still_works (
206- self , zim_with_varied_illustrations , favicon_data
234+ self , zim_with_varied_illustrations , favicon_data_48 , favicon_data_96
207235 ):
208236 """Test that old API (size parameter) still works."""
209237 zim = Archive (zim_with_varied_illustrations )
210238
211239 # Old API with size should work for @1 scale illustrations
212- item = zim .get_illustration_item (size = 48 )
213- assert bytes (item .content ) == favicon_data
240+ item = zim .get_illustration_item (48 )
241+ assert bytes (item .content ) == favicon_data_48
214242
215- item = zim .get_illustration_item (size = 96 )
216- assert bytes (item .content ) == favicon_data
243+ item = zim .get_illustration_item (96 )
244+ assert bytes (item .content ) == favicon_data_96
217245
218246
219247class TestDeprecationWarnings :
0 commit comments