"""Relevance ranks only the newest RANK_WINDOW matches (E31), DB-lane. A broad word ("a") matched most of the prod library and ts_rank read every match's tsvector: 6.8 s a page. The ranking now covers the newest RANK_WINDOW matches and the rest follow newest first. The window's start rides the cursor, so a video ingested mid-scroll cannot push a row behind the cursor and repeat it. """ from datetime import datetime, timezone import pytest from app import feedquery from app.models import Channel, Subscription, User, Video def _video(vid: str, day: int, title: str) -> Video: return Video( id=vid, channel_id="UCw", published_at=datetime(2024, 1, day, tzinfo=timezone.utc), title=title, is_short=False, live_status="none", via_search=False, via_explore=False, ) def _seed(db) -> User: db.add(Channel(id="UCw", title="Window")) user = User(email="window@example.com", email_verified=True) db.add(user) db.flush() db.add(Subscription(user_id=user.id, channel_id="UCw", priority=0, hidden=False)) # m1 is the oldest and the strongest match, m4 the strongest of the newest three; the rest tie on one # title "foo" each (ts_rank counts occurrences, it does not normalise by length). db.add_all( [ _video("m1", 1, "foo foo foo foo foo"), _video("m2", 2, "foo and some other words here"), _video("m3", 3, "foo plus some filler words"), _video("m4", 4, "foo foo foo"), _video("m5", 5, "foo with a longer title"), _video("m6", 6, "foo with yet another title"), ] ) db.commit() return user def _ids(client, cursor=None, limit=50): url = f"/api/feed?q=foo&sort=relevance&limit={limit}" if cursor: url += f"&cursor={cursor}" resp = client.get(url) assert resp.status_code == 200, resp.text body = resp.json() return [it["id"] for it in body["items"]], body["next_cursor"] def test_a_specific_word_ranks_every_match(db, as_user): client = as_user(_seed(db)) ids, _ = _ids(client) assert ids[:2] == ["m1", "m4"], ids def test_a_broad_word_ranks_the_newest_window_and_the_rest_follow_newest_first( db, as_user, monkeypatch ): monkeypatch.setattr(feedquery, "RANK_WINDOW", 3) client = as_user(_seed(db)) ids, _ = _ids(client) assert ids[0] == "m4", ids # the strongest of the newest three assert sorted(ids[:3]) == ["m4", "m5", "m6"], ids assert ids[3:] == ["m3", "m2", "m1"], ids # past the window: newest first, m1 not ranked def test_paging_keeps_the_window_page_one_ranked_against(db, as_user, monkeypatch): monkeypatch.setattr(feedquery, "RANK_WINDOW", 3) client = as_user(_seed(db)) full, _ = _ids(client) first, cursor = _ids(client, limit=2) assert first == full[:2] # A newer match lands mid-scroll. Ranked against a recomputed window, m4 (shown on page one) would # fall out of it to rank 0, sort behind the cursor and come back on page two. db.add(_video("m7", 7, "foo arriving while the reader scrolls")) db.commit() walked = list(first) while cursor: page, cursor = _ids(client, cursor, limit=2) walked.extend(page) assert len(walked) == len(set(walked)), walked assert set(full) <= set(walked), walked @pytest.mark.parametrize( ("window", "limit"), # 3: the page is read as its two halves (the window ranked, the rest newest first), and pages of 2 # and 3 cross the window's edge mid-page and exactly at it. 2000: one ranked query. [(3, 2), (3, 3), (2000, 2)], ) def test_cursor_walk_matches_the_unpaged_order(db, as_user, monkeypatch, window, limit): monkeypatch.setattr(feedquery, "RANK_WINDOW", window) client = as_user(_seed(db)) full, _ = _ids(client) if window == 3: assert full == ["m4", "m6", "m5", "m3", "m2", "m1"] walked, cursor = _ids(client, limit=limit) while cursor: page, cursor = _ids(client, cursor, limit=limit) walked.extend(page) assert walked == full