Coverage for tests/utility/test_project.py: 100%
57 statements
« prev ^ index » next coverage.py v7.10.5, created at 2025-08-28 09:13 +0000
« prev ^ index » next coverage.py v7.10.5, created at 2025-08-28 09:13 +0000
1"""Test module for the functions in the `utils/project.py` module.
3This module contains unit tests for the functions implemented in the `utils/project.py` module. The purpose of these tests is to
4ensure the correct functionality of each function in different scenarios and to validate that the expected outputs are
5returned.
7Tests should cover various edge cases, valid inputs, and any other conditions that are necessary to confirm the
8robustness of the functions."""
10from pathlib import Path
11from unittest.mock import patch, Mock, mock_open
13import pytest
15from utility.project import get_last_commit_date_from_github, get_pyproject_info
18class TestGetLastCommitDateFromGitHub:
20 @patch("utility.project.requests.get")
21 def test_successful_response(self, mock_get) -> None:
23 # Arrange
24 mock_response = Mock()
25 mock_response.raise_for_status.return_value = None
26 mock_response.json.return_value = [{"commit": {"committer": {"date": "2024-04-27T12:34:56Z"}}}]
27 mock_get.return_value = mock_response
29 # Act
30 result = get_last_commit_date_from_github("https://github.com/owner/repo")
32 # Assert
33 assert result == "27 April 2024"
34 mock_get.assert_called_once_with("https://api.github.com/repos/owner/repo/commits?sha=main")
36 @patch("utility.project.requests.get")
37 def test_custom_branch(self, mock_get) -> None:
39 mock_response = Mock()
40 mock_response.raise_for_status.return_value = None
41 mock_response.json.return_value = [{"commit": {"committer": {"date": "2024-01-15T08:00:00Z"}}}]
42 mock_get.return_value = mock_response
44 result = get_last_commit_date_from_github("https://github.com/owner/repo", branch="dev")
45 assert result == "15 January 2024"
46 mock_get.assert_called_once_with("https://api.github.com/repos/owner/repo/commits?sha=dev")
48 @patch("utility.project.requests.get")
49 def test_http_error(self, mock_get) -> None:
51 # Arrange
52 mock_response = Mock()
53 mock_response.raise_for_status.side_effect = Exception("404 Not Found")
54 mock_get.return_value = mock_response
56 # Act
57 result = get_last_commit_date_from_github("https://github.com/owner/repo")
59 # Assert
60 assert result.startswith("Error fetching data:")
63class TestGetPyprojectInfo:
65 @patch("utility.project.tomllib.load")
66 @patch("utility.project.Path.open", new_callable=mock_open)
67 @patch("utility.project.Path.resolve")
68 def test_single_key(self, mock_resolve, mock_open_file, mock_toml_load) -> None:
69 # Arrange
70 mock_resolve.return_value = Path("/fake/path/to/pyproject.toml")
71 mock_toml_load.return_value = {"tool": {"poetry": {"name": "example-package"}}}
73 # Act
74 result = get_pyproject_info("tool")
76 # Assert
77 assert result == {"poetry": {"name": "example-package"}}
78 mock_open_file.assert_called_once_with("rb")
80 @patch("utility.project.tomllib.load")
81 @patch("utility.project.Path.open", new_callable=mock_open)
82 @patch("utility.project.Path.resolve")
83 def test_multiple_keys(self, mock_resolve, mock_open_file, mock_toml_load) -> None:
84 # Arrange
85 mock_resolve.return_value = Path("/fake/path/to/pyproject.toml")
86 mock_toml_load.return_value = {"tool": {"poetry": {"version": "1.2.3"}}}
88 # Act
89 result = get_pyproject_info("tool", "poetry", "version")
91 # Assert
92 assert result == "1.2.3"
93 mock_open_file.assert_called_once_with("rb")
95 @patch("utility.project.tomllib.load")
96 @patch("utility.project.Path.open", new_callable=mock_open)
97 @patch("utility.project.Path.resolve")
98 def test_missing_key_raises_keyerror(self, mock_resolve, _mock_open_file, mock_toml_load) -> None:
99 # Arrange
100 mock_resolve.return_value = Path("/fake/path/to/pyproject.toml")
101 mock_toml_load.return_value = {"tool": {"poetry": {}}}
103 # Act & Assert
104 with pytest.raises(KeyError):
105 get_pyproject_info("tool", "poetry", "nonexistent_key")