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

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"