const FORBIDDEN_SURFACE: [&str; 14] = [
"send_reactions(",
"send_message(",
"edit_message(",
"delete_messages(",
"download_media(",
"search_all_messages(",
"handle_message(",
"AgentService",
"userbot/tools",
"allow_dangerous",
"outbound_allowlist",
"chat_permissions",
"wait_reply",
"schedule_unix",
];
fn userbot_source(module: &str) -> String {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/channels/telegram/userbot")
.join(module);
std::fs::read_to_string(&path)
.unwrap_or_else(|error| panic!("reading {}: {error}", path.display()))
}
#[test]
fn userbot_source_has_no_mutation_or_agent_dispatch_surface() {
let root =
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/channels/telegram/userbot");
let mut source = String::new();
for entry in std::fs::read_dir(root).expect("userbot dir") {
let path = entry.expect("entry").path();
if path.extension().and_then(|ext| ext.to_str()) == Some("rs") {
source.push_str(&std::fs::read_to_string(path).expect("source"));
}
}
for forbidden in FORBIDDEN_SURFACE {
assert!(
!source.contains(forbidden),
"userbot boundary contains forbidden surface: {forbidden}"
);
}
}
#[test]
fn userbot_download_streams_inbound_only() {
let source = userbot_source("download.rs");
assert!(
source.contains("iter_download"),
"download command should stream with iter_download"
);
for forbidden in FORBIDDEN_SURFACE {
assert!(
!source.contains(forbidden),
"download surface contains forbidden call: {forbidden}"
);
}
}
#[test]
fn watch_gate_precedes_conversion_and_storage() {
let watch = std::fs::read_to_string(
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/channels/telegram/userbot/watch.rs"),
)
.expect("watch source");
let gate = watch.find("chat_allowed(&allowed").expect("allowlist gate");
let convert = watch
.find("to_channel_message(&message)")
.expect("conversion");
let store = watch.find("messages.insert(&row)").expect("storage");
assert!(gate < convert && convert < store);
}