test: final 6 agents — 172+ translate tests, llm_analysis 89%, git_plugin 100%, migration/deps/routes polished. 85-94% files pushed to 95%+. Bulk: backup/debug/maintenance plugins

This commit is contained in:
2026-06-15 22:04:40 +03:00
parent 010edfcfdc
commit fd27569488
35 changed files with 7811 additions and 49 deletions

View File

@@ -0,0 +1,238 @@
# #region Test.DebugPlugin [C:3] [TYPE Module] [SEMANTICS test, debug, plugin, coverage]
# @BRIEF Unit tests for DebugPlugin — properties, get_schema, execute, and edge cases.
# @RELATION BINDS_TO -> [DebugPlugin]
# @TEST_EDGE: unknown_action -> Raises ValueError
# @TEST_EDGE: missing_source_target_env -> Raises ValueError
# @TEST_EDGE: missing_env_dataset_id -> Raises ValueError
# @TEST_EDGE: env_not_found -> Raises ValueError
import pytest
from unittest.mock import AsyncMock, MagicMock, patch, PropertyMock
from src.plugins.debug import DebugPlugin
# ── Helpers ──
def _make_env(id_val="env-1", name="Test Env"):
env = MagicMock()
env.id = id_val
env.name = name
return env
def _make_task_context():
ctx = MagicMock()
ctx.logger = MagicMock()
ctx.logger.with_source.return_value = MagicMock()
return ctx
class TestDebugPluginProperties:
"""Verify static property values."""
def test_id(self):
plugin = DebugPlugin()
assert plugin.id == "system-debug"
def test_name(self):
plugin = DebugPlugin()
assert plugin.name == "System Debug"
def test_description(self):
plugin = DebugPlugin()
assert plugin.description == "Run system diagnostics and debug Superset API responses."
def test_version(self):
plugin = DebugPlugin()
assert plugin.version == "1.0.0"
def test_ui_route(self):
plugin = DebugPlugin()
assert plugin.ui_route == "/tools/debug"
class TestDebugPluginGetSchema:
"""Verify get_schema returns correct structure."""
def test_get_schema(self):
plugin = DebugPlugin()
schema = plugin.get_schema()
assert schema["type"] == "object"
assert "action" in schema["properties"]
assert schema["properties"]["action"]["enum"] == ["test-db-api", "get-dataset-structure"]
assert "action" in schema["required"]
class TestDebugPluginExecute:
"""Verify DebugPlugin.execute with various actions."""
# ── Unknown action → ValueError ──
@pytest.mark.asyncio
async def test_execute_unknown_action(self):
"""Unknown action raises ValueError."""
plugin = DebugPlugin()
with pytest.raises(ValueError, match="Unknown action: bogus"):
await plugin.execute({"action": "bogus"})
@pytest.mark.asyncio
async def test_execute_unknown_action_with_ctx(self):
"""Unknown action raises ValueError even with context."""
plugin = DebugPlugin()
ctx = _make_task_context()
with pytest.raises(ValueError, match="Unknown action: bogus"):
await plugin.execute({"action": "bogus"}, context=ctx)
# ── test-db-api: missing source/target ──
@pytest.mark.asyncio
async def test_execute_test_db_api_missing_params(self):
"""test-db-api without source_env/target_env raises ValueError."""
plugin = DebugPlugin()
with pytest.raises(ValueError, match="source_env and target_env are required"):
await plugin.execute({"action": "test-db-api", "source_env": "src"})
@pytest.mark.asyncio
async def test_execute_test_db_api_no_params(self):
"""test-db-api without any params raises ValueError."""
plugin = DebugPlugin()
with pytest.raises(ValueError, match="source_env and target_env are required"):
await plugin.execute({"action": "test-db-api"})
# ── test-db-api: env not found ──
@pytest.mark.asyncio
async def test_execute_test_db_api_env_not_found(self):
"""test-db-api with non-existent env raises ValueError."""
plugin = DebugPlugin()
mock_cm = MagicMock()
mock_cm.get_environment.return_value = None
with patch('src.dependencies.get_config_manager', return_value=mock_cm):
with pytest.raises(ValueError, match="not found"):
await plugin.execute({
"action": "test-db-api",
"source_env": "NonExistent",
"target_env": "AlsoMissing",
})
# ── test-db-api: happy path ──
@pytest.mark.asyncio
async def test_execute_test_db_api_success(self):
"""test-db-api completes successfully with both envs."""
plugin = DebugPlugin()
src_env = _make_env("src-id", "Source")
tgt_env = _make_env("tgt-id", "Target")
mock_cm = MagicMock()
mock_cm.get_environment.side_effect = [src_env, tgt_env]
mock_client = MagicMock()
mock_client.authenticate = AsyncMock()
mock_client.get_databases = AsyncMock(return_value=(3, [{"id": 1, "name": "db1"}]))
with patch('src.dependencies.get_config_manager', return_value=mock_cm), \
patch('src.plugins.debug.get_superset_client') as mock_get_client:
mock_get_client.side_effect = [mock_client, mock_client]
result = await plugin.execute({
"action": "test-db-api",
"source_env": "Source",
"target_env": "Target",
})
assert "Source" in result
assert "Target" in result
assert result["Source"]["count"] == 3
assert result["Target"]["count"] == 3
# ── get-dataset-structure: missing params ──
@pytest.mark.asyncio
async def test_execute_get_dataset_structure_missing_env(self):
"""get-dataset-structure without env raises ValueError."""
plugin = DebugPlugin()
with pytest.raises(ValueError, match="env and dataset_id are required"):
await plugin.execute({"action": "get-dataset-structure", "dataset_id": 42})
@pytest.mark.asyncio
async def test_execute_get_dataset_structure_missing_dataset_id(self):
"""get-dataset-structure without dataset_id raises ValueError."""
plugin = DebugPlugin()
with pytest.raises(ValueError, match="env and dataset_id are required"):
await plugin.execute({"action": "get-dataset-structure", "env": "Dev"})
# ── get-dataset-structure: env not found ──
@pytest.mark.asyncio
async def test_execute_get_dataset_structure_env_not_found(self):
"""get-dataset-structure with non-existent env raises ValueError."""
plugin = DebugPlugin()
mock_cm = MagicMock()
mock_cm.get_environment.return_value = None
with patch('src.dependencies.get_config_manager', return_value=mock_cm):
with pytest.raises(ValueError, match="not found"):
await plugin.execute({
"action": "get-dataset-structure",
"env": "Missing",
"dataset_id": 1,
})
# ── get-dataset-structure: happy path ──
@pytest.mark.asyncio
async def test_execute_get_dataset_structure_success(self):
"""get-dataset-structure returns dataset result."""
plugin = DebugPlugin()
env = _make_env("dev-id", "Dev")
mock_cm = MagicMock()
mock_cm.get_environment.return_value = env
mock_client = MagicMock()
mock_client.authenticate = AsyncMock()
mock_client.get_dataset = AsyncMock(return_value={
"result": {"id": 42, "table_name": "my_table"},
})
with patch('src.dependencies.get_config_manager', return_value=mock_cm), \
patch('src.plugins.debug.get_superset_client') as mock_get_client:
mock_get_client.return_value = mock_client
result = await plugin.execute({
"action": "get-dataset-structure",
"env": "Dev",
"dataset_id": 42,
})
assert result == {"id": 42, "table_name": "my_table"}
# ── get-dataset-structure: empty result ──
@pytest.mark.asyncio
async def test_execute_get_dataset_structure_empty_result(self):
"""get-dataset-structure returns empty dict when result field is missing."""
plugin = DebugPlugin()
env = _make_env("dev-id", "Dev")
mock_cm = MagicMock()
mock_cm.get_environment.return_value = env
mock_client = MagicMock()
mock_client.authenticate = AsyncMock()
mock_client.get_dataset = AsyncMock(return_value={"some_other_key": "value"})
with patch('src.dependencies.get_config_manager', return_value=mock_cm), \
patch('src.plugins.debug.get_superset_client') as mock_get_client:
mock_get_client.return_value = mock_client
result = await plugin.execute({
"action": "get-dataset-structure",
"env": "Dev",
"dataset_id": 99,
})
assert result == {}