101 lines
4.0 KiB
Python
101 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from codexpi.commands import CommandResult
|
|
from codexpi.github_service import (
|
|
GitHubError,
|
|
connect_repository,
|
|
generate_key,
|
|
ssh_environment,
|
|
status,
|
|
test_connection as verify_connection,
|
|
validate_repository_url,
|
|
)
|
|
|
|
|
|
def test_github_key_is_generated_with_private_permissions(tmp_path: Path):
|
|
value = generate_key(tmp_path)
|
|
key = tmp_path / "github" / "id_ed25519"
|
|
assert value["key_ready"] is True
|
|
assert value["public_key"].startswith("ssh-ed25519 ")
|
|
assert key.stat().st_mode & 0o777 == 0o600
|
|
assert "IdentitiesOnly=yes" in ssh_environment(tmp_path)["GIT_SSH_COMMAND"]
|
|
|
|
|
|
def test_github_repository_url_only_accepts_github_ssh():
|
|
assert validate_repository_url("git@github.com:openai/codex.git") == "git@github.com:openai/codex.git"
|
|
assert validate_repository_url("ssh://git@github.com/openai/codex.git").startswith("ssh://")
|
|
for value in ("https://github.com/openai/codex.git", "git@example.com:openai/codex.git", "-bad"):
|
|
with pytest.raises(GitHubError):
|
|
validate_repository_url(value)
|
|
|
|
|
|
def test_github_connection_recognizes_authenticated_account(tmp_path: Path, monkeypatch):
|
|
generate_key(tmp_path)
|
|
|
|
async def fake_command(*_args, **_kwargs):
|
|
return CommandResult([], 1, "", "Hi octocat! You've successfully authenticated, but GitHub does not provide shell access.")
|
|
|
|
monkeypatch.setattr("codexpi.github_service.run_command", fake_command)
|
|
value = asyncio.run(verify_connection(tmp_path))
|
|
assert value["account"] == "octocat"
|
|
assert status(tmp_path)["account"] == "octocat"
|
|
|
|
|
|
def test_connect_repository_initializes_git_and_sets_origin(tmp_path: Path, monkeypatch):
|
|
data = tmp_path / "data"
|
|
generate_key(data)
|
|
repo = tmp_path / "repo"
|
|
repo.mkdir()
|
|
|
|
async def fake_command(*_args, **_kwargs):
|
|
return CommandResult([], 0, "", "")
|
|
|
|
monkeypatch.setattr("codexpi.github_service.run_command", fake_command)
|
|
value = asyncio.run(connect_repository(repo, data, "git@github.com:octocat/demo.git"))
|
|
remote = subprocess.run(["git", "remote", "get-url", "origin"], cwd=repo, check=True, capture_output=True, text=True)
|
|
assert value["is_repository"] is True
|
|
assert remote.stdout.strip() == "git@github.com:octocat/demo.git"
|
|
|
|
|
|
def test_connect_repository_does_not_mix_an_existing_remote_history(tmp_path: Path, monkeypatch):
|
|
data = tmp_path / "data"
|
|
generate_key(data)
|
|
repo = tmp_path / "plain-project"
|
|
repo.mkdir()
|
|
|
|
async def fake_command(*_args, **_kwargs):
|
|
return CommandResult([], 0, "abc123\trefs/heads/main\n", "")
|
|
|
|
monkeypatch.setattr("codexpi.github_service.run_command", fake_command)
|
|
with pytest.raises(GitHubError, match="possède déjà un historique"):
|
|
asyncio.run(connect_repository(repo, data, "git@github.com:octocat/demo.git"))
|
|
assert not (repo / ".git").exists()
|
|
|
|
|
|
def test_github_endpoints_require_csrf_and_connect_project(logged_in, monkeypatch):
|
|
client, app, projects, _, headers = logged_in
|
|
repo = projects / "github-project"
|
|
repo.mkdir()
|
|
project = client.post("/api/projects", headers=headers, json={"name": "GitHub", "path": str(repo)}).json()
|
|
monkeypatch.setattr("codexpi.main.generate_github_key", lambda _data: {"key_ready": True, "public_key": "ssh-ed25519 test", "account": None, "verified_at": None})
|
|
|
|
async def fake_connect(root, _data, url):
|
|
return {"is_repository": True, "remote_url": url, "branch": "main", "files": [], "history": []}
|
|
|
|
monkeypatch.setattr("codexpi.main.connect_repository", fake_connect)
|
|
assert client.post("/api/github/key").status_code == 403
|
|
assert client.post("/api/github/key", headers=headers).json()["key_ready"] is True
|
|
response = client.post(
|
|
f"/api/projects/{project['id']}/github",
|
|
headers=headers,
|
|
json={"repository_url": "git@github.com:octocat/demo.git"},
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["remote_url"] == "git@github.com:octocat/demo.git"
|