返回 last30days-skill
test_reddit_dedicated.py
根目录 / tests / test_reddit_dedicated.py
1 """Tests for the dedicated-subreddit lane in reddit_keyless (U1).
2
3 A dedicated subreddit (the entity's home, e.g. r/Kanye for "Kanye West") is
4 wholly on-topic: pulled in full via top+hot+new listings and exempt from the
5 relevance floor, so an on-topic post whose title lacks the entity name is kept.
6 """
7
8 from unittest import mock
9
10 from lib import reddit_keyless
11
12
13 def _post(i, date="2026-05-20", rel=0.0):
14 url = f"https://www.reddit.com/r/test/comments/{i:06d}/post_{i}/"
15 return {
16 "id": "", "title": f"Post {i}", "url": url, "score": 0, "num_comments": 0,
17 "subreddit": "test", "created_utc": None, "author": "u", "selftext": "",
18 "date": date, "engagement": {"score": 0, "num_comments": 0, "upvote_ratio": None},
19 "relevance": rel, "why_relevant": "Reddit RSS", "metadata": {},
20 }
21
22
23 def _listing_post(i, score, title, rel=0.0):
24 p = _post(i, rel=rel)
25 p["title"] = title
26 p["score"] = score
27 p["engagement"]["score"] = score
28 p["why_relevant"] = "Reddit listing"
29 p["metadata"] = {"post_id": f"{i:06d}"}
30 return p
31
32
33 def _no_enrich():
34 return mock.patch.object(
35 reddit_keyless.reddit_shreddit, "fetch_comments",
36 return_value={"top_comments": [], "comment_insights": [], "num_comments": None},
37 )
38
39
40 class TestDedicatedLane:
41 def test_dedicated_listings_pulled_with_top_hot_new_and_marked(self):
42 ded = _listing_post(1, 2643, "What the actual fuck is this ye?")
43 ded["subreddit"] = "Kanye" # Match the requested dedicated subreddit.
44 captured = {}
45
46 def fake_fetch(subs, depth="default", query="", sorts=None):
47 if sorts == reddit_keyless.DEDICATED_SORTS:
48 captured["sorts"] = sorts
49 captured["subs"] = subs
50 return [ded]
51 return []
52
53 with mock.patch.object(reddit_keyless.reddit_listing, "fetch_listings",
54 side_effect=fake_fetch), \
55 mock.patch.object(reddit_keyless.reddit_arctic, "fetch_listings",
56 return_value=[]), \
57 mock.patch.object(reddit_keyless.reddit_rss, "search_rss", return_value=[]):
58 out = reddit_keyless._discover("Kanye West", "default", None,
59 dedicated_subreddits=["Kanye"])
60 assert captured["sorts"] == ["top", "hot", "new"]
61 assert captured["subs"] == ["Kanye"]
62 assert len(out) == 1
63 assert out[0]["dedicated"] is True
64
65 def test_dedicated_post_survives_floor_without_entity_name(self):
66 # On-topic dedicated post whose title lacks "Kanye" (relevance 0) must be
67 # kept; off-topic non-dedicated posts (relevance 0) are floored out.
68 ded = _listing_post(1, 2284, "There's 2 types of people", rel=0.0)
69 ded["dedicated"] = True
70 offtopic = [_post(10 + i, rel=0.0) for i in range(5)]
71 with mock.patch.object(reddit_keyless, "_discover", return_value=[ded] + offtopic), \
72 _no_enrich():
73 out = reddit_keyless.search_and_enrich("Kanye West", "2026-05-01", "2026-05-31")
74 urls = {p["url"] for p in out}
75 assert ded["url"] in urls # dedicated kept despite relevance 0
76 assert all(o["url"] not in urls for o in offtopic) # off-topic floored
77
78 def test_dedicated_dedup_keeps_floor_exempt_status(self):
79 # A thread present in both the dedicated lane and a broad listing keeps
80 # its dedicated (floor-exempt) flag — dedicated is merged first.
81 shared_ded = _listing_post(1, 500, "fresh thread", rel=0.0)
82 shared_ded["subreddit"] = "Kanye" # Match the requested dedicated subreddit.
83 shared_broad = _listing_post(1, 500, "fresh thread", rel=0.0) # same url/id
84 shared_broad["subreddit"] = "hiphopheads" # Match the requested broad subreddit.
85
86 def fake_fetch(subs, depth="default", query="", sorts=None):
87 return [shared_ded] if sorts == reddit_keyless.DEDICATED_SORTS else [shared_broad]
88
89 with mock.patch.object(reddit_keyless.reddit_listing, "fetch_listings",
90 side_effect=fake_fetch), \
91 mock.patch.object(reddit_keyless.reddit_rss, "search_rss", return_value=[]):
92 out = reddit_keyless._discover("Kanye West", "default", ["hiphopheads"],
93 dedicated_subreddits=["Kanye"])
94 same = [p for p in out if p["url"] == shared_ded["url"]]
95 assert len(same) == 1
96 assert same[0].get("dedicated") is True
97
98 def test_no_dedicated_subs_is_noop(self):
99 with mock.patch.object(reddit_keyless.reddit_rss, "search_rss",
100 return_value=[_post(1)]), \
101 mock.patch.object(reddit_keyless.reddit_listing, "fetch_listings",
102 return_value=[]):
103 out = reddit_keyless._discover("topic", "default", ["test"])
104 assert all(not p.get("dedicated") for p in out)
105
105 lines PYTHON