Files
upbeatBytes/tests/test_wotd.py
T
thejayman77 67d4bc32cb Small joys: Quote of the Day + Word of the Day engines
- quote.py: curated public-domain quote pool (16 seeded, admin-grows), deterministic daily
  pick, lazy AI "what it means" explainer of the real quote (cached). No LLM-invented quotes.
- wotd.py: LLM proposes positive words → validated/enriched against dictionaryapi.dev (real
  definition, IPA, examples, audio) → audio clip cached to our origin (TTS fallback) →
  deterministic daily pick. Tops the pool up toward 30/day.
- db.py: quote_pool/daily_quote + wotd_pool/daily_wotd tables.
- api.py: /api/quote/today, /api/word/today, /api/word/audio/{word} (GET+HEAD).
- cli.py: cycle steps for both (under --no-joys), shared LLM client.
- tests: test_quote.py (6) + test_wotd.py (5). 393 backend tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:28:55 -04:00

67 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Word of the Day: LLM-proposed words validated against the dictionary (mocked),
harvest dedupes + drops unknowns, audio cached when present, deterministic pick."""
import json
import pytest
from goodnews import wotd
from goodnews.db import connect, init_db
FAKE_DICT = {
"serene": {"word": "serene", "part_of_speech": "adjective", "phonetic": "/səˈriːn/",
"audio_url": "https://a/serene.mp3", "definition": "calm, peaceful, and untroubled",
"examples": ["a serene mountain lake"]},
"dawn": {"word": "dawn", "part_of_speech": "noun", "phonetic": "/dɔːn/",
"audio_url": None, "definition": "the first appearance of light in the sky", "examples": []},
}
class FakeClient:
def chat_text(self, messages):
return '{"words": ["serene", "dawn", "xyzzyq"]}' # xyzzyq isn't a real word
@pytest.fixture
def conn(tmp_path, monkeypatch):
monkeypatch.setenv("GOODNEWS_WOTD_AUDIO", str(tmp_path / "audio"))
monkeypatch.setattr(wotd, "_lookup", lambda w: FAKE_DICT.get(w)) # no dictionary network
monkeypatch.setattr(wotd, "_cache_audio", lambda url, word: f"{word}.mp3" if url else None)
c = connect(":memory:"); init_db(c)
yield c
c.close()
def test_harvest_validates_dedupes_and_caches_audio(conn):
r = wotd.harvest(conn, FakeClient())
assert r["added"] == 2 # serene + dawn; the nonsense word dropped
assert wotd.harvest(conn, FakeClient())["added"] == 0 # idempotent (word is UNIQUE)
assert conn.execute("SELECT audio_file FROM wotd_pool WHERE word='serene'").fetchone()[0] == "serene.mp3"
assert conn.execute("SELECT audio_file FROM wotd_pool WHERE word='dawn'").fetchone()[0] is None
def test_pick_caches_marks_shown_idempotent(conn):
wotd.harvest(conn, FakeClient())
a = wotd.pick_daily(conn, feature_date="2026-06-22")
assert a and a["word"] in ("serene", "dawn") and a["definition"]
assert json.loads(a["examples"]) == FAKE_DICT[a["word"]]["examples"]
shown = conn.execute("SELECT shown_at FROM wotd_pool WHERE id=?", (a["pool_id"],)).fetchone()[0]
assert shown == "2026-06-22"
assert wotd.pick_daily(conn, feature_date="2026-06-22")["pool_id"] == a["pool_id"]
def test_featured_pinned(conn):
wotd.harvest(conn, FakeClient())
conn.execute("UPDATE wotd_pool SET featured=1 WHERE word='dawn'"); conn.commit()
assert wotd.pick_daily(conn, feature_date="2026-06-22", force=True)["word"] == "dawn"
def test_get_today_never_empty(conn):
wotd.harvest(conn, FakeClient())
a = wotd.pick_daily(conn, feature_date="2026-06-22")
assert wotd.get_today(conn, "2099-01-01")["pool_id"] == a["pool_id"]
def test_run_daily_bootstraps(conn):
r = wotd.run_daily(conn, client=FakeClient())
assert r["pool"] == 2 and r["picked"] in ("serene", "dawn")