import json from unittest.mock import patch, MagicMock from src.fetcher import fetch_and_cache_articles from src.models import Article, Image from tests.conftest import SAMPLE_RSS_XML def _mock_feed_response(xml_content): mock = MagicMock() mock.content = xml_content.encode("utf-8") mock.text = xml_content mock.status_code = 200 mock.raise_for_status = MagicMock() return mock def test_fetch_creates_articles(app, db): with app.app_context(): with patch("src.fetcher.requests.get") as mock_get: mock_get.return_value = _mock_feed_response(SAMPLE_RSS_XML) with patch("src.fetcher.process_image") as mock_img: mock_img.return_value = ("/fake/path.jpg", 800, 450) result = fetch_and_cache_articles() assert result["new"] == 2 assert result["skipped"] == 0 articles = Article.query.order_by(Article.pub_date).all() assert len(articles) == 2 assert articles[0].title == "Test Article One" assert articles[1].title == "Test Article Two" def test_fetch_deduplicates(app, db): with app.app_context(): with patch("src.fetcher.requests.get") as mock_get: mock_get.return_value = _mock_feed_response(SAMPLE_RSS_XML) with patch("src.fetcher.process_image") as mock_img: mock_img.return_value = ("/fake/path.jpg", 800, 450) fetch_and_cache_articles() result = fetch_and_cache_articles() assert result["new"] == 0 assert result["skipped"] == 2 assert Article.query.count() == 2 def test_fetch_downloads_images(app, db): with app.app_context(): with patch("src.fetcher.requests.get") as mock_get: mock_get.return_value = _mock_feed_response(SAMPLE_RSS_XML) with patch("src.fetcher.process_image") as mock_img: mock_img.return_value = ("/fake/path.jpg", 800, 450) fetch_and_cache_articles() images = Image.query.all() assert len(images) == 1 assert images[0].original_url == "https://example.com/image1.jpg" def test_fetch_rewrites_image_src(app, db): with app.app_context(): with patch("src.fetcher.requests.get") as mock_get: mock_get.return_value = _mock_feed_response(SAMPLE_RSS_XML) with patch("src.fetcher.process_image") as mock_img: mock_img.return_value = ("/fake/path.jpg", 800, 450) fetch_and_cache_articles() article = Article.query.filter_by( guid="https://example.com/?p=1001" ).first() assert "https://example.com/image1.jpg" not in article.content_html assert "/fake/path.jpg" in article.content_html def test_fetch_handles_feed_error(app, db): with app.app_context(): with patch("src.fetcher.requests.get") as mock_get: mock_get.side_effect = Exception("Network error") result = fetch_and_cache_articles() assert result["error"] is not None assert Article.query.count() == 0