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
179 lines
6.2 KiB
Python
179 lines
6.2 KiB
Python
"""
|
|
Extended tests for news/api.py
|
|
|
|
Tests cover:
|
|
- _notify_scheduler_about_subscription_change() helper
|
|
- Exception classes
|
|
- Basic API function structure
|
|
"""
|
|
|
|
|
|
class TestNotifyScheduler:
|
|
"""Tests for _notify_scheduler_about_subscription_change() helper."""
|
|
|
|
def test_function_exists(self):
|
|
"""_notify_scheduler_about_subscription_change function exists."""
|
|
from local_deep_research.news.api import (
|
|
_notify_scheduler_about_subscription_change,
|
|
)
|
|
|
|
assert callable(_notify_scheduler_about_subscription_change)
|
|
|
|
def test_accepts_action_parameter(self):
|
|
"""Function accepts action parameter without crashing."""
|
|
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: DELETE).
|
|
from local_deep_research.news.api import (
|
|
_notify_scheduler_about_subscription_change,
|
|
)
|
|
|
|
# Should not raise even if scheduler is not set up
|
|
try:
|
|
_notify_scheduler_about_subscription_change("created")
|
|
except Exception:
|
|
pass # May fail if no scheduler, but shouldn't raise unexpected errors
|
|
|
|
|
|
class TestAPIFunctionSignatures:
|
|
"""Tests for API function signatures."""
|
|
|
|
def test_get_news_feed_exists(self):
|
|
"""get_news_feed function exists."""
|
|
from local_deep_research.news.api import get_news_feed
|
|
|
|
assert callable(get_news_feed)
|
|
|
|
def test_create_subscription_exists(self):
|
|
"""create_subscription function exists."""
|
|
from local_deep_research.news.api import create_subscription
|
|
|
|
assert callable(create_subscription)
|
|
|
|
def test_get_subscriptions_exists(self):
|
|
"""get_subscriptions function exists."""
|
|
from local_deep_research.news.api import get_subscriptions
|
|
|
|
assert callable(get_subscriptions)
|
|
|
|
def test_get_subscription_exists(self):
|
|
"""get_subscription function exists."""
|
|
from local_deep_research.news.api import get_subscription
|
|
|
|
assert callable(get_subscription)
|
|
|
|
def test_update_subscription_exists(self):
|
|
"""update_subscription function exists."""
|
|
from local_deep_research.news.api import update_subscription
|
|
|
|
assert callable(update_subscription)
|
|
|
|
def test_delete_subscription_exists(self):
|
|
"""delete_subscription function exists."""
|
|
from local_deep_research.news.api import delete_subscription
|
|
|
|
assert callable(delete_subscription)
|
|
|
|
|
|
class TestExceptionInheritance:
|
|
"""Tests for exception inheritance."""
|
|
|
|
def test_invalid_limit_inherits_from_exception(self):
|
|
"""InvalidLimitException inherits from Exception."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-1)
|
|
assert isinstance(exc, Exception)
|
|
|
|
def test_subscription_not_found_inherits_from_exception(self):
|
|
"""SubscriptionNotFoundException inherits from Exception."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-123")
|
|
assert isinstance(exc, Exception)
|
|
|
|
def test_database_access_inherits_from_exception(self):
|
|
"""DatabaseAccessException inherits from Exception."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("query", "DB error")
|
|
assert isinstance(exc, Exception)
|
|
|
|
|
|
class TestExceptionMessages:
|
|
"""Tests for exception message formatting."""
|
|
|
|
def test_invalid_limit_has_limit_value_in_details(self):
|
|
"""InvalidLimitException stores limit value in details."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-5)
|
|
assert "provided_limit" in exc.details
|
|
assert exc.details["provided_limit"] == -5
|
|
|
|
def test_subscription_not_found_has_id_in_details(self):
|
|
"""SubscriptionNotFoundException stores subscription_id in details."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-123")
|
|
assert "subscription_id" in exc.details
|
|
assert exc.details["subscription_id"] == "sub-123"
|
|
|
|
def test_invalid_limit_message(self):
|
|
"""InvalidLimitException has proper message."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-5)
|
|
assert "-5" in str(exc)
|
|
|
|
def test_subscription_not_found_message(self):
|
|
"""SubscriptionNotFoundException has proper message."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-123")
|
|
assert "sub-123" in str(exc)
|
|
|
|
def test_database_access_exception_has_operation_in_details(self):
|
|
"""DatabaseAccessException stores operation in details."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("query", "Connection failed")
|
|
assert "operation" in exc.details
|
|
assert exc.details["operation"] == "query"
|
|
|
|
def test_exception_to_dict_includes_error(self):
|
|
"""Exception to_dict includes error message."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-5)
|
|
result = exc.to_dict()
|
|
|
|
assert "error" in result
|
|
assert "-5" in result["error"]
|
|
|
|
def test_exception_to_dict_includes_status_code(self):
|
|
"""Exception to_dict includes status_code."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-123")
|
|
result = exc.to_dict()
|
|
|
|
assert "status_code" in result
|
|
assert result["status_code"] == 404
|
|
|
|
def test_exception_to_dict_includes_error_code(self):
|
|
"""Exception to_dict includes error_code."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-5)
|
|
result = exc.to_dict()
|
|
|
|
assert "error_code" in result
|
|
assert result["error_code"] == "INVALID_LIMIT"
|