from pathlib import Path import pytest from nisse_dev.git import GitError, GitRepo, _scrub, authenticated_url @pytest.fixture def repo(tmp_path: Path) -> GitRepo: r = GitRepo(tmp_path / "work") r.init() r.configure_identity("nisse-dev-testing", "nisse@example.test") return r def test_init_creates_repo_on_default_branch(repo: GitRepo) -> None: assert repo.current_branch() == "main" def test_commit_all_returns_sha_and_branch_switching(repo: GitRepo) -> None: (repo.root / "a.txt").write_text("a") sha = repo.commit_all("first") assert sha is not None assert sha == repo.head_sha() repo.checkout_new_branch("milestone-1") assert repo.current_branch() == "milestone-1" def test_commit_with_nothing_staged_returns_none(repo: GitRepo) -> None: (repo.root / "a.txt").write_text("a") repo.commit_all("first") # An empty milestone is a fact to report, not an error to raise. assert repo.commit_all("nothing changed") is None def test_has_changes_tracks_the_worktree(repo: GitRepo) -> None: assert not repo.has_changes() (repo.root / "a.txt").write_text("a") assert repo.has_changes() def test_authenticated_url_shape() -> None: url = authenticated_url("https://gitea.test/", "o/r", "bot", "secret") assert url == "https://bot:secret@gitea.test/o/r.git" def test_push_failure_does_not_leak_the_token(repo: GitRepo) -> None: (repo.root / "a.txt").write_text("a") repo.commit_all("first") url = authenticated_url("https://127.0.0.1:1", "o/r", "bot", "sup3rsecret") with pytest.raises(GitError) as excinfo: repo.push(url, "main", token="sup3rsecret") # git redacts credentials from its own messages, but that is git's # behaviour, not ours; the scrub below is the guarantee we control. assert "sup3rsecret" not in str(excinfo.value) def test_scrub_removes_the_token_when_git_does_echo_it() -> None: assert _scrub("failed to push to https://bot:s3cret@h/o/r.git", "s3cret") == ( "failed to push to https://bot:***@h/o/r.git" ) assert _scrub("no secret here", None) == "no secret here" def test_git_error_on_bad_command(tmp_path: Path) -> None: repo = GitRepo(tmp_path / "not-a-repo") repo.root.mkdir() with pytest.raises(GitError): repo.head_sha()