""" Test cases for news API exception handling. """ from local_deep_research.news.exceptions import ( NewsAPIException, InvalidLimitException, SubscriptionNotFoundException, SubscriptionCreationException, SubscriptionUpdateException, SubscriptionDeletionException, DatabaseAccessException, NewsFeedGenerationException, ResearchProcessingException, NotImplementedException, InvalidParameterException, SchedulerNotificationException, ) class TestNewsAPIException: """Test the base NewsAPIException class.""" def test_basic_exception(self): """Test basic exception creation.""" exc = NewsAPIException("Test error", status_code=400) assert str(exc) == "Test error" assert exc.message == "Test error" assert exc.status_code == 400 assert exc.error_code == "NewsAPIException" assert exc.details == {} def test_exception_with_details(self): """Test exception with additional details.""" details = {"key": "value", "count": 42} exc = NewsAPIException( "Test error", status_code=500, error_code="CUSTOM_ERROR", details=details, ) assert exc.error_code == "CUSTOM_ERROR" assert exc.details == details def test_to_dict(self): """Test converting exception to dictionary.""" exc = NewsAPIException( "Test error", status_code=403, error_code="TEST_ERROR", details={"user": "test"}, ) result = exc.to_dict() assert result == { "error": "Test error", "error_code": "TEST_ERROR", "status_code": 403, "details": {"user": "test"}, } def test_to_dict_without_details(self): """Test converting exception without details.""" exc = NewsAPIException("Simple error") result = exc.to_dict() assert result == { "error": "Simple error", "error_code": "NewsAPIException", "status_code": 500, } class TestSpecificExceptions: """Test specific exception subclasses.""" def test_invalid_limit_exception(self): """Test InvalidLimitException.""" exc = InvalidLimitException(-5) assert exc.status_code == 400 assert exc.error_code == "INVALID_LIMIT" assert "-5" in exc.message assert exc.details["provided_limit"] == -5 assert exc.details["min_limit"] == 1 def test_subscription_not_found(self): """Test SubscriptionNotFoundException.""" exc = SubscriptionNotFoundException("sub-123") assert exc.status_code == 404 assert exc.error_code == "SUBSCRIPTION_NOT_FOUND" assert "sub-123" in exc.message assert exc.details["subscription_id"] == "sub-123" def test_subscription_creation_exception(self): """Test SubscriptionCreationException.""" exc = SubscriptionCreationException( "Database error", {"query": "test query", "type": "search"} ) assert exc.status_code == 500 assert exc.error_code == "SUBSCRIPTION_CREATE_FAILED" assert "Database error" in exc.message assert exc.details["query"] == "test query" def test_subscription_update_exception(self): """Test SubscriptionUpdateException.""" exc = SubscriptionUpdateException("sub-456", "Invalid data") assert exc.status_code == 500 assert exc.error_code == "SUBSCRIPTION_UPDATE_FAILED" assert "sub-456" in exc.message assert "Invalid data" in exc.message assert exc.details["subscription_id"] == "sub-456" def test_subscription_deletion_exception(self): """Test SubscriptionDeletionException.""" exc = SubscriptionDeletionException("sub-789", "Permission denied") assert exc.status_code == 500 assert exc.error_code == "SUBSCRIPTION_DELETE_FAILED" assert "sub-789" in exc.message assert "Permission denied" in exc.message assert exc.details["subscription_id"] == "sub-789" def test_database_access_exception(self): """Test DatabaseAccessException.""" exc = DatabaseAccessException("query_operation", "Connection lost") assert exc.status_code == 500 assert exc.error_code == "DATABASE_ERROR" assert "query_operation" in exc.message assert "Connection lost" in exc.message assert exc.details["operation"] == "query_operation" def test_news_feed_generation_exception(self): """Test NewsFeedGenerationException.""" exc = NewsFeedGenerationException("Processing error", user_id="user123") assert exc.status_code == 500 assert exc.error_code == "FEED_GENERATION_FAILED" assert "Processing error" in exc.message assert exc.details["user_id"] == "user123" def test_news_feed_generation_without_user(self): """Test NewsFeedGenerationException without user_id.""" exc = NewsFeedGenerationException("Processing error") assert exc.details == {} def test_research_processing_exception(self): """Test ResearchProcessingException.""" exc = ResearchProcessingException( "Parse error", research_id="research-001" ) assert exc.status_code == 500 assert exc.error_code == "RESEARCH_PROCESSING_FAILED" assert "Parse error" in exc.message assert exc.details["research_id"] == "research-001" def test_not_implemented_exception(self): """Test NotImplementedException.""" exc = NotImplementedException("advanced_search") assert exc.status_code == 501 assert exc.error_code == "NOT_IMPLEMENTED" assert "advanced_search" in exc.message assert exc.details["feature"] == "advanced_search" def test_invalid_parameter_exception(self): """Test InvalidParameterException.""" exc = InvalidParameterException( "refresh_interval", -100, "Must be positive" ) assert exc.status_code == 400 assert exc.error_code == "INVALID_PARAMETER" assert "refresh_interval" in exc.message assert "Must be positive" in exc.message assert exc.details["parameter"] == "refresh_interval" assert exc.details["value"] == -100 def test_scheduler_notification_exception(self): """Test SchedulerNotificationException.""" exc = SchedulerNotificationException("update", "Service unavailable") assert exc.status_code == 500 assert exc.error_code == "SCHEDULER_NOTIFICATION_FAILED" assert "update" in exc.message assert "Service unavailable" in exc.message assert exc.details["action"] == "update"