Files
siftlode/backend/tests/test_followed_channels.py
T
peter 0517de1f59 fix: poll and backfill only channels somebody follows
The scheduled RSS poll and recent backfill covered every channel row,
but rows also come from search results, playlist sync and dropped
subscriptions, and nothing deletes them. On prod 582 of 979 polled
channels had no follower, three of them dead feeds answering 404 on
every poll. Both jobs now take subscribed or explored channels only,
and the scheduler card counts the same set. As a deliberate trade-off,
the shared Library no longer receives new uploads from channels nobody
follows.
2026-09-17 00:38:46 +02:00

64 lines
2.5 KiB
Python

"""The scheduled RSS poll and recent backfill cover FOLLOWED channels only (owner decision, 2026-09-17).
A channel row also comes from a search result, a playlist item or a subscription somebody dropped,
and nothing deletes those rows. Polling all of them was 582 of 979 channels on prod with no follower,
three of them dead feeds answering 404 every 20 minutes. Followed = subscribed by someone, or explored
by someone. The admin card counting "channels to sync" must use the same selection, or it counts
channels the backfill will never touch. DB lane.
"""
from app.models import Channel, ExploredChannel, Subscription
from app.sync import runner
def _channels(db, make_user):
user = make_user()
for cid in ("UC_sub", "UC_explored", "UC_search", "UC_playlist"):
db.add(Channel(id=cid, title=cid, from_search=cid == "UC_search"))
db.flush()
db.add(Subscription(user_id=user.id, channel_id="UC_sub"))
db.add(ExploredChannel(user_id=user.id, channel_id="UC_explored"))
db.commit()
return user
def test_the_rss_poll_skips_channels_nobody_follows(db, make_user, monkeypatch):
_channels(db, make_user)
polled: list[str] = []
monkeypatch.setattr(runner, "fetch_channel_feed", lambda cid: polled.append(cid) or [])
monkeypatch.setattr(runner, "apply_rss_feed", lambda db, ch, entries: 0)
assert runner.run_rss_poll(db) == {"new": 0, "failed": 0}
assert sorted(polled) == ["UC_explored", "UC_sub"]
def test_the_recent_backfill_skips_channels_nobody_follows(db, make_user, monkeypatch):
user = _channels(db, make_user)
done: list[str] = []
class _Client:
def __init__(self, *a):
pass
def __enter__(self):
return self
def __exit__(self, *a):
return False
monkeypatch.setattr(runner, "get_service_user", lambda db: user)
monkeypatch.setattr(runner, "YouTubeClient", _Client)
monkeypatch.setattr(runner.quota, "backfill_reserve_reached", lambda: False)
monkeypatch.setattr(
runner, "backfill_channel_recent", lambda db, yt, ch: done.append(ch.id) or 0
)
monkeypatch.setattr(runner, "reconcile_full_history", lambda db: 0)
runner.run_recent_backfill(db)
assert sorted(done) == ["UC_explored", "UC_sub"]
def test_the_dashboard_counts_the_channels_the_backfill_will_process(db, make_user, as_user):
_channels(db, make_user)
admin = make_user(role="admin")
queue = as_user(admin).get("/api/admin/scheduler").json()["queue"]
assert queue["channels_recent_pending"] == 2