Files
wehub-resource-sync 7a0da7932b
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
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

226 lines
7.7 KiB
Python

#!/usr/bin/env python3
"""
Test research creation endpoint specifically
"""
import json
import time
import pytest
@pytest.mark.requires_llm
class TestResearchCreation:
"""Test research creation functionality.
All tests in this class POST to /api/start_research with real
Ollama / searxng / model dependencies (PUNCHLIST Tier 4: FLAKY_SLEEP).
The class-level @pytest.mark.requires_llm gate makes them auto-
skip in environments without a live LLM stack, so CI doesn't
flake on the timing-sensitive sleep(0.5) and model-availability
assertions. Manual runs can invoke them with -m requires_llm.
"""
def test_research_creation_endpoint(self, authenticated_client):
"""Test the research creation endpoint."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: FIX_ASSERTION).
print("\nTesting /api/start_research endpoint...")
research_data = {
"query": "Test research query from Python",
"mode": "quick",
"model": "gpt-3.5-turbo",
"search_engines": ["searxng"],
"local_context": 2000,
"web_context": 2000,
"temperature": 0.7,
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
print(f"Response status: {response.status_code}")
assert response.status_code == 200
data = json.loads(response.data)
if data.get("status") == "success":
assert "research_id" in data
print(f"\n✅ SUCCESS! Research ID: {data.get('research_id')}")
return data["research_id"]
# Alternative response format
assert "research_id" in data
print(f"\n✅ SUCCESS! Research ID: {data['research_id']}")
return data["research_id"]
def test_research_creation_with_minimal_params(self, authenticated_client):
"""Test research creation with minimal parameters."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
research_data = {
"query": "Minimal test query",
"mode": "quick",
"model": "llama2",
"model_provider": "OLLAMA",
}
print(f"\n[DEBUG] Sending minimal research request: {research_data}")
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
print(f"[DEBUG] Response status: {response.status_code}")
if response.status_code != 200:
print(f"[DEBUG] Response data: {response.data.decode()[:500]}")
assert response.status_code == 200
data = json.loads(response.data)
assert "research_id" in data or (
data.get("status") == "success" and "research_id" in data
)
def test_research_creation_validation(self, authenticated_client):
"""Test research creation validation."""
# Missing query
response = authenticated_client.post(
"/api/start_research",
json={"mode": "quick"},
content_type="application/json",
)
assert response.status_code == 400
data = json.loads(response.data)
assert "error" in data or "message" in data
def test_research_status_check(self, authenticated_client):
"""Test checking research status."""
# First create a research
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
research_data = {
"query": "Status check test",
"mode": "quick",
"model": "llama2",
"model_provider": "OLLAMA",
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
assert response.status_code == 200
data = json.loads(response.data)
# Extract research_id
if "research_id" in data:
research_id = data["research_id"]
else:
research_id = data.get("data", {}).get("research_id")
assert research_id is not None
# 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
status_data = json.loads(response.data)
assert "status" in status_data or "research_status" in status_data
def test_research_termination(self, authenticated_client):
"""Test terminating a research."""
# First create a research
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
research_data = {
"query": "Termination test",
"mode": "quick",
"model": "llama2",
"model_provider": "OLLAMA",
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
assert response.status_code == 200
data = json.loads(response.data)
research_id = data.get("research_id") or data.get("data", {}).get(
"research_id"
)
assert research_id is not None
# Give it a moment to start
time.sleep(0.5) # allow: unmarked-sleep
# Terminate it
response = authenticated_client.post(f"/api/terminate/{research_id}")
assert response.status_code in [200, 404] # 404 if already finished
def test_research_modes(self, authenticated_client):
"""Test different research modes."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: FIX_ASSERTION).
modes = ["quick", "normal", "comprehensive"]
for mode in modes:
research_data = {
"query": f"Test {mode} mode",
"mode": mode,
"model": "llama2",
"model_provider": "OLLAMA",
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
assert response.status_code == 200
data = json.loads(response.data)
assert "research_id" in data or (
data.get("status") == "success" and "research_id" in data
)
print(f"✅ {mode} mode research created successfully")
# Terminate to clean up
research_id = data.get("research_id") or data.get("data", {}).get(
"research_id"
)
if research_id:
authenticated_client.post(f"/api/terminate/{research_id}")
def test_research_with_custom_model(self, authenticated_client):
"""Test research with custom model settings."""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: REFACTOR_SPLIT).
research_data = {
"query": "Custom model test",
"mode": "quick",
"model_provider": "OLLAMA",
"model": "mistral",
"temperature": 0.5,
"max_tokens": 1000,
}
response = authenticated_client.post(
"/api/start_research",
json=research_data,
content_type="application/json",
)
assert response.status_code == 200
data = json.loads(response.data)
assert "research_id" in data or (
data.get("status") == "success" and "research_id" in data
)