kink-discovery / tests /test_recommend_cache_invalidation_contract.py
Perplexed7675's picture
Sync from kink_cli (Docker Space)
6ff91d6 verified
Raw
History Blame Contribute Delete
2.31 kB
"""Recommendation freshness contracts."""
from __future__ import annotations
import shutil
from pathlib import Path
import pytest
from backend.core import Backend
_SEED = Path(__file__).resolve().parent.parent / "deploy/hf/seed/hf_bundled_store.db"
@pytest.mark.skipif(not _SEED.is_file(), reason="bundled seed DB not present")
def test_saved_recommendation_kink_must_not_appear_in_following_recommend_list(tmp_path: Path) -> None:
"""Fails when HTTP cache is not invalidated on play save (stale deck still lists the saved kink)."""
dest = tmp_path / "rec_inval.db"
shutil.copyfile(_SEED, dest)
b = Backend(dest)
u = b.create_user()
first = b.recommend(u.id, limit=8)
kid = first[0]["kink"]["id"]
b.save_play_preference(u.id, kid, "like", ["together"])
after = b.recommend(u.id, limit=8)
ids = {x["kink"]["id"] for x in after}
assert kid not in ids, "saved kink must be excluded after invalidate + recompute"
@pytest.mark.skipif(not _SEED.is_file(), reason="bundled seed DB not present")
def test_recommendations_are_fresh_without_http_response_cache(tmp_path: Path) -> None:
"""Back-to-back stochastic lists may differ, but must stay valid and uncached."""
dest = tmp_path / "rec_fresh.db"
shutil.copyfile(_SEED, dest)
b = Backend(dest)
u = b.create_user()
a = b.recommend(u.id, limit=8)
b2 = b.recommend(u.id, limit=8)
assert a and b2
for batch in (a, b2):
ids = [x["kink"]["id"] for x in batch]
assert len(ids) == len(set(ids))
assert not (set(ids) & set(b.get_user(u.id)["plays"]))
assert not hasattr(b, "_recommend_http_cache")
@pytest.mark.skipif(not _SEED.is_file(), reason="bundled seed DB not present")
def test_play_board_lists_dual_direction_play_in_to_me_and_by_me(tmp_path: Path) -> None:
"""Server board must place one play in every active direction bucket (regression guard)."""
dest = tmp_path / "board_dual.db"
shutil.copyfile(_SEED, dest)
b = Backend(dest)
u = b.create_user()
kid = next(iter(b._catalog()["detail_by_id"]))
b.save_play_preference(u.id, kid, "like", ["to_me", "by_me"])
board = b.play_board(u.id)
to_me = {x["id"] for x in board["to_me"]}
by_me = {x["id"] for x in board["by_me"]}
assert kid in to_me and kid in by_me