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
300 lines
10 KiB
Python
300 lines
10 KiB
Python
"""
|
|
Comprehensive tests for Flask API helper functions.
|
|
Tests safe_error_message, get_user_id, and related utilities.
|
|
"""
|
|
|
|
|
|
class TestSafeErrorMessage:
|
|
"""Tests for safe_error_message function."""
|
|
|
|
def test_returns_string(self):
|
|
"""Test returns a string."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("test"), "context")
|
|
assert isinstance(result, str)
|
|
|
|
def test_handles_value_error(self):
|
|
"""Test handles ValueError specifically."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(ValueError("invalid input"), "testing")
|
|
assert result == "Invalid input provided"
|
|
|
|
def test_handles_key_error(self):
|
|
"""Test handles KeyError specifically."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(KeyError("missing_key"), "testing")
|
|
assert result == "Required data missing"
|
|
|
|
def test_handles_type_error(self):
|
|
"""Test handles TypeError specifically."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(TypeError("wrong type"), "testing")
|
|
assert result == "Invalid data format"
|
|
|
|
def test_handles_generic_exception(self):
|
|
"""Test handles generic Exception."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("some error"), "")
|
|
assert "An error occurred" in result
|
|
|
|
def test_includes_context_in_generic_message(self):
|
|
"""Test includes context in generic error message."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(RuntimeError("error"), "processing data")
|
|
assert "processing data" in result
|
|
|
|
def test_handles_empty_context(self):
|
|
"""Test handles empty context string."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("error"), "")
|
|
assert "An error occurred" in result
|
|
|
|
def test_does_not_expose_internal_details(self):
|
|
"""Test does not expose internal error details."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(
|
|
Exception("Secret database password: 12345"), "query"
|
|
)
|
|
# Should not contain the actual error message
|
|
assert "12345" not in result
|
|
assert "Secret" not in result
|
|
|
|
|
|
class TestGetUserId:
|
|
"""Tests for get_user_id function."""
|
|
|
|
def test_get_user_id_function_exists(self):
|
|
"""Test get_user_id function exists."""
|
|
from local_deep_research.news.flask_api import get_user_id
|
|
|
|
assert get_user_id is not None
|
|
assert callable(get_user_id)
|
|
|
|
def test_get_user_id_calls_current_user(self):
|
|
"""Test get_user_id calls current_user from auth module."""
|
|
# This test verifies the function exists and can be called
|
|
# Actual authentication testing requires Flask context
|
|
from local_deep_research.news.flask_api import get_user_id
|
|
|
|
# The function should be importable
|
|
assert hasattr(get_user_id, "__call__")
|
|
|
|
|
|
class TestBlueprintConfiguration:
|
|
"""Tests for Flask API blueprint configuration."""
|
|
|
|
def test_blueprint_has_correct_name(self):
|
|
"""Test blueprint has correct name."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
|
|
assert news_api_bp.name == "news_api"
|
|
|
|
def test_blueprint_has_api_prefix(self):
|
|
"""Test blueprint has /api prefix."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
|
|
assert news_api_bp.url_prefix == "/api"
|
|
|
|
|
|
class TestErrorHandlers:
|
|
"""Tests for Flask error handlers."""
|
|
|
|
def test_bad_request_handler(self):
|
|
"""Test 400 error handler."""
|
|
from local_deep_research.news.flask_api import bad_request, news_api_bp
|
|
from flask import Flask
|
|
|
|
app = Flask(__name__)
|
|
app.register_blueprint(news_api_bp, url_prefix="/news/api")
|
|
|
|
with app.app_context():
|
|
response, status_code = bad_request(None)
|
|
# Response should be a JSON response with error
|
|
assert status_code == 400
|
|
|
|
def test_not_found_handler(self):
|
|
"""Test 404 error handler."""
|
|
from local_deep_research.news.flask_api import not_found, news_api_bp
|
|
from flask import Flask
|
|
|
|
app = Flask(__name__)
|
|
app.register_blueprint(news_api_bp, url_prefix="/news/api")
|
|
|
|
with app.app_context():
|
|
response, status_code = not_found(None)
|
|
assert status_code == 404
|
|
|
|
def test_internal_error_handler(self):
|
|
"""Test 500 error handler."""
|
|
from local_deep_research.news.flask_api import (
|
|
internal_error,
|
|
news_api_bp,
|
|
)
|
|
from flask import Flask
|
|
|
|
app = Flask(__name__)
|
|
app.register_blueprint(news_api_bp, url_prefix="/news/api")
|
|
|
|
with app.app_context():
|
|
response, status_code = internal_error(None)
|
|
assert status_code == 500
|
|
|
|
|
|
class TestAPIRouteExists:
|
|
"""Tests to verify API routes are registered."""
|
|
|
|
def test_blueprint_is_valid(self):
|
|
"""Test blueprint is a valid Flask Blueprint."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
from flask import Blueprint
|
|
|
|
assert isinstance(news_api_bp, Blueprint)
|
|
|
|
def test_blueprint_has_deferred_functions(self):
|
|
"""Test blueprint has deferred route functions."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
|
|
# Blueprints store routes as deferred functions
|
|
assert hasattr(news_api_bp, "deferred_functions")
|
|
# Should have routes registered
|
|
assert len(news_api_bp.deferred_functions) > 0
|
|
|
|
def test_blueprint_url_prefix(self):
|
|
"""Test blueprint has correct URL prefix."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
|
|
assert news_api_bp.url_prefix == "/api"
|
|
|
|
|
|
class TestSafeErrorMessageEdgeCases:
|
|
"""Edge case tests for safe_error_message."""
|
|
|
|
def test_handles_exception_with_no_message(self):
|
|
"""Test handles exception with no message."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception(), "")
|
|
assert isinstance(result, str)
|
|
|
|
def test_handles_none_context(self):
|
|
"""Test handles None-like context."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("error"), "")
|
|
assert "An error occurred" in result
|
|
|
|
def test_handles_custom_exception(self):
|
|
"""Test handles custom exception class."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
class CustomException(Exception):
|
|
pass
|
|
|
|
result = safe_error_message(CustomException("custom error"), "testing")
|
|
assert "An error occurred" in result
|
|
|
|
def test_handles_unicode_in_error(self):
|
|
"""Test handles unicode characters in error."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(ValueError("Invalid: 日本語"), "processing")
|
|
assert result == "Invalid input provided"
|
|
|
|
def test_handles_long_context(self):
|
|
"""Test handles very long context string."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
long_context = "a" * 10000
|
|
result = safe_error_message(Exception("error"), long_context)
|
|
assert isinstance(result, str)
|
|
|
|
|
|
class TestFlaskApiImports:
|
|
"""Tests for module imports."""
|
|
|
|
def test_imports_safe_error_message(self):
|
|
"""Test safe_error_message can be imported."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
assert callable(safe_error_message)
|
|
|
|
def test_imports_get_user_id(self):
|
|
"""Test get_user_id can be imported."""
|
|
from local_deep_research.news.flask_api import get_user_id
|
|
|
|
assert callable(get_user_id)
|
|
|
|
def test_imports_news_api_bp(self):
|
|
"""Test news_api_bp can be imported."""
|
|
from local_deep_research.news.flask_api import news_api_bp
|
|
from flask import Blueprint
|
|
|
|
assert isinstance(news_api_bp, Blueprint)
|
|
|
|
|
|
class TestExceptionTypeHandling:
|
|
"""Tests for different exception type handling."""
|
|
|
|
def test_attribute_error(self):
|
|
"""Test handles AttributeError."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(AttributeError("no attr"), "test")
|
|
assert "An error occurred" in result
|
|
|
|
def test_index_error(self):
|
|
"""Test handles IndexError."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(IndexError("out of bounds"), "test")
|
|
assert "An error occurred" in result
|
|
|
|
def test_runtime_error(self):
|
|
"""Test handles RuntimeError."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(RuntimeError("runtime issue"), "test")
|
|
assert "An error occurred" in result
|
|
|
|
def test_os_error(self):
|
|
"""Test handles OSError."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(OSError("file not found"), "test")
|
|
assert "An error occurred" in result
|
|
|
|
|
|
class TestContextFormatting:
|
|
"""Tests for context formatting in error messages."""
|
|
|
|
def test_context_with_special_characters(self):
|
|
"""Test context with special characters."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(
|
|
Exception("error"), "processing <user> input"
|
|
)
|
|
assert "processing <user> input" in result
|
|
|
|
def test_context_with_numbers(self):
|
|
"""Test context with numbers."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("error"), "item 123")
|
|
assert "item 123" in result
|
|
|
|
def test_context_with_whitespace(self):
|
|
"""Test context with various whitespace."""
|
|
from local_deep_research.news.flask_api import safe_error_message
|
|
|
|
result = safe_error_message(Exception("error"), " processing ")
|
|
assert "processing" in result
|