This commit is contained in:
2026-03-04 19:33:47 +03:00
parent 42def69dcc
commit 2820e491d5
28 changed files with 972 additions and 365 deletions

View File

@@ -2,7 +2,8 @@ import sys
from pathlib import Path
import shutil
import pytest
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
from git.exc import InvalidGitRepositoryError
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
@@ -39,3 +40,76 @@ def test_superset_client_import_dashboard_guard():
client = SupersetClient(mock_env)
with pytest.raises(ValueError, match="file_name cannot be None"):
client.import_dashboard(None)
def test_git_service_init_repo_reclones_when_path_is_not_a_git_repo():
"""Verify init_repo reclones when target path exists but is not a valid Git repository."""
service = GitService(base_path="test_repos_invalid_repo")
target_path = Path(service.base_path) / "covid"
target_path.mkdir(parents=True, exist_ok=True)
(target_path / "placeholder.txt").write_text("not a git repo", encoding="utf-8")
clone_result = MagicMock()
with patch("src.services.git_service.Repo") as repo_ctor:
repo_ctor.side_effect = InvalidGitRepositoryError("invalid repo")
repo_ctor.clone_from.return_value = clone_result
result = service.init_repo(10, "https://example.com/org/repo.git", "token", repo_key="covid")
assert result is clone_result
repo_ctor.assert_called_once_with(str(target_path))
repo_ctor.clone_from.assert_called_once()
assert not target_path.exists()
def test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults():
"""Verify _ensure_gitflow_branches creates dev/preprod locally and pushes them to origin."""
service = GitService(base_path="test_repos_gitflow_defaults")
class FakeRemoteRef:
def __init__(self, remote_head):
self.remote_head = remote_head
class FakeHead:
def __init__(self, name, commit):
self.name = name
self.commit = commit
class FakeOrigin:
def __init__(self):
self.refs = [FakeRemoteRef("main")]
self.pushed = []
def fetch(self):
return []
def push(self, refspec=None):
self.pushed.append(refspec)
return []
class FakeHeadPointer:
def __init__(self, commit):
self.commit = commit
class FakeRepo:
def __init__(self):
self.head = FakeHeadPointer("main-commit")
self.heads = [FakeHead("main", "main-commit")]
self.origin = FakeOrigin()
def create_head(self, name, commit):
head = FakeHead(name, commit)
self.heads.append(head)
return head
def remote(self, name="origin"):
if name != "origin":
raise ValueError("unknown remote")
return self.origin
repo = FakeRepo()
service._ensure_gitflow_branches(repo, dashboard_id=10)
local_branch_names = {head.name for head in repo.heads}
assert {"main", "dev", "preprod"}.issubset(local_branch_names)
assert "dev:dev" in repo.origin.pushed
assert "preprod:preprod" in repo.origin.pushed

View File

@@ -11,6 +11,7 @@ import sys
from pathlib import Path
from fastapi import HTTPException
import pytest
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
@@ -64,4 +65,40 @@ def test_create_gitea_pull_request_retries_with_remote_host_on_404(monkeypatch):
assert calls[1][1] == "https://giteabusya.bebesh.ru"
# [/DEF:test_create_gitea_pull_request_retries_with_remote_host_on_404:Function]
# [DEF:test_create_gitea_pull_request_returns_branch_error_when_target_missing:Function]
# @PURPOSE: Ensure Gitea 404 on PR creation is mapped to actionable target-branch validation error.
# @PRE: PR create call returns 404 and target branch is absent.
# @POST: Service raises HTTPException 400 with explicit missing target branch message.
def test_create_gitea_pull_request_returns_branch_error_when_target_missing(monkeypatch):
service = GitService(base_path="test_repos")
async def fake_gitea_request(method, server_url, pat, endpoint, payload=None):
if method == "POST" and endpoint.endswith("/pulls"):
raise HTTPException(status_code=404, detail="Gitea API error: The target couldn't be found.")
if method == "GET" and endpoint.endswith("/branches/dev"):
return {"name": "dev"}
if method == "GET" and endpoint.endswith("/branches/preprod"):
raise HTTPException(status_code=404, detail="branch not found")
raise AssertionError(f"Unexpected request: {method} {endpoint}")
monkeypatch.setattr(service, "_gitea_request", fake_gitea_request)
with pytest.raises(HTTPException) as exc_info:
asyncio.run(
service.create_gitea_pull_request(
server_url="https://gitea.bebesh.ru",
pat="secret",
remote_url="https://gitea.bebesh.ru/busya/covid-vaccine-dashboard.git",
from_branch="dev",
to_branch="preprod",
title="Promote dev -> preprod",
description="",
)
)
assert exc_info.value.status_code == 400
assert "target branch 'preprod'" in str(exc_info.value.detail)
# [/DEF:test_create_gitea_pull_request_returns_branch_error_when_target_missing:Function]
# [/DEF:backend.tests.core.test_git_service_gitea_pr:Module]