Files
git-tui/tests/test_git_tui.py
2026-08-04 16:06:20 -03:00

228 lines
8.4 KiB
Python

"""Focused tests for pure URL resolution behavior in the executable module."""
import importlib.machinery
import importlib.util
import os
import pathlib
import subprocess
import sys
import tempfile
import unittest
from unittest import mock
SCRIPT_PATH = pathlib.Path(__file__).parents[1] / "git-tui"
LOADER = importlib.machinery.SourceFileLoader("git_tui", str(SCRIPT_PATH))
SPEC = importlib.util.spec_from_loader(LOADER.name, LOADER)
assert SPEC is not None
git_tui = importlib.util.module_from_spec(SPEC)
sys.modules[LOADER.name] = git_tui
LOADER.exec_module(git_tui)
class GiteaRemoteUrlTests(unittest.TestCase):
def setUp(self) -> None:
self.app = git_tui.GitTuiApp.__new__(git_tui.GitTuiApp)
def test_exact_custom_ssh_clone_url_is_preserved(self) -> None:
expected_url = "ssh://forge@git.example.com:2222/owner/project.git"
self.app.prompt_input = lambda *_args: expected_url
remote_url = self.app.prompt_gitea_existing_remote_url()
self.assertEqual(remote_url, expected_url)
def test_api_resolution_uses_giteas_advertised_ssh_url(self) -> None:
self.app.prompt_secret = lambda *_args: "token"
self.app.select_gitea_transport = lambda: "ssh"
requested_urls = []
def fake_get(url: str, token: str):
requested_urls.append((url, token))
return 200, "", {
"ssh_url": "ssh://forge@ssh.example.com:2222/owner/project.git",
"clone_url": "https://git.example.com/owner/project.git",
}
self.app.gitea_get_json = fake_get
with mock.patch.dict(
os.environ,
{"GITEA_TOKEN": "", "GITEA_ACCESS_TOKEN": ""},
clear=False,
):
remote_url = self.app.resolve_existing_gitea_url_via_api(
"owner/project", "https://git.example.com"
)
self.assertEqual(
remote_url,
"ssh://forge@ssh.example.com:2222/owner/project.git",
)
self.assertEqual(
requested_urls,
[("https://git.example.com/api/v1/repos/owner/project", "token")],
)
class RepositorySyncTests(unittest.TestCase):
def setUp(self) -> None:
self.app = git_tui.GitTuiApp.__new__(git_tui.GitTuiApp)
self.app.status_message = ""
self.app.show_output = lambda *_args: None
self.app.show_command_result = lambda *_args: None
self.original_cwd = pathlib.Path.cwd()
self.temp_dir = tempfile.TemporaryDirectory()
self.root = pathlib.Path(self.temp_dir.name)
def tearDown(self) -> None:
os.chdir(self.original_cwd)
self.temp_dir.cleanup()
def git(self, cwd: pathlib.Path, *args: str) -> str:
completed = subprocess.run(
["git", *args],
cwd=cwd,
check=True,
capture_output=True,
text=True,
)
return completed.stdout.strip()
def init_worktree(self, path: pathlib.Path) -> None:
path.mkdir()
self.git(path, "init", "-b", "main")
self.git(path, "config", "user.name", "Test User")
self.git(path, "config", "user.email", "test@example.com")
self.git(path, "config", "commit.gpgsign", "false")
def test_sync_pushes_local_commit_to_empty_remote(self) -> None:
remote = self.root / "remote.git"
local = self.root / "local"
remote.mkdir()
self.git(remote, "init", "--bare")
self.init_worktree(local)
(local / "local.txt").write_text("local\n", encoding="utf-8")
self.git(local, "add", "local.txt")
self.git(local, "commit", "-m", "local")
self.git(local, "remote", "add", "origin", str(remote))
os.chdir(local)
self.assertTrue(self.app.sync_origin_repository())
self.assertEqual(
self.git(remote, "rev-parse", "refs/heads/main"),
self.git(local, "rev-parse", "HEAD"),
)
def test_sync_populates_unborn_local_repository_from_remote(self) -> None:
remote = self.root / "remote.git"
seed = self.root / "seed"
local = self.root / "local"
remote.mkdir()
self.git(remote, "init", "--bare")
self.git(remote, "symbolic-ref", "HEAD", "refs/heads/main")
self.init_worktree(seed)
(seed / "remote.txt").write_text("remote\n", encoding="utf-8")
self.git(seed, "add", "remote.txt")
self.git(seed, "commit", "-m", "remote")
self.git(seed, "remote", "add", "origin", str(remote))
self.git(seed, "push", "origin", "main")
self.init_worktree(local)
self.git(local, "remote", "add", "origin", str(remote))
os.chdir(local)
self.assertTrue(self.app.sync_origin_repository())
self.assertEqual((local / "remote.txt").read_text(), "remote\n")
self.assertEqual(
self.git(local, "rev-parse", "HEAD"),
self.git(remote, "rev-parse", "refs/heads/main"),
)
def test_sync_merges_diverged_histories_and_pushes_result(self) -> None:
remote = self.root / "remote.git"
seed = self.root / "seed"
local = self.root / "local"
remote.mkdir()
self.git(remote, "init", "--bare")
self.git(remote, "symbolic-ref", "HEAD", "refs/heads/main")
self.init_worktree(seed)
(seed / "remote.txt").write_text("remote\n", encoding="utf-8")
self.git(seed, "add", "remote.txt")
self.git(seed, "commit", "-m", "remote")
self.git(seed, "remote", "add", "origin", str(remote))
self.git(seed, "push", "origin", "main")
self.init_worktree(local)
(local / "local.txt").write_text("local\n", encoding="utf-8")
self.git(local, "add", "local.txt")
self.git(local, "commit", "-m", "local")
self.git(local, "remote", "add", "origin", str(remote))
self.app.select_option_menu = lambda *_args: "merge"
os.chdir(local)
self.assertTrue(self.app.sync_origin_repository())
self.assertTrue((local / "local.txt").exists())
self.assertTrue((local / "remote.txt").exists())
self.assertEqual(
self.git(local, "rev-parse", "HEAD"),
self.git(remote, "rev-parse", "refs/heads/main"),
)
class GiteaPublishTests(unittest.TestCase):
def test_created_repository_can_keep_ssh_origin(self) -> None:
app = git_tui.GitTuiApp.__new__(git_tui.GitTuiApp)
app.status_message = ""
prompt_values = iter(["owner/project", "https://git.example.com"])
app.prompt_input = lambda *_args: next(prompt_values)
app.select_gitea_transport = lambda: "ssh"
app.select_repository_visibility = lambda: False
app.create_gitea_repository = lambda **_kwargs: (
True,
{
"clone_url": "https://git.example.com/owner/project.git",
"ssh_url": "git@git.example.com:owner/project.git",
"full_name": "owner/project",
},
"",
)
configured_urls = []
app.configure_origin_remote = lambda url: configured_urls.append(url) or True
app.push_head_to_remote_branch = lambda *_args, **_kwargs: True
app.current_local_branch = lambda: "main"
app.show_output = lambda *_args: None
with mock.patch.dict(os.environ, {"GITEA_TOKEN": "token"}, clear=False):
self.assertTrue(app.publish_gitea_repository())
self.assertEqual(
configured_urls,
["git@git.example.com:owner/project.git"],
)
class MainMenuTests(unittest.TestCase):
def test_remote_operations_and_disconnect_require_a_remote(self) -> None:
app = git_tui.GitTuiApp.__new__(git_tui.GitTuiApp)
app.has_any_remote = lambda: False
action_names = [action for _, action in app.main_menu_items()]
self.assertNotIn("push", action_names)
self.assertNotIn("pull", action_names)
self.assertNotIn("fetch", action_names)
self.assertNotIn("disconnect_remote", action_names)
def test_disconnect_is_available_when_a_remote_exists(self) -> None:
app = git_tui.GitTuiApp.__new__(git_tui.GitTuiApp)
app.has_any_remote = lambda: True
action_names = [action for _, action in app.main_menu_items()]
self.assertIn("push", action_names)
self.assertIn("pull", action_names)
self.assertIn("fetch", action_names)
self.assertIn("disconnect_remote", action_names)
if __name__ == "__main__":
unittest.main()