@@ -30,6 +30,9 @@ def source():
3030 folder_path = temp_dir / folder
3131 folder_path .mkdir (exist_ok = True )
3232
33+ # Schema file used by unit tests for _find_schema_candidates
34+ (temp_dir / "schema.json" ).write_text ("{}" , encoding = "utf-8" )
35+
3336 yield temp_dir
3437 import shutil
3538
@@ -222,6 +225,7 @@ def test_from_settings_transfer_args(
222225 settings .job_type = "not_default"
223226
224227 manifest = watchdog_service ._manifest_config
228+ assert manifest is not None
225229 new_watchdog_manifest = watchdog_service ._make_transfer_args (
226230 manifest ,
227231 add_default_tasks = True ,
@@ -236,12 +240,18 @@ def test_from_settings_transfer_args(
236240 assert "modality_transformation_settings" in tasks
237241 assert "gather_preliminary_metadata" in tasks
238242 assert all (task in tasks for task in ["myTask" , "nestedTask" , "myTaskInterpolated" , "nestedTaskInterpolated" ])
243+ my_task_interpolated = tasks ["myTaskInterpolated" ]
244+ assert isinstance (my_task_interpolated , Task )
239245 assert (
240- Path (tasks [ "myTaskInterpolated" ]. job_settings ["input_source" ]).resolve ()
246+ Path (my_task_interpolated . model_dump ()[ "job_settings" ] ["input_source" ]).resolve ()
241247 == Path (f"interpolated/path/{ WatchdogDataTransferService ._remote_destination_root (manifest )} " ).resolve ()
242248 )
249+ nested_wrapper = tasks ["nestedTaskInterpolated" ]
250+ assert isinstance (nested_wrapper , dict )
251+ nested_task = nested_wrapper ["nestedTask" ]
252+ assert isinstance (nested_task , Task )
243253 assert (
244- Path (tasks [ "nestedTaskInterpolated" ][ "nestedTask" ]. job_settings ["input_source" ]).resolve ()
254+ Path (nested_task . model_dump ()[ "job_settings" ] ["input_source" ]).resolve ()
245255 == Path (
246256 f"interpolated/path/{ WatchdogDataTransferService ._remote_destination_root (manifest )} /nested"
247257 ).resolve ()
@@ -268,12 +278,18 @@ def test_make_transfer_args(self, watchdog_service: WatchdogDataTransferService)
268278 assert "modality_transformation_settings" in tasks
269279 assert "gather_preliminary_metadata" in tasks
270280 assert all (task in tasks for task in ["myTask" , "nestedTask" , "myTaskInterpolated" , "nestedTaskInterpolated" ])
281+ my_task_interpolated = tasks ["myTaskInterpolated" ]
282+ assert isinstance (my_task_interpolated , Task )
271283 assert (
272- Path (tasks [ "myTaskInterpolated" ]. job_settings ["input_source" ]).resolve ()
284+ Path (my_task_interpolated . model_dump ()[ "job_settings" ] ["input_source" ]).resolve ()
273285 == Path (f"interpolated/path/{ WatchdogDataTransferService ._remote_destination_root (manifest )} " ).resolve ()
274286 )
287+ nested_wrapper = tasks ["nestedTaskInterpolated" ]
288+ assert isinstance (nested_wrapper , dict )
289+ nested_task = nested_wrapper ["nestedTask" ]
290+ assert isinstance (nested_task , Task )
275291 assert (
276- Path (tasks [ "nestedTaskInterpolated" ][ "nestedTask" ]. job_settings ["input_source" ]).resolve ()
292+ Path (nested_task . model_dump ()[ "job_settings" ] ["input_source" ]).resolve ()
277293 == Path (
278294 f"interpolated/path/{ WatchdogDataTransferService ._remote_destination_root (manifest )} /nested"
279295 ).resolve ()
@@ -408,6 +424,48 @@ def test_is_valid_project_name_valid(self, mock_get_project_names, watchdog_serv
408424 def test_is_valid_project_name_invalid (self , mock_get_project_names , watchdog_service ):
409425 assert not watchdog_service .is_valid_project_name ()
410426
427+ def test_remote_destination_root (
428+ self , watchdog_service : WatchdogDataTransferService , mock_session : AindBehaviorSessionModel
429+ ):
430+ manifest = watchdog_service ._create_manifest_from_session (mock_session )
431+ root = watchdog_service ._remote_destination_root (manifest )
432+ assert manifest .name is not None
433+ expected_root = Path (manifest .destination ) / manifest .name
434+ assert root == expected_root
435+
436+ def test_find_modality_candidates (self , watchdog_service : WatchdogDataTransferService , source : Path ):
437+ candidates = watchdog_service ._find_modality_candidates (source )
438+ assert set (candidates .keys ()) == {"behavior" , "behavior-videos" }
439+
440+ def test_find_schema_candidates (self , watchdog_service : WatchdogDataTransferService , source : Path ):
441+ schemas = watchdog_service ._find_schema_candidates (source )
442+ assert any (p .name == "schema.json" for p in schemas )
443+
444+ def test_interpolate_from_manifest (
445+ self , watchdog_service : WatchdogDataTransferService , mock_session : AindBehaviorSessionModel
446+ ):
447+ watchdog_service ._create_manifest_from_session (mock_session )
448+ tasks = {"custom" : Task (job_settings = {"input_source" : "{{ destination }}/extra" })}
449+ interpolated = watchdog_service ._interpolate_from_manifest (tasks , "replacement/value" , "{{ destination }}" )
450+ assert isinstance (interpolated ["custom" ], Task )
451+ assert interpolated ["custom" ].model_dump ()["job_settings" ]["input_source" ].startswith ("replacement/value" )
452+
453+ def test_yaml_dump_and_write_read_yaml (
454+ self ,
455+ watchdog_service : WatchdogDataTransferService ,
456+ mock_session : AindBehaviorSessionModel ,
457+ tmp_path : Path ,
458+ ):
459+ manifest = watchdog_service ._create_manifest_from_session (mock_session )
460+ yaml_str = watchdog_service ._yaml_dump (manifest )
461+ assert manifest .name is not None
462+ assert manifest .name in yaml_str
463+ out_path = tmp_path / "manifest.yaml"
464+ watchdog_service ._write_yaml (manifest , out_path )
465+ loaded = watchdog_service ._read_yaml (out_path )
466+ assert isinstance (loaded , dict )
467+ assert loaded .get ("name" ) == manifest .name
468+
411469
412470@pytest .fixture
413471def robocopy_settings ():
0 commit comments