import os from pathlib import Path from unittest.mock import MagicMock, patch import pytest from vrobbler import context_processors from vrobbler.context_processors import version_info @pytest.fixture(autouse=True) def reset_git_cache(): context_processors._GIT_COMMIT = None @pytest.fixture def mock_request(): return MagicMock() class TestVersionInfo: def test_returns_version_and_commit(self, mock_request): """Test that git commit is returned when _commit.py doesn't exist""" with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, ): mock_get_version.return_value = "1.0.0" mock_check_output.return_value = b"abc1234" # Mock the import to raise ImportError so git is used import builtins original_import = builtins.__import__ def mock_import(name, *args, **kwargs): if name == "vrobbler._commit": raise ImportError("No module named 'vrobbler._commit'") return original_import(name, *args, **kwargs) with patch("builtins.__import__", side_effect=mock_import): result = version_info(mock_request) assert result["app_version"] == "1.0.0" assert result["git_commit"] == "abc1234" def test_uses_env_commit_if_set(self, mock_request): with ( patch.dict(os.environ, {"VROBBLER_COMMIT": "env_commit_hash"}), patch("vrobbler.context_processors.get_version") as mock_get_version, ): mock_get_version.return_value = "1.0.0" result = version_info(mock_request) assert result["git_commit"] == "env_commit_hash" def test_uses_commit_from_module_when_available(self, mock_request): """Test that commit from _commit.py module is used when available""" with (patch("vrobbler.context_processors.get_version") as mock_get_version,): mock_get_version.return_value = "1.0.0" result = version_info(mock_request) # Should use whatever value is in vrobbler/_commit.py # Could be "unknown" or an actual commit hash assert "git_commit" in result assert result["git_commit"] != "" def test_uses_commit_from_file_when_module_unavailable(self, mock_request): """Test that commit from /var/lib/vrobbler/commit.txt is used""" with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch("pathlib.Path.exists", return_value=True), patch("pathlib.Path.read_text", return_value="file_commit_hash"), ): mock_get_version.return_value = "1.0.0" # Mock the import to raise ImportError import builtins original_import = builtins.__import__ def mock_import(name, *args, **kwargs): if name == "vrobbler._commit": raise ImportError("No module named 'vrobbler._commit'") return original_import(name, *args, **kwargs) with patch("builtins.__import__", side_effect=mock_import): result = version_info(mock_request) assert result["git_commit"] == "file_commit_hash" def test_falls_back_to_git_when_file_unavailable(self, mock_request): """Test fallback to git when _commit.py and file don't exist""" with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch("pathlib.Path.exists", return_value=False), patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, ): mock_get_version.return_value = "1.0.0" mock_check_output.return_value = b"git_commit_hash" # Mock the import to raise ImportError import builtins original_import = builtins.__import__ def mock_import(name, *args, **kwargs): if name == "vrobbler._commit": raise ImportError("No module named 'vrobbler._commit'") return original_import(name, *args, **kwargs) with patch("builtins.__import__", side_effect=mock_import): result = version_info(mock_request) assert result["git_commit"] == "git_commit_hash" def test_returns_unknown_when_version_fails(self, mock_request): with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, ): mock_get_version.side_effect = Exception("not found") mock_check_output.return_value = b"abc1234" result = version_info(mock_request) assert result["app_version"] == "unknown" def test_returns_unknown_when_git_fails(self, mock_request): import subprocess with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, ): mock_get_version.return_value = "1.0.0" mock_check_output.side_effect = subprocess.SubprocessError() result = version_info(mock_request) assert result["git_commit"] == "unknown" def test_returns_unknown_when_git_not_found(self, mock_request): import subprocess with ( patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, ): mock_get_version.return_value = "1.0.0" mock_check_output.side_effect = FileNotFoundError() result = version_info(mock_request) assert result["git_commit"] == "unknown"