-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: adds unit tests for tasks and bot
Adds unit tests to isolate tasks from AuthoredObject Adds unit tests to test different combinations for staged files Adds unit test to text exception handling for git failures Signed-off-by: Jennifer Power <[email protected]>
- Loading branch information
Showing
4 changed files
with
149 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,20 +16,38 @@ | |
|
||
"""Test for top-level Trestle Bot logic.""" | ||
|
||
import json | ||
import os | ||
from typing import Tuple | ||
from typing import Callable, List, Tuple | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from git import GitCommandError | ||
from git.repo import Repo | ||
|
||
import trestlebot.bot as bot | ||
from tests.testutils import clean | ||
from trestlebot.provider import GitProvider | ||
|
||
|
||
def test_stage_files(tmp_repo: Tuple[str, Repo]) -> None: | ||
from trestlebot.provider import GitProvider, GitProviderException | ||
|
||
|
||
def check_arrays_equal(arr1: List[str], arr2: List[str]) -> bool: | ||
return sorted(arr1) == sorted(arr2) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"file_patterns, expected_files", | ||
[ | ||
(["*.txt"], ["file1.txt", "file2.txt"]), | ||
(["file*.txt"], ["file1.txt", "file2.txt"]), | ||
(["*.csv"], ["file3.csv"]), | ||
(["file*.csv"], ["file3.csv"]), | ||
(["*.txt", "*.csv"], ["file1.txt", "file2.txt", "file3.csv"]), | ||
(["."], ["file1.txt", "file2.txt", "file3.csv"]), | ||
([], []), | ||
], | ||
) | ||
def test_stage_files( | ||
tmp_repo: Tuple[str, Repo], file_patterns: List[str], expected_files: List[str] | ||
) -> None: | ||
"""Test staging files by patterns""" | ||
repo_path, repo = tmp_repo | ||
|
||
|
@@ -38,16 +56,16 @@ def test_stage_files(tmp_repo: Tuple[str, Repo]) -> None: | |
f.write("Test file 1 content") | ||
with open(os.path.join(repo_path, "file2.txt"), "w") as f: | ||
f.write("Test file 2 content") | ||
with open(os.path.join(repo_path, "file3.csv"), "w") as f: | ||
f.write("test,") | ||
|
||
# Stage the files | ||
bot._stage_files(repo, ["*.txt"]) | ||
bot._stage_files(repo, file_patterns) | ||
|
||
# Verify that files are staged | ||
staged_files = [item.a_path for item in repo.index.diff(repo.head.commit)] | ||
|
||
assert len(staged_files) == 2 | ||
assert "file1.txt" in staged_files | ||
assert "file2.txt" in staged_files | ||
assert check_arrays_equal(staged_files, expected_files) is True | ||
|
||
clean(repo_path, repo) | ||
|
||
|
@@ -201,28 +219,24 @@ def test_run_dry_run(tmp_repo: Tuple[str, Repo]) -> None: | |
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.txt"], | ||
dry_run=True, | ||
) | ||
assert commit_sha != "" | ||
with patch("git.remote.Remote.push") as mock_push: | ||
mock_push.return_value = "Mocked result" | ||
|
||
# Verify that the commit is made | ||
commit = next(repo.iter_commits()) | ||
assert commit.message.strip() == "Test commit message" | ||
assert commit.author.name == "The Author" | ||
assert commit.author.email == "[email protected]" | ||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.txt"], | ||
dry_run=True, | ||
) | ||
assert commit_sha != "" | ||
|
||
# Verify that the file is tracked by the commit | ||
assert os.path.basename(test_file_path) in commit.stats.files | ||
mock_push.assert_not_called() | ||
|
||
clean(repo_path, repo) | ||
|
||
|
@@ -248,48 +262,6 @@ def test_empty_commit(tmp_repo: Tuple[str, Repo]) -> None: | |
clean(repo_path, repo) | ||
|
||
|
||
def test_non_matching_files(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test that non-matching files are ignored""" | ||
repo_path, repo = tmp_repo | ||
|
||
# Create a test file | ||
test_file_path = os.path.join(repo_path, "test.txt") | ||
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
# Create a test file | ||
data = {"test": "file"} | ||
test_json_path = os.path.join(repo_path, "test.json") | ||
with open(test_json_path, "w") as f: | ||
json.dump(data, f, indent=4) | ||
|
||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.json"], | ||
dry_run=True, | ||
) | ||
assert commit_sha != "" | ||
|
||
# Verify that the commit is made | ||
commit = next(repo.iter_commits()) | ||
assert commit.message.strip() == "Test commit message" | ||
assert commit.author.name == "The Author" | ||
assert commit.author.email == "[email protected]" | ||
|
||
# Verify that only the JSON file is tracked in the commits | ||
assert os.path.basename(test_file_path) not in commit.stats.files | ||
assert os.path.basename(test_json_path) in commit.stats.files | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_run_check_only(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with check_only""" | ||
repo_path, repo = tmp_repo | ||
|
@@ -319,6 +291,53 @@ def test_run_check_only(tmp_repo: Tuple[str, Repo]) -> None: | |
clean(repo_path, repo) | ||
|
||
|
||
def push_side_effect(refspec: str) -> None: | ||
raise GitCommandError("example") | ||
|
||
|
||
def pull_side_effect(refspec: str) -> None: | ||
raise GitProviderException("example") | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"side_effect, msg", | ||
[ | ||
(push_side_effect, "Git push to .* failed: .*"), | ||
(pull_side_effect, "Git pull request to .* failed: example"), | ||
], | ||
) | ||
def test_run_with_exception( | ||
tmp_repo: Tuple[str, Repo], side_effect: Callable[[str], None], msg: str | ||
) -> None: | ||
"""Test bot run with mocked push with side effects that throw exceptions""" | ||
repo_path, repo = tmp_repo | ||
|
||
# Create a test file | ||
test_file_path = os.path.join(repo_path, "test.txt") | ||
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
repo.create_remote("origin", url="git.test.com/test/repo.git") | ||
|
||
with patch("git.remote.Remote.push") as mock_push: | ||
mock_push.side_effect = side_effect | ||
|
||
with pytest.raises(bot.RepoException, match=msg): | ||
_ = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.txt"], | ||
dry_run=False, | ||
) | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_run_with_provider(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with mock git provider""" | ||
repo_path, repo = tmp_repo | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters