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

332 lines
12 KiB
Python

"""
Comprehensive API test suite with proper authentication handling.
"""
import json
import time
from loguru import logger
class TestComprehensiveAPIs:
"""Comprehensive API test suite using Flask test client."""
def test_auth_apis(self, authenticated_client):
"""Test authentication APIs."""
logger.info("Testing Authentication APIs")
# Check auth status
response = authenticated_client.get("/auth/check")
assert response.status_code == 200
data = json.loads(response.data)
assert data["authenticated"] is True
# Test integrity check
response = authenticated_client.get("/auth/integrity-check")
assert response.status_code == 200
data = json.loads(response.data)
assert "integrity" in data
logger.info("✅ Auth APIs tested")
def test_settings_apis(self, authenticated_client):
"""Test settings APIs."""
logger.info("Testing Settings APIs")
# Get all settings
response = authenticated_client.get("/settings/api")
assert response.status_code == 200
data = json.loads(response.data)
assert data["status"] == "success"
assert "settings" in data
# Get categories
response = authenticated_client.get("/settings/api/categories")
assert response.status_code == 200
data = json.loads(response.data)
assert "categories" in data
# Get types
response = authenticated_client.get("/settings/api/types")
assert response.status_code == 200
data = json.loads(response.data)
assert "types" in data
# Get available models
print("\n[DEBUG] Testing /settings/api/available-models")
response = authenticated_client.get("/settings/api/available-models")
print(f"[DEBUG] Response status: {response.status_code}")
assert response.status_code == 200
data = json.loads(response.data)
print(f"[DEBUG] Response keys: {list(data.keys())}")
# The endpoint returns provider_options and providers, not models
assert "provider_options" in data
assert "providers" in data
# Get available search engines
response = authenticated_client.get(
"/settings/api/available-search-engines"
)
assert response.status_code == 200
data = json.loads(response.data)
assert "engines" in data or "engine_options" in data
# Test setting CRUD (use an allow-listed prefix so the
# namespace gate permits creation of this throwaway key).
test_key = "llm.test_setting"
test_value = {"value": "test_value_123"}
# Create/Update setting
response = authenticated_client.put(
f"/settings/api/{test_key}",
json=test_value,
content_type="application/json",
)
assert response.status_code in [200, 201]
# Get the setting
response = authenticated_client.get(f"/settings/api/{test_key}")
# Setting might have been created or might not exist
assert response.status_code in [200, 404]
# Delete the setting
response = authenticated_client.delete(f"/settings/api/{test_key}")
assert response.status_code in [200, 204, 404]
logger.info("✅ Settings APIs tested")
def test_research_apis(self, authenticated_client):
"""Test research APIs."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
logger.info("Testing Research APIs")
# Get research history (endpoint is /api/history not /research/api/history)
response = authenticated_client.get("/api/history")
assert response.status_code == 200
data = json.loads(response.data)
assert "history" in data or "items" in data
# Start a test research
research_data = {
"query": "Test research from comprehensive API test",
"mode": "quick",
"model_provider": "OLLAMA",
"model": "llama2",
"search_engine": "searxng",
"max_results": 5,
"iterations": 1,
"questions_per_iteration": 2,
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
if response.status_code == 200:
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
# Check status
response = authenticated_client.get(
f"/api/research/{research_id}/status"
)
assert response.status_code == 200
# Terminate research
response = authenticated_client.post(
f"/api/terminate/{research_id}"
)
assert response.status_code in [200, 404]
logger.info("✅ Research APIs tested")
def test_metrics_apis(self, authenticated_client):
"""Test metrics APIs."""
logger.info("Testing Metrics APIs")
# Get metrics summary
response = authenticated_client.get("/metrics/api/metrics")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'metrics' not 'summary'
assert "metrics" in data
# Get enhanced metrics
response = authenticated_client.get("/metrics/api/metrics/enhanced")
assert response.status_code == 200
# Get pricing info
response = authenticated_client.get("/metrics/api/pricing")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'pricing' not 'models'
assert "pricing" in data
# Get cost analytics
response = authenticated_client.get("/metrics/api/cost-analytics")
assert response.status_code == 200
# 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
logger.info("✅ Metrics APIs tested")
def test_benchmark_apis(self, authenticated_client):
"""Test benchmark APIs."""
logger.info("Testing Benchmark APIs")
# Get benchmark history
response = authenticated_client.get("/benchmark/api/history")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'runs' not 'history'
assert "runs" in data
# Get saved configs
response = authenticated_client.get("/benchmark/api/configs")
assert response.status_code == 200
data = json.loads(response.data)
assert "configs" in data
# Check running benchmark
response = authenticated_client.get("/benchmark/api/running")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint might return either is_running or success key
assert "is_running" in data or "success" in data
# Validate config
test_config = {
"name": "Test Config",
"queries": ["test query"],
"models": ["gpt-3.5-turbo"],
"search_engines": ["searxng"],
}
response = authenticated_client.post(
"/benchmark/api/validate-config",
json=test_config,
content_type="application/json",
)
assert response.status_code == 200
logger.info("✅ Benchmark APIs tested")
def test_history_apis(self, authenticated_client):
"""Test history APIs."""
logger.info("Testing History APIs")
response = authenticated_client.get("/history/api")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'items' not 'history'
assert "items" in data
assert isinstance(data["items"], list)
logger.info("✅ History APIs tested")
def test_config_apis(self, authenticated_client):
"""Test configuration APIs."""
logger.info("Testing Config APIs")
# Get current config (correct path is /research/api/settings/current-config)
response = authenticated_client.get(
"/research/api/settings/current-config"
)
assert response.status_code == 200
data = json.loads(response.data)
# The response has a 'config' key containing the actual config
assert "config" in data or ("llm" in data and "search" in data)
if "config" in data:
config = data["config"]
assert "provider" in config or "llm" in config
logger.info("✅ Config APIs tested")
def test_health_check_apis(self, authenticated_client):
"""Test health check APIs."""
logger.info("Testing Health Check APIs")
# Check Ollama status (correct path is /research/api/check/ollama_status)
response = authenticated_client.get("/research/api/check/ollama_status")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'running' not 'available'
assert "running" in data or "available" in data
# Check Ollama model (might return 400 if no model specified)
response = authenticated_client.get("/research/api/check/ollama_model")
assert response.status_code in [200, 400]
logger.info("✅ Health Check APIs tested")
def test_api_v1_endpoints(self, authenticated_client):
"""Test API v1 endpoints."""
logger.info("Testing API v1 endpoints")
# Health check
response = authenticated_client.get("/api/v1/health")
assert response.status_code == 200
data = json.loads(response.data)
assert data["status"] == "ok"
# API documentation
response = authenticated_client.get("/api/v1/")
assert response.status_code == 200
data = json.loads(response.data)
assert data["api_version"] == "v1"
assert "endpoints" in data
logger.info("✅ API v1 endpoints tested")
def test_rate_limiting(self, authenticated_client):
"""Test rate limiting functionality."""
logger.info("Testing Rate Limiting")
# Get rate limiting status
response = authenticated_client.get(
"/settings/api/rate-limiting/status"
)
assert response.status_code == 200
# Get current rate limits
response = authenticated_client.get(
"/metrics/api/rate-limiting/current"
)
assert response.status_code == 200
# Test cleanup
response = authenticated_client.post(
"/settings/api/rate-limiting/cleanup"
)
assert response.status_code == 200
logger.info("✅ Rate limiting tested")
def test_data_location_api(self, authenticated_client):
"""Test data location API."""
logger.info("Testing Data Location API")
response = authenticated_client.get("/settings/api/data-location")
assert response.status_code == 200
data = json.loads(response.data)
# The endpoint returns 'data_directory' not 'data_dir'
assert "data_directory" in data
assert "is_custom" in data
logger.info("✅ Data location API tested")