feat: comprehensive test infrastructure improvements
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m26s
Run Tests / Backend Tests (push) Failing after 2m36s
Run Tests / Frontend Tests (push) Failing after 2m23s
Run Tests / Test Summary (push) Failing after 13s

- Fix unit test imports: add env setup in conftest.py before module imports
- Add 24 new auth router tests (RBAC, preferences, password validation)
- Add 16 new tests for litellm and chat_summary routers
- Apply black formatting and ruff linting across codebase
- Add pre-commit hooks configuration (black, ruff, file checks)
- Increase CI coverage threshold from 40% to 50%

Test Results:
- 206 tests passing (91 unit + 115 integration)
- Coverage: 58.79% on core modules
- auth.py: 57% → 85%, litellm.py: 23% → 87%, chat_summary.py: 41% → 100%
- auth_service: 96.51%, config: 100%, rbac: 93.48%
This commit is contained in:
Gan, Jimmy
2026-04-08 00:21:32 +08:00
parent fcc95ac23f
commit b981c06d59
44 changed files with 1732 additions and 924 deletions
@@ -1,9 +1,11 @@
"""
Integration tests for system operations.
"""
import pytest
import os
from unittest.mock import patch, Mock
from unittest.mock import Mock, patch
import pytest
class TestSystemStats:
@@ -17,7 +19,7 @@ class TestSystemStats:
mock_disk.used = 500000000000
mock_disk.free = 500000000000
with patch('shutil.disk_usage', return_value=mock_disk):
with patch("shutil.disk_usage", return_value=mock_disk):
response = test_app.get("/api/system/stats", headers=admin_headers)
assert response.status_code == 200
@@ -81,11 +83,7 @@ class TestAuditLog:
def test_get_audit_log_with_limit(self, test_app, admin_headers, temp_volume_root):
"""Test getting audit log with line limit."""
response = test_app.get(
"/api/system/audit-log",
headers=admin_headers,
params={"lines": 50}
)
response = test_app.get("/api/system/audit-log", headers=admin_headers, params={"lines": 50})
assert response.status_code == 200
data = response.json()
@@ -104,22 +102,14 @@ class TestNotification:
@pytest.mark.skip(reason="Requires Telegram bot token and makes external API call")
def test_send_notification_success(self, test_app, admin_headers):
"""Test sending a notification."""
response = test_app.post(
"/api/system/notify",
headers=admin_headers,
json={"message": "Test notification"}
)
response = test_app.post("/api/system/notify", headers=admin_headers, json={"message": "Test notification"})
# This will fail without proper Telegram config
assert response.status_code in [200, 400]
def test_send_notification_without_message(self, test_app, admin_headers):
"""Test sending notification without message."""
response = test_app.post(
"/api/system/notify",
headers=admin_headers,
json={}
)
response = test_app.post("/api/system/notify", headers=admin_headers, json={})
assert response.status_code == 200
data = response.json()
@@ -127,10 +117,7 @@ class TestNotification:
def test_send_notification_without_auth(self, test_app):
"""Test sending notification without authentication."""
response = test_app.post(
"/api/system/notify",
json={"message": "Test"}
)
response = test_app.post("/api/system/notify", json={"message": "Test"})
assert response.status_code == 401
@@ -140,6 +127,7 @@ class TestOpenClawToken:
def test_get_openclaw_token_as_admin(self, test_app, admin_headers, mock_config, monkeypatch):
"""Test getting OpenClaw token as admin from LAN."""
# Mock the IP check to return a LAN IP
def mock_get_client_ip(request):
return "192.168.1.100"
@@ -148,6 +136,7 @@ class TestOpenClawToken:
return True
import config
monkeypatch.setattr(config, "get_client_ip", mock_get_client_ip)
monkeypatch.setattr(config, "is_lan_ip", mock_is_lan_ip)
@@ -159,6 +148,7 @@ class TestOpenClawToken:
def test_get_openclaw_token_non_lan(self, test_app, admin_headers, monkeypatch):
"""Test getting OpenClaw token from non-LAN IP."""
# Mock the IP check to return a non-LAN IP
def mock_get_client_ip(request):
return "1.2.3.4"
@@ -167,6 +157,7 @@ class TestOpenClawToken:
return False
import config
monkeypatch.setattr(config, "get_client_ip", mock_get_client_ip)
monkeypatch.setattr(config, "is_lan_ip", mock_is_lan_ip)
@@ -176,12 +167,12 @@ class TestOpenClawToken:
def test_get_openclaw_token_as_member(self, test_app, mock_config, temp_auth_file, temp_rbac_file):
"""Test that non-admin cannot get OpenClaw token."""
from auth_service import create_access_token
from datetime import timedelta
from auth_service import create_access_token
member_token = create_access_token(
data={"sub": "memberuser", "role": "member"},
expires_delta=timedelta(minutes=30)
data={"sub": "memberuser", "role": "member"}, expires_delta=timedelta(minutes=30)
)
headers = {"Authorization": f"Bearer {member_token}"}