feat: add comprehensive testing mechanism for dashboard features
Deploy Dashboard (Dev) / deploy-dev (push) Failing after 2m0s
Run Tests / Backend Tests (push) Failing after 4m26s
Run Tests / Frontend Tests (push) Failing after 49s
Run Tests / Test Summary (push) Failing after 15s
Run Tests / Backend Tests (pull_request) Failing after 6m9s
Run Tests / Frontend Tests (pull_request) Failing after 3m54s
Run Tests / Test Summary (pull_request) Failing after 15s
Deploy Dashboard (Dev) / deploy-dev (push) Failing after 2m0s
Run Tests / Backend Tests (push) Failing after 4m26s
Run Tests / Frontend Tests (push) Failing after 49s
Run Tests / Test Summary (push) Failing after 15s
Run Tests / Backend Tests (pull_request) Failing after 6m9s
Run Tests / Frontend Tests (pull_request) Failing after 3m54s
Run Tests / Test Summary (pull_request) Failing after 15s
- Add smoke test script for post-deployment verification - Add health monitoring script with Telegram alerts - Add backend integration tests for conversation tracker API - Add frontend tests to verify correct API paths - Update CI/CD workflows to enforce test failures and run smoke tests - Add comprehensive testing documentation This testing mechanism will catch issues like the double /api/ prefix bug before they reach users.
This commit is contained in:
@@ -287,3 +287,64 @@ def mock_request():
|
||||
request.client.host = "192.168.31.100"
|
||||
request.headers = {}
|
||||
return request
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_conversation_db(tmp_path, monkeypatch):
|
||||
"""Mock conversation tracker database"""
|
||||
import sqlite3
|
||||
|
||||
db_path = tmp_path / "conversations.db"
|
||||
|
||||
# Create minimal SQLite schema
|
||||
conn = sqlite3.connect(db_path)
|
||||
conn.execute("""
|
||||
CREATE TABLE conversations (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
project_path TEXT,
|
||||
started_at DATETIME,
|
||||
message_count INTEGER,
|
||||
total_input_tokens INTEGER DEFAULT 0,
|
||||
total_output_tokens INTEGER DEFAULT 0
|
||||
)
|
||||
""")
|
||||
conn.execute("""
|
||||
CREATE TABLE messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
message_uuid TEXT UNIQUE NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
content_text TEXT,
|
||||
timestamp DATETIME NOT NULL
|
||||
)
|
||||
""")
|
||||
conn.execute("""
|
||||
CREATE TABLE tool_calls (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
message_uuid TEXT NOT NULL,
|
||||
tool_name TEXT NOT NULL,
|
||||
timestamp DATETIME NOT NULL
|
||||
)
|
||||
""")
|
||||
conn.execute("""
|
||||
CREATE TABLE daily_summaries (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
date TEXT UNIQUE NOT NULL,
|
||||
summary_content TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
|
||||
# Insert test data
|
||||
conn.execute("""
|
||||
INSERT INTO conversations VALUES
|
||||
('test-session-id', '/test/project', '2026-04-19 10:00:00', 10, 1000, 500)
|
||||
""")
|
||||
conn.execute("""
|
||||
INSERT INTO messages VALUES
|
||||
(1, 'test-session-id', 'msg-1', 'user', 'test message', '2026-04-19 10:00:00')
|
||||
""")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
monkeypatch.setenv("CONVERSATION_TRACKER_DB", str(db_path))
|
||||
return db_path
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
class TestConversationTrackerAPI:
|
||||
"""Test conversation tracker endpoints"""
|
||||
|
||||
def test_list_dates_requires_auth(self, test_app):
|
||||
"""Verify dates endpoint requires authentication"""
|
||||
response = test_app.get("/api/conversations/dates")
|
||||
assert response.status_code == 401
|
||||
assert "Not authenticated" in response.json()["detail"]
|
||||
|
||||
def test_list_dates_with_auth(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Verify dates endpoint returns data with auth"""
|
||||
response = test_app.get("/api/conversations/dates", headers=admin_headers)
|
||||
assert response.status_code == 200
|
||||
assert isinstance(response.json(), list)
|
||||
|
||||
def test_get_summary_not_found(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test daily summary endpoint returns 404 when no summary exists"""
|
||||
response = test_app.get("/api/conversations/summary/2026-04-19", headers=admin_headers)
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_list_conversations(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test conversation list endpoint"""
|
||||
response = test_app.get("/api/conversations/list?date=2026-04-19", headers=admin_headers)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
if len(data) > 0:
|
||||
assert "session_id" in data[0]
|
||||
assert "project_path" in data[0]
|
||||
|
||||
def test_list_conversations_requires_auth(self, test_app):
|
||||
"""Test conversation list requires authentication"""
|
||||
response = test_app.get("/api/conversations/list?date=2026-04-19")
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_get_conversation_detail(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test conversation detail endpoint"""
|
||||
response = test_app.get("/api/conversations/test-session-id", headers=admin_headers)
|
||||
assert response.status_code in [200, 404]
|
||||
|
||||
def test_get_conversation_messages(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test conversation messages endpoint"""
|
||||
response = test_app.get("/api/conversations/test-session-id/messages", headers=admin_headers)
|
||||
assert response.status_code in [200, 404]
|
||||
|
||||
def test_search_conversations(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test search endpoint"""
|
||||
response = test_app.get("/api/conversations/search?q=test", headers=admin_headers)
|
||||
assert response.status_code == 200
|
||||
assert isinstance(response.json(), list)
|
||||
|
||||
def test_search_requires_query(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test search requires query parameter"""
|
||||
response = test_app.get("/api/conversations/search", headers=admin_headers)
|
||||
# Should handle missing query gracefully
|
||||
assert response.status_code in [200, 400, 422]
|
||||
|
||||
def test_get_stats(self, test_app, admin_headers, mock_conversation_db):
|
||||
"""Test stats endpoint"""
|
||||
response = test_app.get("/api/conversations/stats", headers=admin_headers)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "top_projects" in data
|
||||
assert "top_tools" in data
|
||||
assert isinstance(data["top_projects"], list)
|
||||
assert isinstance(data["top_tools"], list)
|
||||
|
||||
def test_trigger_summary_requires_auth(self, test_app):
|
||||
"""Test trigger endpoint requires authentication"""
|
||||
response = test_app.post("/api/conversations/trigger")
|
||||
assert response.status_code == 401
|
||||
|
||||
def test_api_prefix_correct(self, test_app, admin_headers):
|
||||
"""Test that API paths don't have double /api/ prefix"""
|
||||
# This should be 404, not a valid endpoint
|
||||
response = test_app.get("/api/api/conversations/dates", headers=admin_headers)
|
||||
assert response.status_code == 404
|
||||
Reference in New Issue
Block a user