use std::time::Duration;
use kryphocron::{
BindError, CapabilityClass, CapabilityKind, CapabilitySemantics, ReceiptVerificationFailure,
Tier, UserCapability, Visibility, MAX_CHAIN_DEPTH,
};
use kryphocron::authority::{
DeletePrivatePost, EditPrivatePost, ManageAudience, ModerationCapability, ModeratorRead,
ModeratorRestore, ModeratorTakedown, ParticipatePrivate, ViewPrivate,
};
use kryphocron::resolver::PeerKind;
#[test]
fn tier_has_public_and_private_variants() {
let _public = Tier::Public;
let _private = Tier::Private;
}
#[test]
fn visibility_three_variants() {
let _v = Visibility::Visible;
let _h = Visibility::Hidden;
let _f = Visibility::Forbidden;
assert!(Visibility::Visible.allows_read());
assert!(!Visibility::Hidden.allows_read());
assert!(!Visibility::Forbidden.allows_read());
}
#[test]
fn capability_kind_v1_set_pinned() {
let kinds = [
CapabilityKind::ViewPrivate,
CapabilityKind::ParticipatePrivate,
CapabilityKind::EditPrivatePost,
CapabilityKind::DeletePrivatePost,
CapabilityKind::ManageAudience,
CapabilityKind::EmitToSyncChannel,
CapabilityKind::AppViewSync,
CapabilityKind::GraphSync,
CapabilityKind::ScanShard,
CapabilityKind::ReplicatePrivate,
CapabilityKind::GarbageCollect,
CapabilityKind::ModeratorRead,
CapabilityKind::ModeratorTakedown,
CapabilityKind::ModeratorRestore,
];
assert_eq!(kinds.len(), 14);
}
#[test]
fn user_class_capabilities_are_wire_eligible() {
assert!(CapabilityKind::ViewPrivate.is_wire_eligible());
assert!(CapabilityKind::EditPrivatePost.is_wire_eligible());
}
#[test]
fn substrate_and_moderation_never_wire_eligible() {
for k in [
CapabilityKind::ScanShard,
CapabilityKind::ReplicatePrivate,
CapabilityKind::GarbageCollect,
CapabilityKind::ModeratorRead,
CapabilityKind::ModeratorTakedown,
CapabilityKind::ModeratorRestore,
] {
assert!(!k.is_wire_eligible(), "{k:?} must not be wire-eligible");
}
}
#[test]
fn capability_class_partitioning_consistent() {
assert_eq!(CapabilityKind::ViewPrivate.class(), CapabilityClass::User);
assert_eq!(
CapabilityKind::EmitToSyncChannel.class(),
CapabilityClass::Channel
);
assert_eq!(CapabilityKind::ScanShard.class(), CapabilityClass::Substrate);
assert_eq!(
CapabilityKind::ModeratorRead.class(),
CapabilityClass::Moderation
);
}
#[test]
fn v1_max_age_table_matches_spec() {
assert_eq!(<ViewPrivate as UserCapability>::MAX_AGE, Duration::from_secs(300));
assert_eq!(
<ParticipatePrivate as UserCapability>::MAX_AGE,
Duration::from_secs(60)
);
assert_eq!(<EditPrivatePost as UserCapability>::MAX_AGE, Duration::from_secs(60));
assert_eq!(
<DeletePrivatePost as UserCapability>::MAX_AGE,
Duration::from_secs(30)
);
assert_eq!(<ManageAudience as UserCapability>::MAX_AGE, Duration::from_secs(60));
assert_eq!(
<ModeratorRead as ModerationCapability>::MAX_AGE,
Duration::from_secs(30)
);
assert_eq!(
<ModeratorTakedown as ModerationCapability>::MAX_AGE,
Duration::from_secs(10)
);
assert_eq!(
<ModeratorRestore as ModerationCapability>::MAX_AGE,
Duration::from_secs(30)
);
}
#[test]
fn v1_semantics_read_vs_write_pinned() {
assert_eq!(
<ViewPrivate as UserCapability>::SEMANTICS,
CapabilitySemantics::Read
);
assert_eq!(
<ParticipatePrivate as UserCapability>::SEMANTICS,
CapabilitySemantics::Write
);
assert_eq!(
<EditPrivatePost as UserCapability>::SEMANTICS,
CapabilitySemantics::Write
);
assert_eq!(
<DeletePrivatePost as UserCapability>::SEMANTICS,
CapabilitySemantics::Write
);
assert_eq!(
<ManageAudience as UserCapability>::SEMANTICS,
CapabilitySemantics::Write
);
}
#[test]
fn bind_error_includes_attribution_receipt_invalid() {
let e = BindError::AttributionReceiptInvalid {
failing_hop: 3,
reason: ReceiptVerificationFailure::Malformed,
};
match e {
BindError::AttributionReceiptInvalid { failing_hop, .. } => {
assert_eq!(failing_hop, 3);
}
_ => panic!("variant did not destructure as expected"),
}
}
#[test]
fn peer_kind_has_internal_and_federation() {
let _i = PeerKind::Internal;
let _f = PeerKind::Federation;
assert_ne!(PeerKind::Internal, PeerKind::Federation);
}
#[test]
fn max_chain_depth_is_8() {
assert_eq!(MAX_CHAIN_DEPTH, 8);
}