"""Tests for CLI artifact default paths and legacy compatibility warnings.""" import json from pathlib import Path from unittest.mock import patch from click.testing import CliRunner from vlm.cli import main def _write_config(path: Path, library_root: Path, workspace_dir: str | None = None) -> None: workspace_line = f"\nworkspace_dir: {workspace_dir}" if workspace_dir else "" path.write_text( ( f"library_root: {library_root}\n" "video_extensions:\n" " - .mp4\n" " - .mkv\n" "categories:\n" " movie: [movie, movies]\n" " series: [series, tv, shows]\n" " anime: [anime]\n" f"{workspace_line}\n" ), encoding="utf-8", ) def _write_inventory_csv(path: Path) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text( "# vlm inventory\n" "path,filename,size_bytes,modified_timestamp,category,resolution,codec,duration_seconds,bitrate_kbps\n" "/library/movie/Matrix (1999).mkv,Matrix (1999).mkv,1000000,2024-01-01T00:00:00,movie,,,\n", encoding="utf-8", ) def test_scan_default_output_uses_artifacts_dir(tmp_path): """Scan should write to artifacts/inventory.csv by default.""" library_root = tmp_path / "library" library_root.mkdir(parents=True) config_file = tmp_path / "config.yaml" _write_config(config_file, library_root) runner = CliRunner() with patch("vlm.commands.scan.scan_library", return_value=[]), patch( "vlm.commands.scan.save_inventory_csv" ) as mock_save: result = runner.invoke(main, ["--config", str(config_file), "scan"]) assert result.exit_code == 0 assert mock_save.call_count == 1 assert mock_save.call_args.args[1] == Path("artifacts/inventory.csv") def test_scan_default_output_uses_workspace_dir_from_config(tmp_path): """Scan should honor configured workspace_dir for default output.""" library_root = tmp_path / "library" library_root.mkdir(parents=True) config_file = tmp_path / "config.yaml" _write_config(config_file, library_root, workspace_dir="work/cache") runner = CliRunner() with patch("vlm.commands.scan.scan_library", return_value=[]), patch( "vlm.commands.scan.save_inventory_csv" ) as mock_save: result = runner.invoke(main, ["--config", str(config_file), "scan"]) assert result.exit_code == 0 assert mock_save.call_count == 1 assert mock_save.call_args.args[1] == Path("work/cache/inventory.csv") def test_parse_default_input_falls_back_to_legacy_root_file_with_warning(tmp_path): """Parse should warn and fallback to legacy root inventory.csv during stage-A migration.""" runner = CliRunner() with runner.isolated_filesystem(temp_dir=str(tmp_path)): library_root = Path("library") library_root.mkdir(parents=True) config_file = Path("config.yaml") _write_config(config_file, library_root) _write_inventory_csv(Path("inventory.csv")) result = runner.invoke(main, ["--config", str(config_file), "parse"]) assert result.exit_code == 0 assert "Warning: detected legacy default input at" in result.output assert "example: --input" in result.output assert Path("artifacts/identities.json").exists() data = json.loads(Path("artifacts/identities.json").read_text(encoding="utf-8")) assert data["metadata"]["source_inventory"] == "inventory.csv" def test_parse_default_input_no_warning_when_artifacts_input_exists(tmp_path): """When artifacts input exists, parse should use it without migration warning.""" runner = CliRunner() with runner.isolated_filesystem(temp_dir=str(tmp_path)): library_root = Path("library") library_root.mkdir(parents=True) config_file = Path("config.yaml") _write_config(config_file, library_root) _write_inventory_csv(Path("artifacts/inventory.csv")) _write_inventory_csv(Path("inventory.csv")) result = runner.invoke(main, ["--config", str(config_file), "parse"]) assert result.exit_code == 0 assert "Warning: detected legacy default input at" not in result.output