@@ -30,6 +30,8 @@ class TestDownloadList:
3030 - add_files_batch: multiple files added in one call
3131 - download_files_multiple_versions: two versions of the same file both download
3232 - get_manifest_custom_csv_descriptor: tab-separated descriptor produces TSV
33+ - add_files_no_version: version_number=None adds latest version
34+ - remove_files_no_version: version_number=None does not match explicit version
3335 - download_files_default_location: omitting download_location writes to CWD
3436 """
3537
@@ -430,6 +432,72 @@ async def test_get_manifest_with_custom_csv_descriptor(
430432 row ["ID" ] == file .id for row in rows
431433 ), f"Expected { file .id } in tab-separated manifest"
432434
435+ async def test_add_files_with_no_version_number (
436+ self ,
437+ project : Synapse_Project ,
438+ syn : Synapse ,
439+ schedule_for_cleanup : Callable [..., None ],
440+ ) -> None :
441+ """add_files_async() with version_number=None adds the latest version."""
442+ # GIVEN an empty cart and a file in Synapse
443+ await DownloadList .clear_async (synapse_client = syn )
444+ file = await self ._create_test_file (project , syn , schedule_for_cleanup )
445+
446+ # WHEN I add the file without specifying a version number
447+ count = await DownloadList .add_files_async (
448+ files = [
449+ DownloadListItem (file_entity_id = file .id ),
450+ ],
451+ synapse_client = syn ,
452+ )
453+
454+ # THEN the file is added to the cart
455+ assert count == 1 , f"Expected 1 file added, got { count } "
456+
457+ manifest_path = await DownloadList .get_manifest_async (synapse_client = syn )
458+ schedule_for_cleanup (manifest_path )
459+ with open (manifest_path , newline = "" ) as f :
460+ reader = csv .DictReader (f )
461+ ids_in_cart = {row ["ID" ] for row in reader }
462+ await DownloadList .clear_async (synapse_client = syn )
463+
464+ assert file .id in ids_in_cart , f"Expected { file .id } in the cart"
465+
466+ async def test_remove_files_with_no_version_number (
467+ self ,
468+ project : Synapse_Project ,
469+ syn : Synapse ,
470+ schedule_for_cleanup : Callable [..., None ],
471+ ) -> None :
472+ """remove_files_async() with version_number=None does NOT match a cart entry
473+ that was added with an explicit version — the API requires an exact
474+ (fileEntityId, versionNumber) pair."""
475+ # GIVEN an empty cart with one file added (with explicit version)
476+ await DownloadList .clear_async (synapse_client = syn )
477+ file = await self ._create_test_file (project , syn , schedule_for_cleanup )
478+ await self ._add_to_cart (file , syn )
479+
480+ # WHEN I try to remove the file without specifying a version number
481+ removed = await DownloadList .remove_files_async (
482+ files = [
483+ DownloadListItem (file_entity_id = file .id ),
484+ ],
485+ synapse_client = syn ,
486+ )
487+
488+ # THEN nothing is removed because null versionNumber doesn't match
489+ assert removed == 0 , f"Expected 0 files removed, got { removed } "
490+
491+ # AND the file is still in the cart
492+ manifest_path = await DownloadList .get_manifest_async (synapse_client = syn )
493+ schedule_for_cleanup (manifest_path )
494+ with open (manifest_path , newline = "" ) as f :
495+ reader = csv .DictReader (f )
496+ ids_in_cart = {row ["ID" ] for row in reader }
497+ await DownloadList .clear_async (synapse_client = syn )
498+
499+ assert file .id in ids_in_cart , f"Expected { file .id } to still be in the cart"
500+
433501 async def test_download_files_default_location (
434502 self ,
435503 project : Synapse_Project ,
0 commit comments