Files
python-github-backup/tests/test_pull_reviews.py
2026-04-29 11:43:30 +02:00

238 lines
8.3 KiB
Python

"""Tests for pull request review backups."""
import json
import os
from github_backup import github_backup
def test_parse_args_pull_reviews_flag():
args = github_backup.parse_args(["--pull-reviews", "testuser"])
assert args.include_pull_reviews is True
def test_backup_pulls_includes_review_data(create_args, tmp_path, monkeypatch):
args = create_args(include_pulls=True, include_pull_reviews=True)
repository = {"full_name": "owner/repo"}
calls = []
def fake_retrieve_data(passed_args, template, query_args=None, paginated=True):
calls.append((template, query_args))
if template == "https://api.github.com/repos/owner/repo/pulls":
if query_args["state"] == "open":
return [
{
"number": 1,
"updated_at": "2026-02-01T00:00:00Z",
"title": "Add feature",
}
]
return []
if template == "https://api.github.com/repos/owner/repo/pulls/1/reviews":
return [
{
"id": 123,
"state": "APPROVED",
"body": "Looks good",
"submitted_at": "2026-02-01T00:00:00Z",
}
]
raise AssertionError("Unexpected template: {0}".format(template))
monkeypatch.setattr(github_backup, "retrieve_data", fake_retrieve_data)
github_backup.backup_pulls(
args, tmp_path, repository, "https://api.github.com/repos"
)
with open(tmp_path / "pulls" / "1.json", encoding="utf-8") as f:
pull = json.load(f)
assert pull["review_data"] == [
{
"body": "Looks good",
"id": 123,
"state": "APPROVED",
"submitted_at": "2026-02-01T00:00:00Z",
}
]
assert (
"https://api.github.com/repos/owner/repo/pulls/1/reviews",
None,
) in calls
def test_pull_reviews_backfill_ignores_repository_checkpoint(
create_args, tmp_path, monkeypatch
):
args = create_args(
include_pulls=True,
include_pull_reviews=True,
incremental=True,
)
args.since = "2026-01-01T00:00:00Z"
repository = {"full_name": "owner/repo"}
def fake_retrieve_data(passed_args, template, query_args=None, paginated=True):
if template == "https://api.github.com/repos/owner/repo/pulls":
if query_args["state"] == "open":
return [
{
"number": 1,
"updated_at": "2025-01-01T00:00:00Z",
"title": "Old pull request",
}
]
return []
if template == "https://api.github.com/repos/owner/repo/pulls/1/reviews":
return [{"id": 123, "state": "APPROVED"}]
raise AssertionError("Unexpected template: {0}".format(template))
monkeypatch.setattr(github_backup, "retrieve_data", fake_retrieve_data)
github_backup.backup_pulls(
args, tmp_path, repository, "https://api.github.com/repos"
)
with open(tmp_path / "pulls" / "1.json", encoding="utf-8") as f:
pull = json.load(f)
assert pull["review_data"] == [{"id": 123, "state": "APPROVED"}]
assert (tmp_path / "pulls" / "reviews_last_update").read_text() == (
"2025-01-01T00:00:00Z"
)
def test_pull_reviews_uses_review_checkpoint_when_older_than_repository_checkpoint(
create_args, tmp_path, monkeypatch
):
args = create_args(
include_pulls=True,
include_pull_reviews=True,
incremental=True,
)
args.since = "2026-01-01T00:00:00Z"
repository = {"full_name": "owner/repo"}
pulls_dir = tmp_path / "pulls"
pulls_dir.mkdir()
(pulls_dir / "reviews_last_update").write_text("2025-01-01T00:00:00Z")
def fake_retrieve_data(passed_args, template, query_args=None, paginated=True):
if template == "https://api.github.com/repos/owner/repo/pulls":
if query_args["state"] == "open":
return [
{
"number": 1,
"updated_at": "2025-06-01T00:00:00Z",
"title": "Review changed while feature was disabled",
},
{
"number": 2,
"updated_at": "2024-12-01T00:00:00Z",
"title": "Too old",
},
]
return []
if template == "https://api.github.com/repos/owner/repo/pulls/1/reviews":
return [{"id": 123, "state": "COMMENTED"}]
raise AssertionError("Unexpected template: {0}".format(template))
monkeypatch.setattr(github_backup, "retrieve_data", fake_retrieve_data)
github_backup.backup_pulls(
args, tmp_path, repository, "https://api.github.com/repos"
)
assert os.path.exists(tmp_path / "pulls" / "1.json")
assert not os.path.exists(tmp_path / "pulls" / "2.json")
assert (tmp_path / "pulls" / "reviews_last_update").read_text() == (
"2025-06-01T00:00:00Z"
)
def test_pull_reviews_preserves_existing_optional_pull_data(
create_args, tmp_path, monkeypatch
):
args = create_args(include_pulls=True, include_pull_reviews=True)
repository = {"full_name": "owner/repo"}
pulls_dir = tmp_path / "pulls"
pulls_dir.mkdir()
with open(pulls_dir / "1.json", "w", encoding="utf-8") as f:
json.dump(
{
"number": 1,
"updated_at": "2026-01-01T00:00:00Z",
"comment_data": [{"id": 10, "body": "inline comment"}],
"comment_regular_data": [{"id": 11, "body": "regular comment"}],
"commit_data": [{"sha": "abc"}],
},
f,
)
def fake_retrieve_data(passed_args, template, query_args=None, paginated=True):
if template == "https://api.github.com/repos/owner/repo/pulls":
if query_args["state"] == "open":
return [
{
"number": 1,
"updated_at": "2026-02-01T00:00:00Z",
"title": "Add reviews",
}
]
return []
if template == "https://api.github.com/repos/owner/repo/pulls/1/reviews":
return [{"id": 123, "state": "APPROVED"}]
raise AssertionError("Unexpected template: {0}".format(template))
monkeypatch.setattr(github_backup, "retrieve_data", fake_retrieve_data)
github_backup.backup_pulls(
args, tmp_path, repository, "https://api.github.com/repos"
)
with open(pulls_dir / "1.json", encoding="utf-8") as f:
pull = json.load(f)
assert pull["review_data"] == [{"id": 123, "state": "APPROVED"}]
assert pull["comment_data"] == [{"id": 10, "body": "inline comment"}]
assert pull["comment_regular_data"] == [{"id": 11, "body": "regular comment"}]
assert pull["commit_data"] == [{"sha": "abc"}]
def test_pull_reviews_does_not_advance_checkpoint_on_review_error(
create_args, tmp_path, monkeypatch
):
args = create_args(
include_pulls=True,
include_pull_reviews=True,
incremental=True,
)
args.since = "2026-01-01T00:00:00Z"
repository = {"full_name": "owner/repo"}
pulls_dir = tmp_path / "pulls"
pulls_dir.mkdir()
(pulls_dir / "reviews_last_update").write_text("2025-01-01T00:00:00Z")
def fake_retrieve_data(passed_args, template, query_args=None, paginated=True):
if template == "https://api.github.com/repos/owner/repo/pulls":
if query_args["state"] == "open":
return [
{
"number": 1,
"updated_at": "2025-06-01T00:00:00Z",
"title": "Review retrieval fails",
}
]
return []
if template == "https://api.github.com/repos/owner/repo/pulls/1/reviews":
raise Exception("temporary API failure")
raise AssertionError("Unexpected template: {0}".format(template))
monkeypatch.setattr(github_backup, "retrieve_data", fake_retrieve_data)
github_backup.backup_pulls(
args, tmp_path, repository, "https://api.github.com/repos"
)
assert (pulls_dir / "reviews_last_update").read_text() == "2025-01-01T00:00:00Z"