Skip to content

fix: add back news rss comps#10069

Merged
erichare merged 6 commits into
mainfrom
add-back-news-rss-comps
Oct 2, 2025
Merged

fix: add back news rss comps#10069
erichare merged 6 commits into
mainfrom
add-back-news-rss-comps

Conversation

@jordanrfrazier
Copy link
Copy Markdown
Collaborator

@jordanrfrazier jordanrfrazier commented Oct 1, 2025

These components were accidentally removed instead of being deprecated first; this just adds them back until we decide to eventually clean up the deprecated components.

Original PR: #9975

Summary by CodeRabbit

  • New Features

    • Added a News Search component that retrieves articles from Google News by keyword, topic, or location with language/country options. Returns titles, links, dates, and summaries, with clear handling for errors and no results.
    • Added an RSS Reader component to fetch and parse any RSS feed into an articles list with robust validation, timeouts, and error feedback.
  • Tests

    • Introduced comprehensive unit tests for both components, covering successful fetches, empty feeds, missing fields, and network errors.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 1, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds two new data components: NewsSearchComponent for Google News RSS-based searches and RSSReaderComponent for generic RSS fetching/parsing. Introduces corresponding unit tests validating success, empty, error, and missing-field scenarios. Components perform HTTP GET, parse XML with BeautifulSoup, and return DataFrames with standardized columns.

Changes

Cohort / File(s) Summary
New data components
src/lfx/src/lfx/components/data/news_search.py, src/lfx/src/lfx/components/data/rss.py
Adds NewsSearchComponent with inputs for query/topic/location and outputs a DataFrame via search_news; adds RSSReaderComponent with inputs for rss_url/timeout and outputs a DataFrame via read_rss; both implement HTTP fetch, XML parsing, and error handling.
Unit tests
src/backend/tests/unit/components/data/test_news_search.py, src/backend/tests/unit/components/data/test_rss.py
Adds pytest-based tests covering successful parses, empty feeds, errors via mocked requests.get, and field validation for DataFrame structure and values.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as Caller
  participant NS as NewsSearchComponent
  participant GN as Google News RSS
  participant BS as XML Parser (BeautifulSoup)

  U->>NS: search_news()
  alt topic/location/query provided
    NS->>NS: Build RSS URL (topic/location/keyword)
    NS->>GN: HTTP GET (timeout)
    alt HTTP OK
      NS->>BS: Parse XML content
      BS-->>NS: Items [title, link, pubDate, description]
      alt Items found
        NS-->>U: DataFrame[title, link, published, summary]
      else No items
        NS-->>U: DataFrame[{"title":"No articles found", ...}]
      end
    else Request/Parse error
      NS-->>U: DataFrame[{"title":"Error", "summary": error}]
    end
  else no search parameter
    NS-->>U: DataFrame[{"title":"Error", "summary":"No search parameter"}]
  end
Loading
sequenceDiagram
  autonumber
  participant U as Caller
  participant RSS as RSSReaderComponent
  participant SRC as RSS Source
  participant BS as XML Parser (BeautifulSoup)

  U->>RSS: read_rss(rss_url, timeout)
  RSS->>SRC: HTTP GET (timeout)
  alt HTTP OK
    RSS->>BS: Parse XML content
    alt Valid XML with items
      BS-->>RSS: Items [title, link, pubDate, description]
      RSS-->>U: DataFrame[title, link, published, summary]
    else No/invalid items
      RSS-->>U: DataFrame[0 rows or error row per implementation]
    end
  else Request error
    RSS-->>U: DataFrame[{"title":"Error", "summary": error}]
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • erichare

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary change—restoring the news RSS components—using clear language and conventional commit style without unnecessary detail, making it easy to understand at a glance.
Test Coverage For New Implementations ✅ Passed The PR adds two new data components (NewsSearchComponent and RSSReaderComponent) and includes corresponding unit tests (test_news_search.py and test_rss.py) that follow the test_*.py backend naming convention; these tests exercise successful fetches, missing fields, error handling, and empty-result scenarios, directly validating the new parsing and error paths, so the new functionality is adequately covered by meaningful automated tests.
Test Quality And Coverage ✅ Passed Based on the submitted unit tests, both NewsSearchComponent and RSSReaderComponent have dedicated pytest suites that exercise successful fetches as well as key failure paths, validating DataFrame shape, contents, and error-reporting rows instead of performing mere smoke checks. The tests align with the backend’s pytest conventions, using targeted patching of requests.get and covering empty-result scenarios, ensuring the core behaviors of parsing RSS content, handling missing fields, and surfacing network exceptions are all verified. While additional cases (for example topic- and location-based news searches) could further expand coverage, the current suite already exercises the primary functionality paths introduced in this PR.
Test File Naming And Structure ✅ Passed Both new backend test modules live under src/backend/tests/unit/components/data/ and adhere to the expected test_*.py naming pattern for pytest suites.(github.com) Fixtures are declared with @pytest.fixture, and test functions such as test_successful_news_search, test_news_search_error, and test_empty_news_results use descriptive names, organize their setup through scoped mocks, and keep teardown implicit via context managers.(github.com) Each suite exercises positive flows plus negative and edge conditions—including network errors, empty feeds, and missing RSS fields—meeting the coverage expectations outlined in the custom check.(github.com)
Excessive Mock Usage Warning ✅ Passed Reviewing the added unit suites for NewsSearchComponent and RSSReaderComponent shows that each scenario only patches requests.get (and returns a lightweight Mock response) to sidestep external HTTP calls, while still exercising the components’ real parsing and DataFrame-building logic. The mocks do not cascade into internal behavior or replace core collaborators, so assertions remain transparent about what is being validated. Because the tests cover success, empty-feed, missing-field, and error paths without over-mocking internal code, there is no indication of excessive or poor mock usage.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Oct 1, 2025
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 1, 2025
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 1, 2025
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 1, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (10)
src/lfx/src/lfx/components/data/rss.py (3)

47-52: Eliminate redundant XML parsing.

The XML is parsed twice: once for validation (line 48) and again for extraction (line 52). This is inefficient and adds unnecessary overhead.

Apply this diff to remove the redundant validation parse:

-            # Check if the response is valid XML
-            try:
-                BeautifulSoup(response.content, "xml")
-            except Exception as e:
-                msg = f"Invalid XML response: {e}"
-                raise ValueError(msg) from e
             soup = BeautifulSoup(response.content, "xml")
+            if soup is None:
+                msg = "Invalid XML response"
+                raise ValueError(msg)
             items = soup.find_all("item")

28-34: Validate timeout input range.

The timeout input accepts any integer, but negative or zero values would cause issues with requests.get.

Consider adding validation in the read_rss method:

     def read_rss(self) -> DataFrame:
+        if self.timeout <= 0:
+            self.status = "Timeout must be positive"
+            return DataFrame(pd.DataFrame([{"title": "Error", "link": "", "published": "", "summary": "Invalid timeout value"}]))
         try:

41-41: Consider adding URL validation.

The component accepts any string as rss_url without validation. Malformed URLs will fail at request time, but early validation could provide better error messages.

You could add basic URL validation before making the request:

from urllib.parse import urlparse

# In read_rss():
parsed = urlparse(self.rss_url)
if not parsed.scheme or not parsed.netloc:
    self.status = "Invalid RSS URL"
    return DataFrame(pd.DataFrame([{"title": "Error", "link": "", "published": "", "summary": "Invalid URL format"}]))
src/backend/tests/unit/components/data/test_rss.py (1)

29-129: Consider adding tests for invalid XML and empty content.

The component has specific handling for invalid XML (lines 47-51 in rss.py) and empty response content (lines 43-45), but these paths aren't tested.

Add these test cases:

def test_invalid_xml_response(self):
    """Test handling of non-XML response content."""
    mock_response = Mock()
    mock_response.content = b"Not XML content"
    mock_response.raise_for_status = Mock()
    
    with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
        component = RSSReaderComponent(rss_url="https://example.com/feed.xml")
        result = component.read_rss()
        
        assert isinstance(result, DataFrame)
        assert len(result) == 1
        assert result.iloc[0]["title"] == "Error"
        assert "Invalid XML" in result.iloc[0]["summary"]

def test_empty_response_content(self):
    """Test handling of empty response."""
    mock_response = Mock()
    mock_response.content = b"   "  # Only whitespace
    mock_response.raise_for_status = Mock()
    
    with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
        component = RSSReaderComponent(rss_url="https://example.com/feed.xml")
        result = component.read_rss()
        
        assert isinstance(result, DataFrame)
        assert len(result) == 1
        assert result.iloc[0]["title"] == "Error"
        assert "Empty response" in result.iloc[0]["summary"]
src/backend/tests/unit/components/data/test_news_search.py (2)

24-88: Add test coverage for missing input scenario.

The component handles the case where no query, topic, or location is provided (lines 115-129 in news_search.py), but this isn't tested.

Add this test:

def test_no_search_parameters(self):
    """Test handling when no query, topic, or location is provided."""
    component = NewsSearchComponent()
    result = component.search_news()
    
    assert isinstance(result, DataFrame)
    assert len(result) == 1
    assert result.iloc[0]["title"] == "Error"
    assert "No search query, topic, or location provided" in result.iloc[0]["summary"]

24-88: Consider testing HTML cleaning functionality.

The component uses clean_html() on titles and summaries (lines 153, 156 in news_search.py), but tests don't verify HTML stripping works correctly.

Add a test with HTML in the RSS content:

def test_html_cleaning_in_results(self):
    """Test that HTML tags are stripped from titles and summaries."""
    mock_rss_content = """
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0">
        <channel>
            <item>
                <title>&lt;b&gt;Bold Title&lt;/b&gt;</title>
                <link>https://example.com/1</link>
                <pubDate>2024-03-20</pubDate>
                <description>&lt;p&gt;HTML &lt;em&gt;content&lt;/em&gt;&lt;/p&gt;</description>
            </item>
        </channel>
    </rss>
    """
    mock_response = Mock()
    mock_response.content = mock_rss_content.encode("utf-8")
    mock_response.raise_for_status = Mock()
    
    with patch("lfx.components.data.news_search.requests.get", return_value=mock_response):
        component = NewsSearchComponent(query="test")
        result = component.search_news()
        
        assert "<b>" not in result.iloc[0]["title"]
        assert "<p>" not in result.iloc[0]["summary"]
        assert "Bold Title" in result.iloc[0]["title"]
        assert "HTML content" in result.iloc[0]["summary"]
src/lfx/src/lfx/components/data/news_search.py (4)

92-92: Fix potential IndexError when splitting language code.

If hl is a simple language code like "en" (without hyphen), hl.split('-')[0] works, but the logic assumes a hyphen exists. While split won't fail, this could create unexpected ceid values.

Apply this diff to handle both cases:

-        ceid = getattr(self, "ceid", None) or f"{gl}:{hl.split('-')[0]}"
+        ceid = getattr(self, "ceid", None) or f"{gl}:{hl.split('-')[0] if '-' in hl else hl}"

111-112: Simplify redundant list wrapping and join.

Creating a single-element list then joining it is unnecessary.

Apply this diff:

-            query_parts = [query]
-            query_encoded = quote_plus(" ".join(query_parts))
+            query_encoded = quote_plus(query)

166-167: Code duplication: clean_html duplicated across components.

This method is identical to the one in src/lfx/src/lfx/components/data/web_search.py (lines 149-151). Since both RSS/News components are legacy and will be replaced by WebSearch, this duplication is acceptable for now, but consider extracting to a shared utility if this pattern continues.

Based on relevant code snippets showing the same method in web_search.py.


131-143: Consider adding XML validation like RSSReaderComponent.

RSSReaderComponent validates the XML response and checks for empty content (lines 43-51 in rss.py), but NewsSearchComponent doesn't. This could lead to less informative error messages for malformed responses.

Consider adding similar validation:

         try:
             response = requests.get(rss_url, timeout=self.timeout)
             response.raise_for_status()
+            if not response.content.strip():
+                msg = "Empty response received"
+                raise ValueError(msg)
             soup = BeautifulSoup(response.content, "xml")
             items = soup.find_all("item")
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7382ac8 and f151d55.

📒 Files selected for processing (4)
  • src/backend/tests/unit/components/data/test_news_search.py (1 hunks)
  • src/backend/tests/unit/components/data/test_rss.py (1 hunks)
  • src/lfx/src/lfx/components/data/news_search.py (1 hunks)
  • src/lfx/src/lfx/components/data/rss.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
src/backend/tests/unit/components/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure for unit tests in src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping for backward compatibility in component tests
Create comprehensive unit tests for all new components

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
src/backend/tests/unit/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Test component integration within flows using create_flow, build_flow, and get_build_events utilities

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Unit tests for backend code must be located in the 'src/backend/tests/' directory, with component tests organized by component subdirectory under 'src/backend/tests/unit/components/'.
Test files should use the same filename as the component under test, with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests in backend Python tests, as defined in 'src/backend/tests/conftest.py'.
When writing component tests, inherit from the appropriate base class in 'src/backend/tests/base.py' (ComponentTestBase, ComponentTestBaseWithClient, or ComponentTestBaseWithoutClient) and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping'.
Each test in backend Python test files should have a clear docstring explaining its purpose, and complex setups or mocks should be well-commented.
Test both sync and async code paths in backend Python tests, using '@pytest.mark.asyncio' for async tests.
Mock external dependencies appropriately in backend Python tests to isolate unit tests from external services.
Test error handling and edge cases in backend Python tests, including using 'pytest.raises' and asserting error messages.
Validate input/output behavior and test component initialization and configuration in backend Python tests.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests when necessary.
Be aware of ContextVar propagation in async tests; test both direct event loop execution and 'asyncio.to_thread' scenarios to ensure proper context isolation.
Test error handling by mocking internal functions using monkeypatch in backend Python tests.
Test resource cleanup in backend Python tests by using fixtures that ensure proper initialization and cleanup of resources.
Test timeout and performance constraints in backend Python tests using 'asyncio.wait_for' and timing assertions.
Test Langflow's Messag...

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
src/backend/**/components/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)

In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
{**/test_*.py,**/*.test.{ts,tsx}}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

{**/test_*.py,**/*.test.{ts,tsx}}: Warn when mocks replace testing real behavior/interactions in test files
Suggest using real objects or simpler test doubles when mocks become excessive
Ensure mocks are reserved for external dependencies, not core application logic, in tests
Test files should have descriptive test names that explain what is being validated
Organize tests logically with proper setup and teardown
Include edge cases and error conditions for comprehensive test coverage
Cover both positive and negative scenarios where appropriate
Tests must cover the main functionality being implemented
Avoid smoke-only tests; assert meaningful behavior and outcomes
Follow project testing frameworks (pytest for backend, Playwright for frontend)
For API endpoints, verify both success and error responses in tests

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/test_*.py: Backend test files must follow naming convention test_*.py
Backend tests should use proper pytest structure
For async Python code, use proper pytest async testing patterns (e.g., pytest-asyncio)

Files:

  • src/backend/tests/unit/components/data/test_news_search.py
  • src/backend/tests/unit/components/data/test_rss.py
🧬 Code graph analysis (3)
src/backend/tests/unit/components/data/test_news_search.py (2)
src/lfx/src/lfx/components/data/news_search.py (2)
  • NewsSearchComponent (12-167)
  • search_news (88-164)
src/backend/tests/base.py (1)
  • ComponentTestBaseWithoutClient (166-167)
src/lfx/src/lfx/components/data/news_search.py (2)
src/lfx/src/lfx/custom/custom_component/component.py (1)
  • log (1475-1492)
src/lfx/src/lfx/components/data/web_search.py (1)
  • clean_html (150-152)
src/backend/tests/unit/components/data/test_rss.py (2)
src/lfx/src/lfx/components/data/rss.py (2)
  • RSSReaderComponent (11-71)
  • read_rss (39-71)
src/backend/tests/base.py (1)
  • ComponentTestBaseWithoutClient (166-167)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Update Starter Projects
  • GitHub Check: Validate PR
🔇 Additional comments (11)
src/backend/tests/unit/components/data/test_rss.py (5)

11-27: LGTM! Proper test class structure.

Test class correctly inherits from ComponentTestBaseWithoutClient and provides all required fixtures as per coding guidelines.


29-64: LGTM! Comprehensive success scenario test.

Test properly mocks the external HTTP dependency and validates DataFrame structure, row count, columns, and data values. Well-structured and complete.


66-94: LGTM! Good edge case coverage.

Test validates the component handles missing RSS fields gracefully by returning empty strings, which aligns with the safe extraction logic in the component.


96-107: LGTM! Proper error handling test.

Test validates that network exceptions are caught and return a structured error DataFrame, matching the component's error handling behavior.


109-129: LGTM! Empty feed scenario well-tested.

Test validates that an empty RSS feed returns an empty DataFrame with correct schema, ensuring schema consistency as implemented in the component.

src/backend/tests/unit/components/data/test_news_search.py (4)

11-22: LGTM! Proper test class structure.

Test class correctly inherits from ComponentTestBaseWithoutClient and provides all required fixtures as per coding guidelines.


24-57: LGTM! Comprehensive success scenario test.

Test properly mocks the external HTTP dependency and validates DataFrame structure, row count, columns, and data values. Patch target is appropriate for module-level requests import.


59-67: LGTM! Proper error handling test.

Test validates that network exceptions are caught and return a structured error DataFrame with appropriate error messaging.


69-88: LGTM! Empty results scenario well-tested.

Test correctly validates that an empty news feed returns a single-row DataFrame with "No articles found", matching the component's implementation at lines 145-148 of news_search.py.

src/lfx/src/lfx/components/data/rss.py (1)

11-71: LGTM! Component implementation is solid.

The RSS reader correctly handles fetching, parsing, error cases, and returns a well-structured DataFrame. The legacy flag and replacement reference are appropriate for this restoration.

src/lfx/src/lfx/components/data/news_search.py (1)

12-167: LGTM! Component implementation handles multiple search modes well.

The NewsSearch component correctly handles topic, location, and keyword-based searches with proper error handling and HTML cleaning. The legacy flag and replacement reference are appropriate.

mock_response.content = mock_rss_content.encode("utf-8")
mock_response.raise_for_status = Mock()

with patch("requests.get", return_value=mock_response):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

The patch target should reference where the component imports requests, not the global module.

Apply this diff:

-        with patch("requests.get", return_value=mock_response):
+        with patch("lfx.components.data.news_search.requests.get", return_value=mock_response):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", return_value=mock_response):
with patch("lfx.components.data.news_search.requests.get", return_value=mock_response):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_news_search.py around line 49,
the test currently patches "requests.get" but must patch the name used inside
the component; change the patch target to the component's import path (e.g.
patch("backend.components.data.news_search.requests.get",
return_value=mock_response)) so the mock replaces requests.get where news_search
imports it.

assert news_results_df.iloc[1]["title"] == "Test News 2"

def test_news_search_error(self):
with patch("requests.get", side_effect=requests.RequestException("Network error")):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

Same issue as in test_successful_news_search.

Apply this diff:

-        with patch("requests.get", side_effect=requests.RequestException("Network error")):
+        with patch("lfx.components.data.news_search.requests.get", side_effect=requests.RequestException("Network error")):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", side_effect=requests.RequestException("Network error")):
with patch("lfx.components.data.news_search.requests.get", side_effect=requests.RequestException("Network error")):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_news_search.py around line 60,
the test patches "requests.get" but the component imports requests within its
module so the patch target must reference that module; change the patch target
to the module import path used by the code under test (e.g.
patch("src.backend.components.data.news.requests.get",
side_effect=requests.RequestException("Network error"))) so the mocked exception
is applied where the component actually calls requests.get.

mock_response.content = mock_rss_content.encode("utf-8")
mock_response.raise_for_status = Mock()

with patch("requests.get", return_value=mock_response):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

Same issue as in test_successful_news_search.

Apply this diff:

-        with patch("requests.get", return_value=mock_response):
+        with patch("lfx.components.data.news_search.requests.get", return_value=mock_response):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", return_value=mock_response):
with patch("lfx.components.data.news_search.requests.get", return_value=mock_response):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_news_search.py around line 82,
the patch target currently mocks "requests.get" but the component imports
requests from its module, so update the patch target to mock the requests.get
used by the module under test (e.g. patch
"src.backend.components.data.news_search.requests.get" to match how the
component imports requests) so the test actually intercepts the HTTP call.

mock_response.content = mock_rss_content.encode("utf-8")
mock_response.raise_for_status = Mock()

with patch("requests.get", return_value=mock_response):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

The patch target "requests.get" may not correctly intercept the call in RSSReaderComponent.read_rss(). Since the component imports requests directly (line 2 in rss.py), you should patch where the component uses it.

Apply this diff:

-        with patch("requests.get", return_value=mock_response):
+        with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", return_value=mock_response):
with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_rss.py around line 56, the patch
target "requests.get" won't intercept the call because rss.py imports requests
directly; change the patch target to the component import path (e.g.
"src.backend.components.data.rss.requests.get" or the exact module path used
when importing RSSReaderComponent) so the test patches the requests.get used
inside RSSReaderComponent.read_rss().

mock_response.content = mock_rss_content.encode("utf-8")
mock_response.raise_for_status = Mock()

with patch("requests.get", return_value=mock_response):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

Same issue as in test_successful_rss_fetch.

Apply this diff:

-        with patch("requests.get", return_value=mock_response):
+        with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", return_value=mock_response):
with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_rss.py around line 86, the test
patches "requests.get" but the component under test imports requests from its
module; change the patch target to the component's import path by replacing
patch("requests.get", return_value=mock_response) with
patch("backend.components.data.rss.requests.get", return_value=mock_response) so
the mocked GET is applied to the actual function used by the component.


def test_rss_fetch_error(self):
# Mock a failed request
with patch("requests.get", side_effect=requests.RequestException("Network error")):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

Same issue as in test_successful_rss_fetch.

Apply this diff:

-        with patch("requests.get", side_effect=requests.RequestException("Network error")):
+        with patch("lfx.components.data.rss.requests.get", side_effect=requests.RequestException("Network error")):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", side_effect=requests.RequestException("Network error")):
with patch("lfx.components.data.rss.requests.get", side_effect=requests.RequestException("Network error")):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_rss.py around line 98, the test
patches "requests.get" but the component imports requests locally, so update the
patch target to the component's import path (e.g. patch
"backend.components.data.rss.requests.get" to match the module under test) so
the mocked exception is applied where the code actually calls requests.get.

mock_response.content = mock_rss_content.encode("utf-8")
mock_response.raise_for_status = Mock()

with patch("requests.get", return_value=mock_response):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix patch target to match component import.

Same issue as in test_successful_rss_fetch.

Apply this diff:

-        with patch("requests.get", return_value=mock_response):
+        with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("requests.get", return_value=mock_response):
with patch("lfx.components.data.rss.requests.get", return_value=mock_response):
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/data/test_rss.py around line 123, the test
patches "requests.get" but the component under test imports requests from its
module, so the patch target must match that import; change the patch call to
target the component's requests import (e.g.
backend.components.data.rss.requests.get) so the mock replaces the function
actually used by the RSS fetcher.

@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 1, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 24.21%. Comparing base (bcabbd7) to head (f35dd56).
⚠️ Report is 1 commits behind head on main.

❌ Your project status has failed because the head coverage (47.24%) is below the target coverage (55.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10069      +/-   ##
==========================================
- Coverage   24.21%   24.21%   -0.01%     
==========================================
  Files        1091     1091              
  Lines       40014    40013       -1     
  Branches     5543     5542       -1     
==========================================
- Hits         9690     9689       -1     
  Misses      30153    30153              
  Partials      171      171              
Flag Coverage Δ
backend 47.24% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@erichare erichare enabled auto-merge October 1, 2025 17:15
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 2, 2025
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Oct 2, 2025

@erichare erichare added this pull request to the merge queue Oct 2, 2025
Merged via the queue into main with commit 2ff6b4d Oct 2, 2025
29 of 33 checks passed
@erichare erichare deleted the add-back-news-rss-comps branch October 2, 2025 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants