Files
k-ap/src/tests/broadcast.rs
Gabriel Kaszewski f00514850b test: add 31 meaningful unit tests for business logic
Activity receive() tests (src/tests/activities.rs):
- Accept: updates following_status to Accepted with correct user/actor
- Reject: removes following with correct user/actor
- Undo(Follow): removes follower + calls on_actor_removed
- Undo(Like): calls on_unlike for local objects; ignores remote objects
- Undo(Announce): removes announce record + calls on_announce_removed for local;
                  removes record but skips notification for remote objects
- Create: uses object["id"] not activity id; mention fires on_mention + on_create
- Update: uses object["id"]
- Delete(object): calls on_delete; does NOT call on_actor_removed
- Delete(actor): calls on_actor_removed; does NOT call on_delete
- Announce(local): records announce + calls on_announce_received
- Announce(remote): calls on_announce_of_remote; does NOT record announce
- Like(local): calls on_like
- Like(remote): silently ignored
- Add: uses object["id"] not activity id
- Block: removes both following and follower
- Domain block: activity skipped before any processing
- Actor block: Follow skipped before HTTP dereference (SSRF fix)
- Idempotency: duplicate delivery skipped

Actor serialization tests (src/tests/actors.rs):
- actor_type=Service serializes as "Service"
- discoverable=false serializes
- also_known_as serializes as JSON array (all aliases, not just first)
- optional fields omitted when None
- featured URL serialized when set

Visibility addressing tests (src/tests/broadcast.rs):
- Public: to=[AS_PUBLIC], cc=[followers]
- FollowersOnly: to=[followers], cc=[] — AS_PUBLIC absent
- Private: both empty
2026-05-29 02:44:23 +02:00

58 lines
1.8 KiB
Rust

/// Tests for broadcast addressing logic (visibility → to/cc fields).
use url::Url;
use crate::service::broadcast::visibility_addressing;
use crate::urls::AS_PUBLIC;
use crate::user::ApVisibility;
fn followers_url() -> Url {
"https://example.com/users/alice/followers".parse().unwrap()
}
#[test]
fn public_visibility_addresses_public_and_followers() {
let (to, cc) = visibility_addressing(ApVisibility::Public, &followers_url());
assert_eq!(to, vec![AS_PUBLIC.to_string()]);
assert_eq!(cc, vec![followers_url().to_string()]);
}
#[test]
fn followers_only_visibility_addresses_followers_only() {
let (to, cc) = visibility_addressing(ApVisibility::FollowersOnly, &followers_url());
assert_eq!(to, vec![followers_url().to_string()]);
assert!(
cc.is_empty(),
"FollowersOnly must not include AS_PUBLIC in cc"
);
}
#[test]
fn followers_only_excludes_as_public() {
let (to, cc) = visibility_addressing(ApVisibility::FollowersOnly, &followers_url());
assert!(
!to.contains(&AS_PUBLIC.to_string()),
"FollowersOnly must not include AS_PUBLIC in to"
);
assert!(
!cc.contains(&AS_PUBLIC.to_string()),
"FollowersOnly must not include AS_PUBLIC in cc"
);
}
#[test]
fn private_visibility_produces_empty_addressing() {
let (to, cc) = visibility_addressing(ApVisibility::Private, &followers_url());
assert!(to.is_empty());
assert!(cc.is_empty());
}
#[test]
fn public_and_followers_only_differ_in_to() {
let (pub_to, _) = visibility_addressing(ApVisibility::Public, &followers_url());
let (fo_to, _) = visibility_addressing(ApVisibility::FollowersOnly, &followers_url());
assert_ne!(
pub_to, fo_to,
"Public and FollowersOnly must produce different to fields"
);
}