79 lines
2.7 KiB
Python
79 lines
2.7 KiB
Python
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.services.git_service import GitService
|
|
|
|
|
|
def run_git(cwd: Path, *args: str) -> str:
|
|
result = subprocess.run(["git", *args], cwd=cwd, capture_output=True, text=True, check=True)
|
|
return result.stdout.strip()
|
|
|
|
|
|
def commit_file(cwd: Path, relative_path: str, content: str, message: str) -> None:
|
|
target = cwd / relative_path
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text(content, encoding="utf-8")
|
|
run_git(cwd, "add", ".")
|
|
run_git(cwd, "-c", "user.name=Test", "-c", "user.email=test@example.com", "commit", "-m", message)
|
|
|
|
|
|
@pytest.fixture
|
|
def git_fixture(tmp_path: Path):
|
|
remote = tmp_path / "remote.git"
|
|
local = tmp_path / "local"
|
|
seed = tmp_path / "seed"
|
|
remote.mkdir()
|
|
local.mkdir()
|
|
seed.mkdir()
|
|
run_git(remote, "init", "--bare", "-b", "main")
|
|
run_git(seed, "init", "-b", "main")
|
|
commit_file(seed, "docs/one.md", "one", "initial")
|
|
commit_file(seed, "other.txt", "other", "other")
|
|
run_git(seed, "remote", "add", "origin", str(remote))
|
|
run_git(seed, "push", "-u", "origin", "main")
|
|
run_git(local, "clone", "-b", "main", str(remote), ".")
|
|
return remote, local, seed
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_directory_push_only_changes_selected_directory(git_fixture):
|
|
remote, local, _ = git_fixture
|
|
service = GitService()
|
|
(local / "docs/one.md").write_text("updated", encoding="utf-8")
|
|
(local / "other.txt").write_text("local-only", encoding="utf-8")
|
|
|
|
ok, message = await service.push(local, str(remote), sub_path="docs")
|
|
|
|
assert ok, message
|
|
assert run_git(local, "remote", "get-url", "origin") == str(remote)
|
|
check = Path(local.parent / "check")
|
|
run_git(local.parent, "clone", "-b", "main", str(remote), str(check))
|
|
assert (check / "docs/one.md").read_text(encoding="utf-8") == "updated"
|
|
assert (check / "other.txt").read_text(encoding="utf-8") == "other"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_whole_push_rejects_remote_ahead(git_fixture):
|
|
remote, local, seed = git_fixture
|
|
service = GitService()
|
|
commit_file(seed, "other.txt", "remote-update", "remote update")
|
|
run_git(seed, "push", "origin", "main")
|
|
(local / "docs/one.md").write_text("local-update", encoding="utf-8")
|
|
|
|
ok, message = await service.push(local, str(remote))
|
|
|
|
assert not ok
|
|
assert "先执行整库拉取" in message
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_credentials_are_not_written_to_remote_url(git_fixture):
|
|
remote, local, _ = git_fixture
|
|
service = GitService()
|
|
ok, message = await service.pull(local, str(remote), username="user", token="secret")
|
|
|
|
assert ok, message
|
|
assert "secret" not in run_git(local, "remote", "get-url", "origin")
|