Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

454 lines
16 KiB
Python

#!/usr/bin/env python3
"""
Comprehensive test suite that tests ALL API endpoints in the codebase.
This ensures we have coverage for every single endpoint.
"""
import json
import time
import pytest
from loguru import logger
class TestAllEndpoints:
"""Comprehensive API test suite using Flask test client."""
def test_all_auth_endpoints(self, authenticated_client):
"""Test ALL authentication endpoints."""
logger.info("\n=== Testing ALL Authentication Endpoints ===")
# Test endpoints
endpoints = [
("GET", "/auth/check", None, 200),
("GET", "/auth/integrity-check", None, 200),
]
for method, endpoint, data, expected_status in endpoints:
if method == "GET":
response = authenticated_client.get(endpoint)
else:
response = authenticated_client.post(
endpoint,
json=data,
content_type="application/json",
)
assert response.status_code == expected_status, (
f"{endpoint} failed: {response.data}"
)
logger.info("✅ All Auth endpoints tested")
def test_all_settings_endpoints(self, authenticated_client):
"""Test ALL settings endpoints."""
logger.info("\n=== Testing ALL Settings Endpoints ===")
# Basic GET endpoints
get_endpoints = [
"/settings/api",
"/settings/api/categories",
"/settings/api/types",
"/settings/api/ui_elements",
"/settings/api/available-models",
"/settings/api/available-search-engines",
"/settings/api/warnings",
"/settings/api/ollama-status",
"/settings/api/rate-limiting/status",
"/settings/api/data-location",
]
for endpoint in get_endpoints:
response = authenticated_client.get(endpoint)
assert response.status_code == 200, (
f"{endpoint} failed: {response.data}"
)
# Test bulk get
response = authenticated_client.get(
"/settings/api/bulk?keys=llm.provider,llm.model"
)
assert response.status_code == 200, f"Bulk get failed: {response.data}"
# Test setting CRUD (use an allow-listed prefix so the
# namespace gate permits creation of this throwaway key).
test_key = "llm.endpoint_test_value"
test_value = {"value": "test_endpoint_123", "editable": True}
# Create/Update
response = authenticated_client.put(
f"/settings/api/{test_key}",
json=test_value,
content_type="application/json",
)
assert response.status_code in [200, 201], (
f"Create setting failed: {response.data}"
)
# Get specific setting
data = json.loads(response.data)
if isinstance(data, dict) and "setting" in data:
actual_key = data["setting"].get("key", test_key)
else:
actual_key = test_key
response = authenticated_client.get(f"/settings/api/{actual_key}")
assert response.status_code == 200, (
f"Get setting failed: {response.data}"
)
# Delete
response = authenticated_client.delete(f"/settings/api/{actual_key}")
assert response.status_code in [200, 204, 404], (
f"Delete setting failed: {response.data}"
)
# Test rate limiting reset
response = authenticated_client.post(
"/settings/api/rate-limiting/engines/test/reset"
)
assert response.status_code in [200, 404], (
f"Rate limit reset failed: {response.data}"
)
# Test cleanup
response = authenticated_client.post(
"/settings/api/rate-limiting/cleanup"
)
assert response.status_code == 200, (
f"Rate limit cleanup failed: {response.data}"
)
logger.info("✅ All Settings endpoints tested")
def test_all_research_endpoints(self, authenticated_client):
"""Test ALL research-related endpoints."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
logger.info("\n=== Testing ALL Research Endpoints ===")
# Set up logging.
try:
logger.level("MILESTONE", no=26, color="<magenta><bold>")
except (TypeError, ValueError):
pass # Level already registered
# Test history endpoint first
response = authenticated_client.get("/history/api")
assert response.status_code == 200, (
f"History API failed: {response.data}"
)
# Start research via main endpoint
research_data = {
"query": "Test all endpoints comprehensive",
"mode": "quick",
"model_provider": "OLLAMA",
"model": "llama2",
"search_engine": "searxng",
"max_results": 5,
"time_period": "y",
"iterations": 1,
"questions_per_iteration": 2,
"strategy": "rapid",
}
# Test /api/start_research endpoint
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
assert response.status_code == 200, (
f"Start research failed: {response.data}"
)
data = json.loads(response.data)
assert "research_id" in data
research_id = data["research_id"]
# Give it a moment to start
time.sleep(0.5) # allow: unmarked-sleep
# Test various research endpoints
research_endpoints = [
("GET", f"/api/research/{research_id}", None, 200),
("GET", f"/api/research/{research_id}/status", None, 200),
("GET", f"/research/api/status/{research_id}", None, 200),
("GET", f"/history/status/{research_id}", None, 200),
("GET", f"/history/details/{research_id}", None, 200),
("GET", f"/history/log_count/{research_id}", None, 200),
]
for method, endpoint, req_data, expected_status in research_endpoints:
if method == "GET":
response = authenticated_client.get(endpoint)
else:
response = authenticated_client.post(
endpoint,
json=req_data,
content_type="application/json",
)
# Some endpoints might return 404 if research is still initializing
assert response.status_code in [expected_status, 404], (
f"{endpoint} failed: {response.data}"
)
# Test research API routes
response = authenticated_client.get(
"/research/api/settings/current-config"
)
assert response.status_code == 200, (
f"Current config failed: {response.data}"
)
# Test Ollama checks
response = authenticated_client.get("/research/api/check/ollama_status")
assert response.status_code == 200, (
f"Ollama status check failed: {response.data}"
)
# Terminate research
response = authenticated_client.post(f"/api/terminate/{research_id}")
assert response.status_code in [200, 400, 404], (
f"Terminate research failed: {response.data}"
)
# Test alternate terminate endpoint
response = authenticated_client.post(
f"/research/api/terminate/{research_id}"
)
assert response.status_code in [200, 400, 404], (
f"API terminate research failed: {response.data}"
)
logger.info("✅ All Research endpoints tested")
return research_id
def test_all_metrics_endpoints(self, authenticated_client):
"""Test ALL metrics endpoints."""
logger.info("\n=== Testing ALL Metrics Endpoints ===")
# Basic metrics endpoints
metrics_endpoints = [
"/metrics/api/metrics",
"/metrics/api/metrics/enhanced",
"/metrics/api/pricing",
"/metrics/api/cost-analytics",
"/metrics/api/star-reviews",
"/metrics/api/rate-limiting",
"/metrics/api/rate-limiting/current",
]
for endpoint in metrics_endpoints:
response = authenticated_client.get(endpoint)
assert response.status_code == 200, (
f"{endpoint} failed: {response.data}"
)
# Test specific model pricing
response = authenticated_client.get(
"/metrics/api/pricing/gpt-3.5-turbo"
)
assert response.status_code in [200, 404], (
f"Model pricing failed: {response.data}"
)
# Test cost calculation
cost_data = {
"model_name": "gpt-3.5-turbo",
"prompt_tokens": 1000,
"completion_tokens": 500,
}
response = authenticated_client.post(
"/metrics/api/cost-calculation",
json=cost_data,
content_type="application/json",
)
assert response.status_code == 200, (
f"Cost calculation failed: {response.data}"
)
logger.info("✅ All Metrics endpoints tested")
def test_all_benchmark_endpoints(self, authenticated_client):
"""Test ALL benchmark endpoints."""
logger.info("\n=== Testing ALL Benchmark Endpoints ===")
# Basic benchmark endpoints
benchmark_endpoints = [
"/benchmark/api/history",
"/benchmark/api/configs",
"/benchmark/api/running",
"/benchmark/api/search-quality",
]
for endpoint in benchmark_endpoints:
response = authenticated_client.get(endpoint)
assert response.status_code == 200, (
f"{endpoint} failed: {response.data}"
)
# Test config validation
test_config = {
"name": "Test Benchmark Config",
"queries": ["test query 1", "test query 2"],
"models": ["gpt-3.5-turbo"],
"search_engines": ["searxng"],
"iterations": 1,
}
response = authenticated_client.post(
"/benchmark/api/validate-config",
json=test_config,
content_type="application/json",
)
assert response.status_code == 200, (
f"Validate config failed: {response.data}"
)
# Test simple benchmark start (but don't actually run it)
simple_benchmark = {
"query": "test benchmark",
"models": ["gpt-3.5-turbo"],
"search_engines": ["searxng"],
}
# Note: We won't actually start a benchmark as it's resource intensive
# Just verify the endpoint exists
response = authenticated_client.post(
"/benchmark/api/start-simple",
json=simple_benchmark,
content_type="application/json",
)
# Accept 409 (conflict) if another benchmark is running
assert response.status_code in [200, 409, 400], (
f"Start simple benchmark status: {response.status_code}, {response.data}"
)
logger.info("✅ All Benchmark endpoints tested")
def test_all_history_endpoints(self, authenticated_client):
"""Test ALL history endpoints."""
logger.info("\n=== Testing ALL History Endpoints ===")
# Basic history endpoint
response = authenticated_client.get("/history/api")
assert response.status_code == 200, (
f"History API failed: {response.data}"
)
logger.info("✅ All History endpoints tested")
@pytest.mark.requires_llm
def test_all_api_v1_endpoints(self, authenticated_client):
"""Test ALL API v1 endpoints."""
logger.info("\n=== Testing ALL API v1 Endpoints ===")
# Health check (doesn't require auth)
response = authenticated_client.get("/api/v1/health")
assert response.status_code == 200, (
f"Health check failed: {response.data}"
)
# API documentation
response = authenticated_client.get("/api/v1/")
assert response.status_code == 200, f"API docs failed: {response.data}"
# Quick summary
summary_data = {"query": "What is machine learning?", "max_tokens": 100}
response = authenticated_client.post(
"/api/v1/quick_summary",
json=summary_data,
content_type="application/json",
)
assert response.status_code in [200, 404, 500], (
f"Quick summary status: {response.status_code}"
)
# Generate report
report_data = {
"query": "Test report generation",
"research_type": "comprehensive",
}
response = authenticated_client.post(
"/api/v1/generate_report",
json=report_data,
content_type="application/json",
)
assert response.status_code in [200, 404, 500], (
f"Generate report status: {response.status_code}"
)
# Analyze documents. The endpoint searches a named local collection;
# it does not accept an inline "documents" key (that now yields a 400).
doc_data = {
"query": "Summarize this document",
"collection_name": "test_collection",
}
response = authenticated_client.post(
"/api/v1/analyze_documents",
json=doc_data,
content_type="application/json",
)
assert response.status_code in [200, 404, 500], (
f"Analyze documents status: {response.status_code}"
)
logger.info("✅ All API v1 endpoints tested")
def test_miscellaneous_endpoints(self, authenticated_client):
"""Test miscellaneous endpoints not covered in other categories."""
logger.info("\n=== Testing Miscellaneous Endpoints ===")
# Test static file serving
response = authenticated_client.get("/static/css/style.css")
assert response.status_code in [200, 404], "Static file endpoint failed"
# Test favicon
response = authenticated_client.get("/favicon.ico")
assert response.status_code in [200, 404], "Favicon endpoint failed"
# Test pages that should exist
page_endpoints = [
"/", # Home page
"/history", # History page
"/settings", # Settings page
"/metrics/", # Metrics dashboard
"/benchmark/", # Benchmark dashboard
]
for endpoint in page_endpoints:
response = authenticated_client.get(endpoint)
assert response.status_code == 200, (
f"Page {endpoint} failed with status {response.status_code}"
)
logger.info("✅ All miscellaneous endpoints tested")
def test_error_handling(self, authenticated_client):
"""Test error handling for invalid endpoints and methods."""
logger.info("\n=== Testing Error Handling ===")
# Test non-existent endpoint
response = authenticated_client.get("/api/does-not-exist")
assert response.status_code == 404, (
f"Non-existent endpoint should return 404, got {response.status_code}"
)
# Test wrong method
response = authenticated_client.delete("/auth/check")
assert response.status_code in [404, 405], (
f"Wrong method should return 404/405, got {response.status_code}"
)
# Test invalid JSON
response = authenticated_client.post(
"/api/start_research",
data="invalid json",
content_type="application/json",
)
assert response.status_code in [400, 500], (
f"Invalid JSON should return 400/500, got {response.status_code}"
)
logger.info("✅ Error handling tested")