@@ -208,6 +208,86 @@ def test_preferred_region_wins_over_cus(self):
208208 assert result ["box2d_url" ] is not None
209209 assert "box-2D(us)" in result ["box2d_url" ]
210210
211+ def _make_game_with_box_faces (self ) -> SSGame :
212+ """A game exposing all three box faces: front, back and spine."""
213+ return cast (
214+ SSGame ,
215+ {
216+ "medias" : [
217+ {
218+ "type" : "box-2D" ,
219+ "parent" : "jeu" ,
220+ "region" : "us" ,
221+ "url" : "https://screenscraper.example.com/box-2D" ,
222+ "crc" : "aabbccdd" ,
223+ "md5" : "deadbeef" ,
224+ "sha1" : "cafebabe" ,
225+ "size" : "12345" ,
226+ "format" : "png" ,
227+ },
228+ {
229+ "type" : "box-2D-back" ,
230+ "parent" : "jeu" ,
231+ "region" : "us" ,
232+ "url" : "https://screenscraper.example.com/box-2D-back" ,
233+ "crc" : "11223344" ,
234+ "md5" : "feedface" ,
235+ "sha1" : "baadf00d" ,
236+ "size" : "23456" ,
237+ "format" : "png" ,
238+ },
239+ {
240+ "type" : "box-2D-side" ,
241+ "parent" : "jeu" ,
242+ "region" : "us" ,
243+ "url" : "https://screenscraper.example.com/box-2D-side" ,
244+ "crc" : "55667788" ,
245+ "md5" : "0ddba11" ,
246+ "sha1" : "f00dcafe" ,
247+ "size" : "34567" ,
248+ "format" : "png" ,
249+ },
250+ ]
251+ },
252+ )
253+
254+ def test_box2d_side_path_set_when_in_config (self ):
255+ """When 'box2d_side' is in SCAN_MEDIA the spine is persisted locally."""
256+ config = _make_config (scan_media = ["box2d" , "box2d_back" , "box2d_side" ])
257+ rom = self ._make_rom ()
258+ game = self ._make_game_with_box_faces ()
259+
260+ with (
261+ patch ("handler.metadata.ss_handler.cm.get_config" , return_value = config ),
262+ patch (
263+ "handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path" ,
264+ side_effect = lambda pid , rid , mt : f"roms/{ pid } /{ rid } /{ mt .value } " ,
265+ ),
266+ ):
267+ result = extract_media_from_ss_game (rom , game )
268+
269+ assert result ["box2d_side_url" ] is not None
270+ assert "box-2D-side" in result ["box2d_side_url" ]
271+ assert result ["box2d_side_path" ] == "roms/1/100/box2d_side/box2d_side.png"
272+
273+ def test_box2d_side_path_not_set_when_absent_from_config (self ):
274+ """Without 'box2d_side' in SCAN_MEDIA the spine URL is kept but not stored."""
275+ config = _make_config (scan_media = ["box2d" , "box2d_back" ])
276+ rom = self ._make_rom ()
277+ game = self ._make_game_with_box_faces ()
278+
279+ with (
280+ patch ("handler.metadata.ss_handler.cm.get_config" , return_value = config ),
281+ patch (
282+ "handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path" ,
283+ side_effect = lambda pid , rid , mt : f"roms/{ pid } /{ rid } /{ mt .value } " ,
284+ ),
285+ ):
286+ result = extract_media_from_ss_game (rom , game )
287+
288+ assert result ["box2d_side_url" ] is not None
289+ assert result ["box2d_side_path" ] is None
290+
211291 def _make_game_with_both_miximage_versions (self ) -> SSGame :
212292 """A game that has both mixrbv1 and mixrbv2 (v1 listed first, matching SS API order)."""
213293 return cast (
0 commit comments