Files
upbeatBytes/tests/test_quote.py
T
thejayman77 0ae789752e fix: QOTD/WOTD freshness — pick within the freshest cohort, not the rotated pool
Both selectors ordered candidates least-recently-shown, then daily.seeded_order()
ROTATED the whole list and took [0] — an arbitrary date-hashed item, undoing the
ordering. Result: repeats (quote id 2 on 6/28+6/29; word "harmony" on 6/25+6/28),
no guarantee a pool item is shown before it recurs.

Fix: daily.freshest(rows) returns the freshest cohort only — every NEVER-shown
item while any remain, else the oldest-shown group. quote/wotd _candidates use it;
seeded_order now picks deterministically WITHIN that cohort. So every pool item is
featured once before any repeat, then cycles oldest-first. Dropped the unused
_NO_REPEAT_POOL window. Tests: no-repeat-until-exhausted (quote + wotd) + a
freshest() unit test. 428 backend tests green.

(Separate follow-up: expand the QOTD pool from 16 → 90+ vetted public-domain
quotes for a longer no-repeat window.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 05:39:06 -04:00

84 lines
3.2 KiB
Python

"""Quote of the Day: curated seed (idempotent), deterministic pick (idempotent,
blocked/featured), lazy AI meaning, never-empty get_today."""
import pytest
from goodnews import quote
from goodnews.db import connect, init_db
class FakeClient:
def chat_text(self, messages):
return "It means contentment is built from within, not from circumstance."
@pytest.fixture
def conn():
c = connect(":memory:"); init_db(c)
yield c
c.close()
def test_seed_idempotent(conn):
assert quote.seed(conn) == len(quote.SEED)
assert quote.seed(conn) == 0
assert conn.execute("SELECT COUNT(*) FROM quote_pool").fetchone()[0] == len(quote.SEED)
def test_pick_caches_marks_shown_idempotent(conn):
quote.seed(conn)
a = quote.pick_daily(conn, feature_date="2026-06-22")
assert a and a["text"] and a["author"]
shown = conn.execute("SELECT shown_at FROM quote_pool WHERE id=?", (a["pool_id"],)).fetchone()[0]
assert shown == "2026-06-22"
assert quote.pick_daily(conn, feature_date="2026-06-22")["pool_id"] == a["pool_id"]
def test_meaning_generated_lazily_and_cached(conn):
quote.seed(conn)
a = quote.pick_daily(conn, feature_date="2026-06-22", client=FakeClient())
assert a["meaning"].startswith("It means")
pool_meaning = conn.execute("SELECT meaning FROM quote_pool WHERE id=?", (a["pool_id"],)).fetchone()[0]
assert pool_meaning == a["meaning"] # cached on the pool row, not regenerated
def test_featured_pinned(conn):
quote.seed(conn)
conn.execute("UPDATE quote_pool SET featured=1 WHERE author='Rumi'"); conn.commit()
assert quote.pick_daily(conn, feature_date="2026-06-22", force=True)["author"] == "Rumi"
def test_get_today_never_empty(conn):
quote.seed(conn)
a = quote.pick_daily(conn, feature_date="2026-06-22")
assert quote.get_today(conn, "2099-01-01")["pool_id"] == a["pool_id"]
def test_run_daily_seeds_then_picks(conn):
r = quote.run_daily(conn)
assert r["pool"] == len(quote.SEED) and r["picked"]
def test_no_repeat_until_pool_exhausted(conn):
"""Every quote is featured exactly once before ANY repeat; then the oldest-shown
repeats first. (Regression for the rotate-the-whole-pool selector bug.)"""
import datetime
quote.seed(conn)
n = len(quote.SEED)
d0 = datetime.date(2026, 1, 1)
picks = [quote.pick_daily(conn, feature_date=(d0 + datetime.timedelta(days=i)).isoformat())["pool_id"]
for i in range(n)]
assert len(set(picks)) == n # full coverage, no repeat within the pool
nxt = (d0 + datetime.timedelta(days=n)).isoformat()
assert quote.pick_daily(conn, feature_date=nxt)["pool_id"] == picks[0] # oldest repeats first
def test_freshest_cohort():
from goodnews import daily
# never-shown win outright (the oldest shown item is ignored while any never-shown remain)
assert daily.freshest([{"id": 1, "shown_at": "2026-01-02"},
{"id": 2, "shown_at": None}, {"id": 3, "shown_at": None}]) == [2, 3]
# all shown → only the oldest-shown cohort
assert daily.freshest([{"id": 1, "shown_at": "2026-01-03"},
{"id": 2, "shown_at": "2026-01-01"}, {"id": 3, "shown_at": "2026-01-01"}]) == [2, 3]
assert daily.freshest([]) == []