|
9 | 9 | queue_content_skill, |
10 | 10 | recompute_authority_scores, |
11 | 11 | run_all_authority_recomputations, |
| 12 | + run_all_source_quality_recomputations, |
12 | 13 | run_relevance_scoring_skill, |
13 | 14 | run_summarization_skill, |
14 | 15 | ) |
@@ -86,6 +87,43 @@ def test_run_all_authority_recomputations_executes_inline_when_eager( |
86 | 87 | delay_mock.assert_not_called() |
87 | 88 |
|
88 | 89 |
|
| 90 | +def test_run_all_source_quality_recomputations_enqueues_all_projects( |
| 91 | + source_plugin_context, mocker |
| 92 | +): |
| 93 | + delay_mock = mocker.patch("core.tasks.recompute_source_quality.delay") |
| 94 | + other_project = Project.objects.create( |
| 95 | + name="Source Quality Project", |
| 96 | + topic_description="Signals", |
| 97 | + ) |
| 98 | + |
| 99 | + enqueued_count = run_all_source_quality_recomputations() |
| 100 | + |
| 101 | + assert enqueued_count == 2 |
| 102 | + delay_mock.assert_any_call(source_plugin_context.project.id) |
| 103 | + delay_mock.assert_any_call(_require_pk(other_project)) |
| 104 | + assert delay_mock.call_count == 2 |
| 105 | + |
| 106 | + |
| 107 | +def test_run_all_source_quality_recomputations_executes_inline_when_eager( |
| 108 | + source_plugin_context, settings, mocker |
| 109 | +): |
| 110 | + settings.CELERY_TASK_ALWAYS_EAGER = True |
| 111 | + recompute_mock = mocker.patch("core.tasks.recompute_source_quality") |
| 112 | + delay_mock = mocker.patch("core.tasks.recompute_source_quality.delay") |
| 113 | + other_project = Project.objects.create( |
| 114 | + name="Inline Source Quality Project", |
| 115 | + topic_description="Signals", |
| 116 | + ) |
| 117 | + |
| 118 | + enqueued_count = run_all_source_quality_recomputations() |
| 119 | + |
| 120 | + assert enqueued_count == 2 |
| 121 | + recompute_mock.assert_any_call(source_plugin_context.project.id) |
| 122 | + recompute_mock.assert_any_call(_require_pk(other_project)) |
| 123 | + assert recompute_mock.call_count == 2 |
| 124 | + delay_mock.assert_not_called() |
| 125 | + |
| 126 | + |
89 | 127 | def test_recompute_authority_scores_updates_entities_and_creates_snapshots( |
90 | 128 | source_plugin_context, mocker |
91 | 129 | ): |
@@ -198,6 +236,62 @@ def test_recompute_authority_scores_updates_entities_and_creates_snapshots( |
198 | 236 | assert primary_snapshot.weights_at_compute["engagement"] == pytest.approx(0.15) |
199 | 237 |
|
200 | 238 |
|
| 239 | +def test_recompute_authority_scores_uses_bluesky_and_reddit_engagement_metadata( |
| 240 | + source_plugin_context, mocker |
| 241 | +): |
| 242 | + mocker.patch("content.signals.queue_topic_centroid_recompute") |
| 243 | + project = source_plugin_context.project |
| 244 | + ProjectConfig.objects.create(project=project) |
| 245 | + entity = source_plugin_context.entity |
| 246 | + bluesky_content = Content.objects.create( |
| 247 | + project=project, |
| 248 | + entity=entity, |
| 249 | + url="https://bsky.app/profile/example/post/abc", |
| 250 | + canonical_url="https://bsky.app/profile/example/post/abc", |
| 251 | + title="Bluesky authority content", |
| 252 | + author="example.bsky.social", |
| 253 | + source_plugin=SourcePluginName.BLUESKY, |
| 254 | + published_date="2026-04-28T12:00:00Z", |
| 255 | + content_text="Bluesky authority content.", |
| 256 | + source_metadata={"like_count": 4, "reply_count": 1, "repost_count": 2}, |
| 257 | + ) |
| 258 | + reddit_content = Content.objects.create( |
| 259 | + project=project, |
| 260 | + entity=entity, |
| 261 | + url="https://www.reddit.com/r/python/comments/abc123/test", |
| 262 | + canonical_url="https://www.reddit.com/r/python/comments/abc123/test", |
| 263 | + title="Reddit authority content", |
| 264 | + author="redditor", |
| 265 | + source_plugin=SourcePluginName.REDDIT, |
| 266 | + published_date="2026-04-28T13:00:00Z", |
| 267 | + content_text="Reddit authority content.", |
| 268 | + source_metadata={"score": 10, "comment_count": 3}, |
| 269 | + ) |
| 270 | + EntityMention.objects.create( |
| 271 | + project=project, |
| 272 | + content=bluesky_content, |
| 273 | + entity=entity, |
| 274 | + role=EntityMentionRole.AUTHOR, |
| 275 | + sentiment="positive", |
| 276 | + span="Example", |
| 277 | + confidence=0.9, |
| 278 | + ) |
| 279 | + EntityMention.objects.create( |
| 280 | + project=project, |
| 281 | + content=reddit_content, |
| 282 | + entity=entity, |
| 283 | + role=EntityMentionRole.AUTHOR, |
| 284 | + sentiment="neutral", |
| 285 | + span="Example", |
| 286 | + confidence=0.9, |
| 287 | + ) |
| 288 | + |
| 289 | + recompute_authority_scores(project.id) |
| 290 | + |
| 291 | + snapshot = EntityAuthoritySnapshot.objects.get(entity=entity) |
| 292 | + assert snapshot.engagement_component == pytest.approx(1.0) |
| 293 | + |
| 294 | + |
201 | 295 | def test_queue_content_skill_enqueues_relevance_task(source_plugin_context, mocker): |
202 | 296 | content = Content.objects.create( |
203 | 297 | project=source_plugin_context.project, |
|
0 commit comments