Skip to content

Commit

Permalink
Add moderation::tests::quoteposts
Browse files Browse the repository at this point in the history
  • Loading branch information
sugyan committed Jun 5, 2024
1 parent 3d09886 commit cefa4a4
Show file tree
Hide file tree
Showing 6 changed files with 643 additions and 317 deletions.
6 changes: 3 additions & 3 deletions bsky-sdk/src/moderation/decision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ impl ModerationDecision {
}
pub(crate) fn merge(decisions: &[Self]) -> Self {
assert!(!decisions.is_empty());
assert!(decisions
.windows(2)
.all(|w| w[0].did == w[1].did && w[0].is_me == w[1].is_me));
// assert!(decisions
// .windows(2)
// .all(|w| w[0].did == w[1].did && w[0].is_me == w[1].is_me));
Self {
did: decisions[0].did.clone(),
is_me: decisions[0].is_me,
Expand Down
75 changes: 71 additions & 4 deletions bsky-sdk/src/moderation/subjects/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use super::super::decision::ModerationDecision;
use super::super::types::{LabelTarget, SubjectPost};
use super::super::Moderator;
use atrium_api::app::bsky::actor::defs::MutedWord;
use atrium_api::app::bsky::embed::record::{ViewBlocked, ViewRecord, ViewRecordRefs};
use atrium_api::app::bsky::feed::defs::PostViewEmbedRefs;
use atrium_api::app::bsky::richtext::facet::MainFeaturesItem;
use atrium_api::records::{KnownRecord, Record};
use atrium_api::types::Union;
Expand Down Expand Up @@ -29,10 +31,35 @@ impl Moderator {
acc.add_muted_word();
}

let embed_acc = Option::<ModerationDecision>::None;
if let Some(Union::Refs(embed)) = &subject.embed {
todo!()
}
let embed_acc = match &subject.embed {
Some(Union::Refs(PostViewEmbedRefs::AppBskyEmbedRecordView(view))) => {
match &view.record {
Union::Refs(ViewRecordRefs::ViewRecord(record)) => {
// quoted post
Some(self.decide_quoted_post(record))
}
Union::Refs(ViewRecordRefs::ViewBlocked(blocked)) => {
// blocked quote post
Some(self.decide_bloked_quoted_post(blocked))
}
_ => None,
}
}
Some(Union::Refs(PostViewEmbedRefs::AppBskyEmbedRecordWithMediaView(view))) => {
match &view.record.record {
Union::Refs(ViewRecordRefs::ViewRecord(record)) => {
// quoted post with media
Some(self.decide_quoted_post(record))
}
Union::Refs(ViewRecordRefs::ViewBlocked(blocked)) => {
// blocked quote post with media
Some(self.decide_bloked_quoted_post(blocked))
}
_ => None,
}
}
_ => None,
};

let mut decisions = vec![acc];
if let Some(mut embed_acc) = embed_acc {
Expand All @@ -43,6 +70,46 @@ impl Moderator {
decisions.extend([self.decide_account(&author), self.decide_profile(&author)]);
ModerationDecision::merge(&decisions)
}
fn decide_quoted_post(&self, subject: &ViewRecord) -> ModerationDecision {
let mut acc = ModerationDecision::new();
acc.set_did(subject.author.did.clone());
acc.set_is_me(self.user_did.as_ref() == Some(&subject.author.did));
if let Some(labels) = &subject.labels {
for label in labels {
acc.add_label(LabelTarget::Content, label, self);
}
}
ModerationDecision::merge(&[
acc,
self.decide_account(&subject.author.clone().into()),
self.decide_profile(&subject.author.clone().into()),
])
}
fn decide_bloked_quoted_post(&self, subject: &ViewBlocked) -> ModerationDecision {
let mut acc = ModerationDecision::new();
acc.set_did(subject.author.did.clone());
acc.set_is_me(self.user_did.as_ref() == Some(&subject.author.did));
if let Some(viewer) = &subject.author.viewer {
if viewer.muted.unwrap_or_default() {
if let Some(list_view) = &viewer.muted_by_list {
acc.add_muted_by_list(list_view);
} else {
acc.add_muted();
}
}
if viewer.blocking.is_some() {
if let Some(list_view) = &viewer.blocking_by_list {
acc.add_blocking_by_list(list_view);
} else {
acc.add_blocking();
}
}
if viewer.blocked_by.unwrap_or_default() {
acc.add_blocked_by();
}
}
acc
}
}

fn check_muted_words(subject: &SubjectPost, muted_words: &[MutedWord]) -> bool {
Expand Down
95 changes: 36 additions & 59 deletions bsky-sdk/src/moderation/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod behaviors;
mod custom_labels;
mod mutewords;
mod quoteposts;

use crate::moderation::decision::{DecisionContext, ModerationDecision};
use crate::moderation::types::*;
Expand All @@ -16,7 +17,7 @@ use std::collections::HashMap;
const FAKE_CID: &str = "bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq";

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ModerationTestResultFlag {
enum ResultFlag {
Filter,
Blur,
Alert,
Expand All @@ -25,19 +26,19 @@ enum ModerationTestResultFlag {
}

#[derive(Debug, Default)]
struct TestExpectedBehaviors {
profile_list: Vec<ModerationTestResultFlag>,
profile_view: Vec<ModerationTestResultFlag>,
avatar: Vec<ModerationTestResultFlag>,
banner: Vec<ModerationTestResultFlag>,
display_name: Vec<ModerationTestResultFlag>,
content_list: Vec<ModerationTestResultFlag>,
content_view: Vec<ModerationTestResultFlag>,
content_media: Vec<ModerationTestResultFlag>,
struct ExpectedBehaviors {
profile_list: Vec<ResultFlag>,
profile_view: Vec<ResultFlag>,
avatar: Vec<ResultFlag>,
banner: Vec<ResultFlag>,
display_name: Vec<ResultFlag>,
content_list: Vec<ResultFlag>,
content_view: Vec<ResultFlag>,
content_media: Vec<ResultFlag>,
}

impl TestExpectedBehaviors {
fn expected_for(&self, context: DecisionContext) -> &Vec<ModerationTestResultFlag> {
impl ExpectedBehaviors {
fn expected_for(&self, context: DecisionContext) -> &Vec<ResultFlag> {
match context {
DecisionContext::ProfileList => &self.profile_list,
DecisionContext::ProfileView => &self.profile_view,
Expand Down Expand Up @@ -110,11 +111,7 @@ fn label(src: &str, uri: &str, val: &str) -> Label {
}
}

fn assert_ui(
decision: &ModerationDecision,
expected: &[ModerationTestResultFlag],
context: DecisionContext,
) {
fn assert_ui(decision: &ModerationDecision, expected: &[ResultFlag], context: DecisionContext) {
let ui = decision.ui(context);
if expected.is_empty() {
assert!(
Expand All @@ -137,31 +134,31 @@ fn assert_ui(
} else {
assert_eq!(
ui.inform(),
expected.contains(&ModerationTestResultFlag::Inform),
expected.contains(&ResultFlag::Inform),
"inform should be {} for context {context:?}",
!ui.inform()
);
assert_eq!(
ui.alert(),
expected.contains(&ModerationTestResultFlag::Alert),
expected.contains(&ResultFlag::Alert),
"alert should be {} for context {context:?}",
!ui.alert()
);
assert_eq!(
ui.blur(),
expected.contains(&ModerationTestResultFlag::Blur),
expected.contains(&ResultFlag::Blur),
"blur should be {} for context {context:?}",
!ui.blur()
);
assert_eq!(
ui.filter(),
expected.contains(&ModerationTestResultFlag::Filter),
expected.contains(&ResultFlag::Filter),
"filter should be {} for context {context:?}",
!ui.filter()
);
assert_eq!(
ui.no_override,
expected.contains(&ModerationTestResultFlag::NoOverride),
expected.contains(&ResultFlag::NoOverride),
"no_override should be {} for context {context:?}",
!ui.no_override
);
Expand Down Expand Up @@ -191,11 +188,7 @@ fn self_label_global() {
HashMap::new(),
);
let result = moderator.moderate_profile(&profile);
assert_ui(
&result,
&[ModerationTestResultFlag::Blur],
DecisionContext::Avatar,
)
assert_ui(&result, &[ResultFlag::Blur], DecisionContext::Avatar)
}
// porn (ignore)
{
Expand Down Expand Up @@ -350,8 +343,8 @@ fn prioritize_custom_labels() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![ModerationTestResultFlag::Inform],
DecisionContext::ContentView => vec![ModerationTestResultFlag::Inform],
DecisionContext::ContentList => vec![ResultFlag::Inform],
DecisionContext::ContentView => vec![ResultFlag::Inform],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand Down Expand Up @@ -399,15 +392,10 @@ fn does_not_override_imperative_labels() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![
ModerationTestResultFlag::Filter,
ModerationTestResultFlag::Blur,
ModerationTestResultFlag::NoOverride,
],
DecisionContext::ContentView => vec![
ModerationTestResultFlag::Blur,
ModerationTestResultFlag::NoOverride,
],
DecisionContext::ContentList => {
vec![ResultFlag::Filter, ResultFlag::Blur, ResultFlag::NoOverride]
}
DecisionContext::ContentView => vec![ResultFlag::Blur, ResultFlag::NoOverride],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand Down Expand Up @@ -551,11 +539,8 @@ fn custom_labels_with_default_settings() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![
ModerationTestResultFlag::Filter,
ModerationTestResultFlag::Blur,
],
DecisionContext::ContentView => vec![ModerationTestResultFlag::Inform],
DecisionContext::ContentList => vec![ResultFlag::Filter, ResultFlag::Blur],
DecisionContext::ContentView => vec![ResultFlag::Inform],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand All @@ -573,8 +558,8 @@ fn custom_labels_with_default_settings() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![ModerationTestResultFlag::Blur],
DecisionContext::ContentView => vec![ModerationTestResultFlag::Inform],
DecisionContext::ContentList => vec![ResultFlag::Blur],
DecisionContext::ContentView => vec![ResultFlag::Inform],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand Down Expand Up @@ -637,15 +622,10 @@ fn custom_labels_require_adult_content_enabled() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![
ModerationTestResultFlag::Filter,
ModerationTestResultFlag::Blur,
ModerationTestResultFlag::NoOverride,
],
DecisionContext::ContentView => vec![
ModerationTestResultFlag::Blur,
ModerationTestResultFlag::NoOverride,
],
DecisionContext::ContentList => {
vec![ResultFlag::Filter, ResultFlag::Blur, ResultFlag::NoOverride]
}
DecisionContext::ContentView => vec![ResultFlag::Blur, ResultFlag::NoOverride],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand Down Expand Up @@ -679,11 +659,8 @@ fn adult_content_disabled_forces_hide() {
));
for context in DecisionContext::ALL {
let expected = match context {
DecisionContext::ContentList => vec![ModerationTestResultFlag::Filter],
DecisionContext::ContentMedia => vec![
ModerationTestResultFlag::Blur,
ModerationTestResultFlag::NoOverride,
],
DecisionContext::ContentList => vec![ResultFlag::Filter],
DecisionContext::ContentMedia => vec![ResultFlag::Blur, ResultFlag::NoOverride],
_ => vec![],
};
assert_ui(&result, &expected, context);
Expand Down
Loading

0 comments on commit cefa4a4

Please sign in to comment.