fix: 5 agents — core 703/703, settings 38/38, git edges 191/191, API routes 1139/1140, plugins +70 coverage
This commit is contained in:
@@ -6,7 +6,8 @@ import sys
|
||||
from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src"))
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
import contextlib
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
@@ -18,21 +19,21 @@ class TestPushChanges:
|
||||
async def test_no_branches(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.heads = []
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
await mixin.push_changes(1) # should not raise
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_origin_remote(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.heads = [MagicMock()]
|
||||
repo.remote.side_effect = ValueError("no origin")
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
with pytest.raises(HTTPException, match="origin"):
|
||||
await mixin.push_changes(1)
|
||||
|
||||
@@ -40,7 +41,7 @@ class TestPushChanges:
|
||||
async def test_no_tracking_branch_sets_upstream(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
mixin._align_origin_host_with_config = MagicMock(return_value=None)
|
||||
repo = MagicMock()
|
||||
repo.heads = [MagicMock()]
|
||||
@@ -51,7 +52,7 @@ class TestPushChanges:
|
||||
current_branch.tracking_branch.return_value = None
|
||||
repo.active_branch = current_branch
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
with patch("src.services.git._sync.SessionLocal") as mock_sl_cls:
|
||||
mock_db = MagicMock()
|
||||
mock_sl_cls.return_value = mock_db
|
||||
@@ -70,7 +71,7 @@ class TestPushChanges:
|
||||
async def test_tracking_branch_push(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
mixin._align_origin_host_with_config = MagicMock(return_value=None)
|
||||
repo = MagicMock()
|
||||
repo.heads = [MagicMock()]
|
||||
@@ -81,7 +82,7 @@ class TestPushChanges:
|
||||
current_branch.tracking_branch.return_value = "origin/main"
|
||||
repo.active_branch = current_branch
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
with patch("src.services.git._sync.SessionLocal") as mock_sl_cls:
|
||||
mock_db = MagicMock()
|
||||
mock_sl_cls.return_value = mock_db
|
||||
@@ -94,7 +95,7 @@ class TestPushChanges:
|
||||
async def test_push_git_command_error_nonfastforward(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
mixin._align_origin_host_with_config = MagicMock(return_value=None)
|
||||
repo = MagicMock()
|
||||
repo.heads = [MagicMock()]
|
||||
@@ -106,7 +107,7 @@ class TestPushChanges:
|
||||
repo.active_branch = current_branch
|
||||
repo.git.push.side_effect = GitCommandError("push", "non-fast-forward")
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
with patch("src.services.git._sync.SessionLocal") as mock_sl_cls:
|
||||
mock_db = MagicMock()
|
||||
mock_sl_cls.return_value = mock_db
|
||||
@@ -118,7 +119,7 @@ class TestPushChanges:
|
||||
async def test_push_generic_exception(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
mixin._align_origin_host_with_config = MagicMock(return_value=None)
|
||||
repo = MagicMock()
|
||||
repo.heads = [MagicMock()]
|
||||
@@ -130,7 +131,7 @@ class TestPushChanges:
|
||||
repo.active_branch = current_branch
|
||||
repo.git.push.side_effect = GitCommandError("push", "some error")
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo):
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo):
|
||||
with patch("src.services.git._sync.SessionLocal") as mock_sl_cls:
|
||||
mock_db = MagicMock()
|
||||
mock_sl_cls.return_value = mock_db
|
||||
@@ -144,15 +145,22 @@ class TestPullChanges:
|
||||
async def test_unfinished_merge_detected(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.git_dir = "/tmp/repo/.git"
|
||||
repo.working_tree_dir = "/tmp/repo"
|
||||
repo.active_branch.name = "main"
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo), \
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo), \
|
||||
patch("os.path.exists", return_value=True), \
|
||||
patch.object(mixin, '_build_unfinished_merge_payload', return_value={"error_code": "GIT_UNFINISHED_MERGE"}):
|
||||
patch.object(mixin, '_build_unfinished_merge_payload', return_value={
|
||||
"repository_path": "/tmp/repo",
|
||||
"git_dir": "/tmp/repo/.git",
|
||||
"current_branch": "main",
|
||||
"merge_head": "abc123",
|
||||
"merge_message_preview": "Merge branch",
|
||||
"conflicts_count": 2,
|
||||
}, create=True):
|
||||
with pytest.raises(HTTPException, match="409"):
|
||||
await mixin.pull_changes(1)
|
||||
|
||||
@@ -160,7 +168,7 @@ class TestPullChanges:
|
||||
async def test_remote_branch_not_found(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.git_dir = "/tmp/repo/.git"
|
||||
repo.working_tree_dir = "/tmp/repo"
|
||||
@@ -171,7 +179,7 @@ class TestPullChanges:
|
||||
repo.remote.return_value = origin
|
||||
repo.refs = []
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo), \
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo), \
|
||||
patch("os.path.exists", return_value=False):
|
||||
with pytest.raises(HTTPException, match="409"):
|
||||
await mixin.pull_changes(1)
|
||||
@@ -180,7 +188,7 @@ class TestPullChanges:
|
||||
async def test_conflict_during_pull(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.git_dir = "/tmp/repo/.git"
|
||||
repo.working_tree_dir = "/tmp/repo"
|
||||
@@ -195,7 +203,7 @@ class TestPullChanges:
|
||||
repo.refs = [ref]
|
||||
repo.git.pull.side_effect = GitCommandError("pull", "conflict")
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo), \
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo), \
|
||||
patch("os.path.exists", return_value=False):
|
||||
with pytest.raises(HTTPException, match="409"):
|
||||
await mixin.pull_changes(1)
|
||||
@@ -204,14 +212,14 @@ class TestPullChanges:
|
||||
async def test_origin_not_found(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.git_dir = "/tmp/repo/.git"
|
||||
repo.working_tree_dir = "/tmp/repo"
|
||||
repo.active_branch.name = "main"
|
||||
repo.remote.side_effect = ValueError
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo), \
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo), \
|
||||
patch("os.path.exists", return_value=False):
|
||||
with pytest.raises(HTTPException, match="origin"):
|
||||
await mixin.pull_changes(1)
|
||||
@@ -220,7 +228,7 @@ class TestPullChanges:
|
||||
async def test_generic_pull_error(self):
|
||||
from src.services.git._sync import GitServiceSyncMixin
|
||||
mixin = GitServiceSyncMixin()
|
||||
mixin._locked = lambda x: (lambda g=None: (yield))()
|
||||
mixin._locked = lambda x: contextlib.nullcontext()
|
||||
repo = MagicMock()
|
||||
repo.git_dir = "/tmp/repo/.git"
|
||||
repo.working_tree_dir = "/tmp/repo"
|
||||
@@ -234,7 +242,7 @@ class TestPullChanges:
|
||||
repo.refs = [ref]
|
||||
repo.git.pull.side_effect = Exception("unknown error")
|
||||
|
||||
with patch.object(mixin, 'get_repo', new_callable=MagicMock, return_value=repo), \
|
||||
with patch.object(mixin, 'get_repo', new_callable=AsyncMock, create=True, return_value=repo), \
|
||||
patch("os.path.exists", return_value=False):
|
||||
with pytest.raises(HTTPException, match="500"):
|
||||
await mixin.pull_changes(1)
|
||||
|
||||
Reference in New Issue
Block a user