feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
127
tests/test_gitlab.py
Normal file
127
tests/test_gitlab.py
Normal file
@@ -0,0 +1,127 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from codexpi.commands import CommandResult
|
||||
from codexpi.gitlab_service import (
|
||||
GitLabError,
|
||||
connect,
|
||||
connect_repository,
|
||||
create_repository,
|
||||
namespaces,
|
||||
normalize_server_url,
|
||||
status,
|
||||
)
|
||||
|
||||
|
||||
def test_gitlab_server_url_requires_safe_explicit_transport():
|
||||
assert normalize_server_url("https://gitlab.local/") == "https://gitlab.local"
|
||||
assert normalize_server_url("http://gitlab.local", True) == "http://gitlab.local"
|
||||
with pytest.raises(GitLabError, match="HTTP"):
|
||||
normalize_server_url("http://gitlab.local")
|
||||
for value in ("gitlab.local", "https://user:password@gitlab.local", "https://gitlab.local/?token=secret"):
|
||||
with pytest.raises(GitLabError):
|
||||
normalize_server_url(value)
|
||||
|
||||
|
||||
def test_gitlab_connection_adds_ssh_key_and_encrypts_token(tmp_path: Path, monkeypatch):
|
||||
calls: list[tuple[str, str, dict | None]] = []
|
||||
|
||||
def fake_request(_config, path, method="GET", payload=None):
|
||||
calls.append((path, method, payload))
|
||||
if path == "user":
|
||||
return {"username": "alice", "name": "Alice"}
|
||||
if path.startswith("user/keys?"):
|
||||
return []
|
||||
return {"id": 42}
|
||||
|
||||
monkeypatch.setattr("codexpi.gitlab_service._request", fake_request)
|
||||
monkeypatch.setattr("codexpi.gitlab_service.generate_key", lambda _data: {"public_key": "ssh-ed25519 AAAATEST codexpi"})
|
||||
value = connect(tmp_path, "application-secret", "https://gitlab.local", "glpat-top-secret")
|
||||
encrypted = (tmp_path / "gitlab" / "connection.json").read_bytes()
|
||||
assert value["configured"] is True
|
||||
assert value["account"] == "alice"
|
||||
assert "token" not in value
|
||||
assert b"glpat-top-secret" not in encrypted
|
||||
assert any(path == "user/keys" and method == "POST" for path, method, _ in calls)
|
||||
|
||||
|
||||
def test_gitlab_does_not_add_an_existing_ssh_key(tmp_path: Path, monkeypatch):
|
||||
calls: list[str] = []
|
||||
|
||||
def fake_request(_config, path, method="GET", payload=None):
|
||||
calls.append(f"{method} {path}")
|
||||
if path == "user":
|
||||
return {"username": "alice"}
|
||||
return [{"key": "ssh-ed25519 AAAATEST another-comment"}]
|
||||
|
||||
monkeypatch.setattr("codexpi.gitlab_service._request", fake_request)
|
||||
monkeypatch.setattr("codexpi.gitlab_service.generate_key", lambda _data: {"public_key": "ssh-ed25519 AAAATEST codexpi"})
|
||||
connect(tmp_path, "secret", "https://gitlab.local", "glpat-example")
|
||||
assert "POST user/keys" not in calls
|
||||
|
||||
|
||||
def test_gitlab_namespaces_and_repository_creation_use_saved_connection(tmp_path: Path, monkeypatch):
|
||||
def connect_request(_config, path, method="GET", payload=None):
|
||||
if path == "user":
|
||||
return {"username": "alice"}
|
||||
if path.startswith("user/keys?"):
|
||||
return [{"key": "ssh-ed25519 AAAATEST"}]
|
||||
raise AssertionError(path)
|
||||
|
||||
monkeypatch.setattr("codexpi.gitlab_service._request", connect_request)
|
||||
monkeypatch.setattr("codexpi.gitlab_service.generate_key", lambda _data: {"public_key": "ssh-ed25519 AAAATEST"})
|
||||
connect(tmp_path, "secret", "https://gitlab.local", "glpat-example")
|
||||
|
||||
def api_request(config, path, method="GET", payload=None):
|
||||
assert config["token"] == "glpat-example"
|
||||
if path.startswith("namespaces?"):
|
||||
return [{"id": 7, "name": "Alice", "full_path": "alice", "kind": "user"}]
|
||||
assert method == "POST" and payload["namespace_id"] == 7
|
||||
return {"id": 9, "name": "Demo", "path_with_namespace": "alice/demo", "visibility": "private", "web_url": "https://gitlab.local/alice/demo", "ssh_url_to_repo": "git@gitlab.local:alice/demo.git"}
|
||||
|
||||
monkeypatch.setattr("codexpi.gitlab_service._request", api_request)
|
||||
assert namespaces(tmp_path, "secret")[0]["full_path"] == "alice"
|
||||
repository = create_repository(tmp_path, "secret", "Demo", "demo", 7, "private")
|
||||
assert repository["ssh_url_to_repo"] == "git@gitlab.local:alice/demo.git"
|
||||
|
||||
|
||||
def test_gitlab_repository_is_initialized_and_linked(tmp_path: Path, monkeypatch):
|
||||
data = tmp_path / "data"
|
||||
key = data / "github" / "id_ed25519"
|
||||
key.parent.mkdir(parents=True)
|
||||
key.write_text("private", encoding="utf-8")
|
||||
root = tmp_path / "project"
|
||||
root.mkdir()
|
||||
|
||||
async def fake_command(*_args, **_kwargs):
|
||||
return CommandResult([], 0, "", "")
|
||||
|
||||
monkeypatch.setattr("codexpi.gitlab_service.run_command", fake_command)
|
||||
value = asyncio.run(connect_repository(root, data, "git@gitlab.local:alice/demo.git"))
|
||||
assert value["is_repository"] is True
|
||||
assert value["remote_url"] == "git@gitlab.local:alice/demo.git"
|
||||
|
||||
|
||||
def test_gitlab_api_connects_and_creates_repository(logged_in, monkeypatch):
|
||||
client, _app, projects, _, headers = logged_in
|
||||
root = projects / "gitlab-project"
|
||||
root.mkdir()
|
||||
project = client.post("/api/projects", headers=headers, json={"name": "GitLab", "path": str(root)}).json()
|
||||
|
||||
monkeypatch.setattr("codexpi.main.connect_gitlab", lambda *_args: {"configured": True, "server_url": "https://gitlab.local", "account": "alice", "name": "Alice", "verified_at": "now", "verify_tls": True})
|
||||
monkeypatch.setattr("codexpi.main.create_gitlab_repository", lambda *_args: {"name": "Demo", "path_with_namespace": "alice/demo", "web_url": "https://gitlab.local/alice/demo", "ssh_url_to_repo": "git@gitlab.local:alice/demo.git"})
|
||||
|
||||
async def fake_link(*_args):
|
||||
return {"is_repository": True, "remote_url": "git@gitlab.local:alice/demo.git"}
|
||||
|
||||
monkeypatch.setattr("codexpi.main.connect_gitlab_repository", fake_link)
|
||||
assert client.post("/api/gitlab/connect", json={"server_url": "https://gitlab.local", "token": "secret"}).status_code == 403
|
||||
connected = client.post("/api/gitlab/connect", headers=headers, json={"server_url": "https://gitlab.local", "token": "secret"})
|
||||
assert connected.status_code == 200
|
||||
created = client.post(f"/api/projects/{project['id']}/gitlab/repositories", headers=headers, json={"name": "Demo", "path": "demo", "namespace_id": 7, "visibility": "private"})
|
||||
assert created.status_code == 201
|
||||
assert created.json()["git"]["remote_url"] == "git@gitlab.local:alice/demo.git"
|
||||
Reference in New Issue
Block a user