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
667 lines
22 KiB
Python
667 lines
22 KiB
Python
"""
|
|
Extended tests for news/exceptions.py
|
|
|
|
Tests cover:
|
|
- NewsAPIException base class
|
|
- All derived exception classes
|
|
- to_dict() serialization
|
|
- Error codes and status codes
|
|
- Exception inheritance
|
|
"""
|
|
|
|
|
|
class TestNewsAPIException:
|
|
"""Tests for NewsAPIException base class."""
|
|
|
|
def test_inherits_from_exception(self):
|
|
"""NewsAPIException inherits from Exception."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test")
|
|
assert isinstance(exc, Exception)
|
|
|
|
def test_stores_message(self):
|
|
"""Stores the message."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("Error message")
|
|
assert exc.message == "Error message"
|
|
|
|
def test_default_status_code_is_500(self):
|
|
"""Default status_code is 500."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test")
|
|
assert exc.status_code == 500
|
|
|
|
def test_custom_status_code(self):
|
|
"""Accepts custom status_code."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", status_code=404)
|
|
assert exc.status_code == 404
|
|
|
|
def test_default_error_code_is_class_name(self):
|
|
"""Default error_code is the class name."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test")
|
|
assert exc.error_code == "NewsAPIException"
|
|
|
|
def test_custom_error_code(self):
|
|
"""Accepts custom error_code."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", error_code="CUSTOM_ERROR")
|
|
assert exc.error_code == "CUSTOM_ERROR"
|
|
|
|
def test_details_defaults_to_empty_dict(self):
|
|
"""Details defaults to empty dict."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test")
|
|
assert exc.details == {}
|
|
|
|
def test_custom_details(self):
|
|
"""Accepts custom details."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", details={"key": "value"})
|
|
assert exc.details == {"key": "value"}
|
|
|
|
def test_str_returns_message(self):
|
|
"""str() returns the message."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("Error occurred")
|
|
assert str(exc) == "Error occurred"
|
|
|
|
|
|
class TestNewsAPIExceptionToDict:
|
|
"""Tests for NewsAPIException.to_dict()."""
|
|
|
|
def test_includes_error(self):
|
|
"""Dict includes error message."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("Error message")
|
|
data = exc.to_dict()
|
|
|
|
assert data["error"] == "Error message"
|
|
|
|
def test_includes_error_code(self):
|
|
"""Dict includes error_code."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", error_code="TEST_ERROR")
|
|
data = exc.to_dict()
|
|
|
|
assert data["error_code"] == "TEST_ERROR"
|
|
|
|
def test_includes_status_code(self):
|
|
"""Dict includes status_code."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", status_code=400)
|
|
data = exc.to_dict()
|
|
|
|
assert data["status_code"] == 400
|
|
|
|
def test_includes_details_when_present(self):
|
|
"""Dict includes details when provided."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test", details={"field": "value"})
|
|
data = exc.to_dict()
|
|
|
|
assert data["details"] == {"field": "value"}
|
|
|
|
def test_excludes_details_when_empty(self):
|
|
"""Dict excludes details when empty."""
|
|
from local_deep_research.news.exceptions import NewsAPIException
|
|
|
|
exc = NewsAPIException("test")
|
|
data = exc.to_dict()
|
|
|
|
assert "details" not in data
|
|
|
|
|
|
class TestNewsFeatureDisabledException:
|
|
"""Tests for NewsFeatureDisabledException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeatureDisabledException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = NewsFeatureDisabledException()
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_default_message(self):
|
|
"""Has default message."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeatureDisabledException,
|
|
)
|
|
|
|
exc = NewsFeatureDisabledException()
|
|
assert exc.message == "News system is disabled"
|
|
|
|
def test_custom_message(self):
|
|
"""Accepts custom message."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeatureDisabledException,
|
|
)
|
|
|
|
exc = NewsFeatureDisabledException("Custom disable message")
|
|
assert exc.message == "Custom disable message"
|
|
|
|
def test_status_code_is_503(self):
|
|
"""Status code is 503 (Service Unavailable)."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeatureDisabledException,
|
|
)
|
|
|
|
exc = NewsFeatureDisabledException()
|
|
assert exc.status_code == 503
|
|
|
|
def test_error_code_is_news_disabled(self):
|
|
"""Error code is NEWS_DISABLED."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeatureDisabledException,
|
|
)
|
|
|
|
exc = NewsFeatureDisabledException()
|
|
assert exc.error_code == "NEWS_DISABLED"
|
|
|
|
|
|
class TestInvalidLimitException:
|
|
"""Tests for InvalidLimitException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidLimitException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = InvalidLimitException(0)
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_limit_in_message(self):
|
|
"""Message includes the invalid limit value."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-5)
|
|
assert "-5" in exc.message
|
|
|
|
def test_status_code_is_400(self):
|
|
"""Status code is 400 (Bad Request)."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(0)
|
|
assert exc.status_code == 400
|
|
|
|
def test_error_code_is_invalid_limit(self):
|
|
"""Error code is INVALID_LIMIT."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(0)
|
|
assert exc.error_code == "INVALID_LIMIT"
|
|
|
|
def test_details_include_provided_limit(self):
|
|
"""Details include provided_limit."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(-10)
|
|
assert exc.details["provided_limit"] == -10
|
|
|
|
def test_details_include_min_limit(self):
|
|
"""Details include min_limit."""
|
|
from local_deep_research.news.exceptions import InvalidLimitException
|
|
|
|
exc = InvalidLimitException(0)
|
|
assert exc.details["min_limit"] == 1
|
|
|
|
|
|
class TestSubscriptionNotFoundException:
|
|
"""Tests for SubscriptionNotFoundException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-123")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_subscription_id_in_message(self):
|
|
"""Message includes the subscription ID."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-abc-123")
|
|
assert "sub-abc-123" in exc.message
|
|
|
|
def test_status_code_is_404(self):
|
|
"""Status code is 404 (Not Found)."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-1")
|
|
assert exc.status_code == 404
|
|
|
|
def test_error_code_is_subscription_not_found(self):
|
|
"""Error code is SUBSCRIPTION_NOT_FOUND."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-1")
|
|
assert exc.error_code == "SUBSCRIPTION_NOT_FOUND"
|
|
|
|
def test_details_include_subscription_id(self):
|
|
"""Details include subscription_id."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionNotFoundException,
|
|
)
|
|
|
|
exc = SubscriptionNotFoundException("sub-xyz")
|
|
assert exc.details["subscription_id"] == "sub-xyz"
|
|
|
|
|
|
class TestSubscriptionCreationException:
|
|
"""Tests for SubscriptionCreationException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionCreationException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = SubscriptionCreationException("Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_message_in_error(self):
|
|
"""Message includes the provided message."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionCreationException,
|
|
)
|
|
|
|
exc = SubscriptionCreationException("Invalid data")
|
|
assert "Invalid data" in exc.message
|
|
|
|
def test_status_code_is_500(self):
|
|
"""Status code is 500 (Internal Server Error)."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionCreationException,
|
|
)
|
|
|
|
exc = SubscriptionCreationException("Error")
|
|
assert exc.status_code == 500
|
|
|
|
def test_error_code_is_subscription_create_failed(self):
|
|
"""Error code is SUBSCRIPTION_CREATE_FAILED."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionCreationException,
|
|
)
|
|
|
|
exc = SubscriptionCreationException("Error")
|
|
assert exc.error_code == "SUBSCRIPTION_CREATE_FAILED"
|
|
|
|
def test_accepts_details(self):
|
|
"""Accepts optional details."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionCreationException,
|
|
)
|
|
|
|
exc = SubscriptionCreationException("Error", details={"field": "topic"})
|
|
assert exc.details["field"] == "topic"
|
|
|
|
|
|
class TestSubscriptionUpdateException:
|
|
"""Tests for SubscriptionUpdateException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionUpdateException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = SubscriptionUpdateException("sub-1", "Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_subscription_id_in_message(self):
|
|
"""Message includes the subscription ID."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionUpdateException,
|
|
)
|
|
|
|
exc = SubscriptionUpdateException("sub-123", "Update failed")
|
|
assert "sub-123" in exc.message
|
|
|
|
def test_includes_error_message(self):
|
|
"""Message includes the error message."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionUpdateException,
|
|
)
|
|
|
|
exc = SubscriptionUpdateException("sub-1", "Validation error")
|
|
assert "Validation error" in exc.message
|
|
|
|
def test_status_code_is_500(self):
|
|
"""Status code is 500."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionUpdateException,
|
|
)
|
|
|
|
exc = SubscriptionUpdateException("sub-1", "Error")
|
|
assert exc.status_code == 500
|
|
|
|
def test_details_include_subscription_id(self):
|
|
"""Details include subscription_id."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionUpdateException,
|
|
)
|
|
|
|
exc = SubscriptionUpdateException("sub-xyz", "Error")
|
|
assert exc.details["subscription_id"] == "sub-xyz"
|
|
|
|
|
|
class TestSubscriptionDeletionException:
|
|
"""Tests for SubscriptionDeletionException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionDeletionException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = SubscriptionDeletionException("sub-1", "Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_subscription_id_in_message(self):
|
|
"""Message includes the subscription ID."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionDeletionException,
|
|
)
|
|
|
|
exc = SubscriptionDeletionException("sub-456", "Delete failed")
|
|
assert "sub-456" in exc.message
|
|
|
|
def test_error_code_is_subscription_delete_failed(self):
|
|
"""Error code is SUBSCRIPTION_DELETE_FAILED."""
|
|
from local_deep_research.news.exceptions import (
|
|
SubscriptionDeletionException,
|
|
)
|
|
|
|
exc = SubscriptionDeletionException("sub-1", "Error")
|
|
assert exc.error_code == "SUBSCRIPTION_DELETE_FAILED"
|
|
|
|
|
|
class TestDatabaseAccessException:
|
|
"""Tests for DatabaseAccessException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
DatabaseAccessException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = DatabaseAccessException("query", "Connection failed")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_operation_in_message(self):
|
|
"""Message includes the operation."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("insert", "Error")
|
|
assert "insert" in exc.message
|
|
|
|
def test_includes_error_message(self):
|
|
"""Message includes the error message."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("op", "Connection timeout")
|
|
assert "Connection timeout" in exc.message
|
|
|
|
def test_error_code_is_database_error(self):
|
|
"""Error code is DATABASE_ERROR."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("op", "Error")
|
|
assert exc.error_code == "DATABASE_ERROR"
|
|
|
|
def test_details_include_operation(self):
|
|
"""Details include operation."""
|
|
from local_deep_research.news.exceptions import DatabaseAccessException
|
|
|
|
exc = DatabaseAccessException("update", "Error")
|
|
assert exc.details["operation"] == "update"
|
|
|
|
|
|
class TestNewsFeedGenerationException:
|
|
"""Tests for NewsFeedGenerationException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeedGenerationException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = NewsFeedGenerationException("Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_message_in_error(self):
|
|
"""Message includes the provided message."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeedGenerationException,
|
|
)
|
|
|
|
exc = NewsFeedGenerationException("No sources available")
|
|
assert "No sources available" in exc.message
|
|
|
|
def test_error_code_is_feed_generation_failed(self):
|
|
"""Error code is FEED_GENERATION_FAILED."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeedGenerationException,
|
|
)
|
|
|
|
exc = NewsFeedGenerationException("Error")
|
|
assert exc.error_code == "FEED_GENERATION_FAILED"
|
|
|
|
def test_includes_user_id_when_provided(self):
|
|
"""Details include user_id when provided."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeedGenerationException,
|
|
)
|
|
|
|
exc = NewsFeedGenerationException("Error", user_id="user-123")
|
|
assert exc.details["user_id"] == "user-123"
|
|
|
|
def test_no_user_id_when_not_provided(self):
|
|
"""Details empty when user_id not provided."""
|
|
from local_deep_research.news.exceptions import (
|
|
NewsFeedGenerationException,
|
|
)
|
|
|
|
exc = NewsFeedGenerationException("Error")
|
|
assert "user_id" not in exc.details
|
|
|
|
|
|
class TestResearchProcessingException:
|
|
"""Tests for ResearchProcessingException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
ResearchProcessingException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = ResearchProcessingException("Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_error_code_is_research_processing_failed(self):
|
|
"""Error code is RESEARCH_PROCESSING_FAILED."""
|
|
from local_deep_research.news.exceptions import (
|
|
ResearchProcessingException,
|
|
)
|
|
|
|
exc = ResearchProcessingException("Error")
|
|
assert exc.error_code == "RESEARCH_PROCESSING_FAILED"
|
|
|
|
def test_includes_research_id_when_provided(self):
|
|
"""Details include research_id when provided."""
|
|
from local_deep_research.news.exceptions import (
|
|
ResearchProcessingException,
|
|
)
|
|
|
|
exc = ResearchProcessingException("Error", research_id="res-123")
|
|
assert exc.details["research_id"] == "res-123"
|
|
|
|
|
|
class TestNotImplementedException:
|
|
"""Tests for NotImplementedException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
NotImplementedException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = NotImplementedException("feature")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_feature_in_message(self):
|
|
"""Message includes the feature name."""
|
|
from local_deep_research.news.exceptions import NotImplementedException
|
|
|
|
exc = NotImplementedException("AI summarization")
|
|
assert "AI summarization" in exc.message
|
|
|
|
def test_status_code_is_501(self):
|
|
"""Status code is 501 (Not Implemented)."""
|
|
from local_deep_research.news.exceptions import NotImplementedException
|
|
|
|
exc = NotImplementedException("feature")
|
|
assert exc.status_code == 501
|
|
|
|
def test_details_include_feature(self):
|
|
"""Details include feature."""
|
|
from local_deep_research.news.exceptions import NotImplementedException
|
|
|
|
exc = NotImplementedException("real-time updates")
|
|
assert exc.details["feature"] == "real-time updates"
|
|
|
|
|
|
class TestInvalidParameterException:
|
|
"""Tests for InvalidParameterException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = InvalidParameterException("param", "value", "message")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_parameter_in_message(self):
|
|
"""Message includes the parameter name."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
)
|
|
|
|
exc = InvalidParameterException("limit", -1, "Must be positive")
|
|
assert "limit" in exc.message
|
|
|
|
def test_includes_error_message(self):
|
|
"""Message includes the error description."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
)
|
|
|
|
exc = InvalidParameterException("limit", -1, "Must be positive")
|
|
assert "Must be positive" in exc.message
|
|
|
|
def test_status_code_is_400(self):
|
|
"""Status code is 400 (Bad Request)."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
)
|
|
|
|
exc = InvalidParameterException("p", "v", "m")
|
|
assert exc.status_code == 400
|
|
|
|
def test_details_include_parameter(self):
|
|
"""Details include parameter name."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
)
|
|
|
|
exc = InvalidParameterException("offset", "abc", "Must be integer")
|
|
assert exc.details["parameter"] == "offset"
|
|
|
|
def test_details_include_value(self):
|
|
"""Details include the invalid value."""
|
|
from local_deep_research.news.exceptions import (
|
|
InvalidParameterException,
|
|
)
|
|
|
|
exc = InvalidParameterException("offset", "abc", "Must be integer")
|
|
assert exc.details["value"] == "abc"
|
|
|
|
|
|
class TestSchedulerNotificationException:
|
|
"""Tests for SchedulerNotificationException."""
|
|
|
|
def test_inherits_from_news_api_exception(self):
|
|
"""Inherits from NewsAPIException."""
|
|
from local_deep_research.news.exceptions import (
|
|
SchedulerNotificationException,
|
|
NewsAPIException,
|
|
)
|
|
|
|
exc = SchedulerNotificationException("action", "Error")
|
|
assert isinstance(exc, NewsAPIException)
|
|
|
|
def test_includes_action_in_message(self):
|
|
"""Message includes the action."""
|
|
from local_deep_research.news.exceptions import (
|
|
SchedulerNotificationException,
|
|
)
|
|
|
|
exc = SchedulerNotificationException("subscription_create", "Failed")
|
|
assert "subscription_create" in exc.message
|
|
|
|
def test_error_code_is_scheduler_notification_failed(self):
|
|
"""Error code is SCHEDULER_NOTIFICATION_FAILED."""
|
|
from local_deep_research.news.exceptions import (
|
|
SchedulerNotificationException,
|
|
)
|
|
|
|
exc = SchedulerNotificationException("action", "Error")
|
|
assert exc.error_code == "SCHEDULER_NOTIFICATION_FAILED"
|
|
|
|
def test_details_include_action(self):
|
|
"""Details include action."""
|
|
from local_deep_research.news.exceptions import (
|
|
SchedulerNotificationException,
|
|
)
|
|
|
|
exc = SchedulerNotificationException("user_update", "Error")
|
|
assert exc.details["action"] == "user_update"
|