import json import os from datetime import date, datetime from unittest.mock import MagicMock, patch from PIL import Image as PILImage from src.models import Article, Image from src.scheduler import SchedulerManager def test_scheduler_starts_fetch_job(app): with app.app_context(): mgr = SchedulerManager(app) mgr.start() jobs = mgr.scheduler.get_jobs() job_ids = [j.id for j in jobs] assert "rss_fetch" in job_ids mgr.shutdown() def test_scheduler_update_fetch_interval(app): with app.app_context(): mgr = SchedulerManager(app) mgr.start() mgr.update_fetch_interval(2) job = mgr.scheduler.get_job("rss_fetch") assert job is not None assert job.trigger.interval.total_seconds() == 7200 mgr.shutdown() def test_scheduler_enable_auto_publish(app): with app.app_context(): mgr = SchedulerManager(app) mgr.start() mgr.enable_auto_publish(day_of_week="sun", hour=6, minute=0, cover_method="text") job = mgr.scheduler.get_job("auto_publish") assert job is not None mgr.shutdown() def test_scheduler_disable_auto_publish(app): with app.app_context(): mgr = SchedulerManager(app) mgr.start() mgr.enable_auto_publish(day_of_week="sun", hour=6, minute=0, cover_method="text") mgr.disable_auto_publish() job = mgr.scheduler.get_job("auto_publish") assert job is None mgr.shutdown() def test_scheduler_get_status(app): with app.app_context(): mgr = SchedulerManager(app) mgr.start() status = mgr.get_status() assert status["running"] is True assert "rss_fetch" in status mgr.shutdown() def test_auto_publish_passes_ordered_image_paths_to_generate_cover(app, tmp_path, db): """First image per article in pub_date order passed to generate_cover.""" os.makedirs(tmp_path, exist_ok=True) img1 = str(tmp_path / "a1.jpg") img2 = str(tmp_path / "a2.jpg") for p in (img1, img2): PILImage.new("RGB", (100, 100), color="blue").save(p, format="JPEG") with app.app_context(): a1 = Article( guid="g1", title="Earlier Article", author="A", pub_date=datetime(2026, 4, 6, 10, 0), categories=json.dumps(["Government"]), link="http://example.com/1", content_html="

x

", ) a2 = Article( guid="g2", title="Later Article", author="B", pub_date=datetime(2026, 4, 7, 10, 0), categories=json.dumps(["Culture"]), link="http://example.com/2", content_html="

y

", ) db.session.add_all([a1, a2]) db.session.flush() db.session.add_all( [ Image( article_id=a1.id, original_url="https://example.com/1.jpg", local_path=img1, width=100, height=100, ), Image( article_id=a2.id, original_url="https://example.com/2.jpg", local_path=img2, width=100, height=100, ), ] ) db.session.commit() mock_cover = MagicMock(return_value="/fake/cover.jpg") mock_epub = MagicMock(return_value="/fake/issue.epub") with patch("src.scheduler.date") as mock_date, patch( "src.cover.generate_cover", mock_cover ), patch("src.epub_builder.build_epub", mock_epub): mock_date.today.return_value = date(2026, 4, 6) mgr = SchedulerManager(app) mgr._run_auto_publish() mock_cover.assert_called_once() args = mock_cover.call_args[0] assert args[0] == "text" assert args[4] == ["Earlier Article", "Later Article"] assert args[5] == [img1, img2]