diff --git a/home-mixer/filters/viewer_muted_keyword_filter.rs b/home-mixer/filters/viewer_muted_keyword_filter.rs index 482a8182..c579818f 100644 --- a/home-mixer/filters/viewer_muted_keyword_filter.rs +++ b/home-mixer/filters/viewer_muted_keyword_filter.rs @@ -43,8 +43,7 @@ impl Filter for ViewerMutedKeywordFilter { let mut removed = Vec::new(); for candidate in candidates { - let tweet_text_token_sequence = tokenizer.tokenize(&candidate.tweet_text); - if matcher.matches(&tweet_text_token_sequence) { + if candidate_matches(&candidate, &tokenizer, &matcher) { removed.push(candidate); } else { kept.push(candidate); @@ -56,6 +55,17 @@ impl Filter for ViewerMutedKeywordFilter { } } +fn candidate_matches( + candidate: &PostCandidate, + tokenizer: &TweetTokenizer, + matcher: &MatchTweetGroup, +) -> bool { + std::iter::once(candidate.tweet_text.as_str()) + .chain(candidate.author_screen_name.as_deref()) + .filter(|text| !text.is_empty()) + .any(|text| matcher.matches(&tokenizer.tokenize(text))) +} + #[cfg(test)] mod tests { use super::*; @@ -315,4 +325,37 @@ mod tests { assert_eq!(result.kept[0].tweet_id, 4); assert_eq!(result.removed.len(), 3); } + + #[tokio::test(flavor = "multi_thread")] + async fn drops_when_author_handle_matches_muted_keyword() { + let filter = ViewerMutedKeywordFilter::new(); + let query = create_test_query(vec!["mutedkeyword".to_string()]); + + let mut handle_only = create_test_candidate(1, "hello"); + handle_only.author_screen_name = Some("mutedkeyword".to_string()); + + let mut other_handle = create_test_candidate(2, "hello"); + other_handle.author_screen_name = Some("otheruser".to_string()); + + let result = filter.filter(&query, vec![handle_only, other_handle]); + + assert_eq!(result.kept.len(), 1); + assert_eq!(result.kept[0].tweet_id, 2); + assert_eq!(result.removed.len(), 1); + assert_eq!(result.removed[0].tweet_id, 1); + } + + #[tokio::test(flavor = "multi_thread")] + async fn keeps_when_author_handle_does_not_match() { + let filter = ViewerMutedKeywordFilter::new(); + let query = create_test_query(vec!["mutedkeyword".to_string()]); + + let mut candidate = create_test_candidate(1, "hello"); + candidate.author_screen_name = Some("otheruser".to_string()); + + let result = filter.filter(&query, vec![candidate]); + + assert_eq!(result.kept.len(), 1); + assert!(result.removed.is_empty()); + } }