use serde_json::{Value, json};
use crate::common::identity::Did;
pub const CONFORMANCE_REPORT_SUBJECT_URI: &str =
"at://did:plc:bvdrfwiamgi5leqs63q2duro/app.bsky.feed.post/3mjxxrzqtwc2d";
pub const CONFORMANCE_REPORT_SUBJECT_CID: &str =
"bafyreigvtlsnrkzac53uluemkc7p7345a2yqa2ct5lg6vglmvfakq4kkxq";
pub fn choose_reason_type(advertised: &[String], is_local: bool) -> String {
let prefer_other = "com.atproto.moderation.defs#reasonOther";
if !is_local && advertised.iter().any(|r| r == prefer_other) {
return prefer_other.to_string();
}
advertised
.first()
.cloned()
.unwrap_or_else(|| prefer_other.to_string())
}
pub fn choose_subject(
advertised_types: &[String],
reporter_did: &Did,
override_did: Option<&Did>,
is_local: bool,
) -> Value {
if let Some(did) = override_did {
return json!({
"$type": "com.atproto.admin.defs#repoRef",
"did": did.0,
});
}
if !is_local && advertised_types.iter().any(|s| s == "record") {
return json!({
"$type": "com.atproto.repo.strongRef",
"uri": CONFORMANCE_REPORT_SUBJECT_URI,
"cid": CONFORMANCE_REPORT_SUBJECT_CID,
});
}
json!({
"$type": "com.atproto.admin.defs#repoRef",
"did": reporter_did.0,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn choose_reason_type_prefers_other_when_advertised_and_non_local() {
let advertised = vec![
"com.atproto.moderation.defs#reasonSpam".to_string(),
"com.atproto.moderation.defs#reasonOther".to_string(),
];
assert_eq!(
choose_reason_type(&advertised, false),
"com.atproto.moderation.defs#reasonOther"
);
}
#[test]
fn choose_reason_type_uses_lex_first_when_local() {
let advertised = vec![
"com.atproto.moderation.defs#reasonSpam".to_string(),
"com.atproto.moderation.defs#reasonOther".to_string(),
];
assert_eq!(
choose_reason_type(&advertised, true),
"com.atproto.moderation.defs#reasonSpam"
);
}
#[test]
fn choose_reason_type_falls_back_to_first_when_other_absent() {
let advertised = vec!["com.atproto.moderation.defs#reasonSpam".to_string()];
assert_eq!(
choose_reason_type(&advertised, false),
"com.atproto.moderation.defs#reasonSpam"
);
}
#[test]
fn choose_subject_local_returns_account_on_reporter() {
let reporter = Did("did:web:127.0.0.1%3A5000".to_string());
let subj = choose_subject(
&["account".to_string(), "record".to_string()],
&reporter,
None,
true,
);
assert_eq!(subj["$type"], "com.atproto.admin.defs#repoRef");
assert_eq!(subj["did"], reporter.0);
}
#[test]
fn choose_subject_non_local_prefers_record_when_advertised() {
let reporter = Did("did:web:127.0.0.1%3A5000".to_string());
let subj = choose_subject(
&["account".to_string(), "record".to_string()],
&reporter,
None,
false,
);
assert_eq!(subj["$type"], "com.atproto.repo.strongRef");
assert_eq!(subj["uri"], CONFORMANCE_REPORT_SUBJECT_URI);
}
#[test]
fn choose_subject_non_local_falls_back_to_account_when_record_absent() {
let reporter = Did("did:web:127.0.0.1%3A5000".to_string());
let subj = choose_subject(&["account".to_string()], &reporter, None, false);
assert_eq!(subj["$type"], "com.atproto.admin.defs#repoRef");
assert_eq!(subj["did"], reporter.0);
}
#[test]
fn choose_subject_override_always_wins() {
let reporter = Did("did:web:127.0.0.1%3A5000".to_string());
let override_did = Did("did:plc:target".to_string());
let subj = choose_subject(
&["record".to_string()],
&reporter,
Some(&override_did),
false, );
assert_eq!(subj["$type"], "com.atproto.admin.defs#repoRef");
assert_eq!(subj["did"], "did:plc:target");
}
}