use crate::channels::commands::handle_respond_to;
use crate::config::{Config, RespondTo};
struct HomeGuard {
prev_home: Option<std::ffi::OsString>,
prev_userprofile: Option<std::ffi::OsString>,
_lock: std::sync::MutexGuard<'static, ()>,
}
impl HomeGuard {
fn new(temp_home: &std::path::Path) -> Self {
let lock = crate::tests::HOME_ENV_LOCK
.lock()
.unwrap_or_else(|p| p.into_inner());
let prev_home = std::env::var_os("HOME");
let prev_userprofile = std::env::var_os("USERPROFILE");
unsafe {
std::env::set_var("HOME", temp_home);
std::env::set_var("USERPROFILE", temp_home);
}
Self {
prev_home,
prev_userprofile,
_lock: lock,
}
}
}
impl Drop for HomeGuard {
fn drop(&mut self) {
unsafe {
match &self.prev_home {
Some(v) => std::env::set_var("HOME", v),
None => std::env::remove_var("HOME"),
}
match &self.prev_userprofile {
Some(v) => std::env::set_var("USERPROFILE", v),
None => std::env::remove_var("USERPROFILE"),
}
}
}
}
#[cfg(unix)]
#[tokio::test]
async fn respond_to_in_group_persists_and_survives_reload() {
let tmp = tempfile::tempdir().unwrap();
let _guard = HomeGuard::new(tmp.path());
let home = tmp.path().join(".opencrabs");
std::fs::create_dir_all(&home).unwrap();
std::fs::write(
home.join("config.toml"),
"[channels.telegram]\nenabled = true\nrespond_to = \"mention\"\n",
)
.unwrap();
let chat_id = "-1001234567890";
let reply = handle_respond_to("all", Some(chat_id)).await;
assert!(
reply.starts_with("✅"),
"expected a success reply, got: {reply}"
);
let raw = std::fs::read_to_string(home.join("config.toml")).unwrap();
assert!(
raw.contains("groups") && raw.contains(chat_id),
"config.toml is missing the groups override:\n{raw}"
);
let cfg = Config::load().expect("config must reload after the group write");
let group = cfg
.channels
.telegram
.groups
.get(chat_id)
.expect("groups entry must persist across reload");
assert!(matches!(group.respond_to, Some(RespondTo::All)));
assert!(matches!(
cfg.channels.telegram.respond_to,
RespondTo::Mention
));
}
#[cfg(unix)]
#[tokio::test]
async fn respond_to_in_dm_writes_channel_level() {
let tmp = tempfile::tempdir().unwrap();
let _guard = HomeGuard::new(tmp.path());
let home = tmp.path().join(".opencrabs");
std::fs::create_dir_all(&home).unwrap();
std::fs::write(
home.join("config.toml"),
"[channels.telegram]\nenabled = true\nrespond_to = \"mention\"\n",
)
.unwrap();
let reply = handle_respond_to("all", None).await;
assert!(
reply.starts_with("✅"),
"expected a success reply, got: {reply}"
);
let cfg = Config::load().expect("config must reload");
assert!(matches!(cfg.channels.telegram.respond_to, RespondTo::All));
assert!(cfg.channels.telegram.groups.is_empty());
}
#[cfg(unix)]
#[tokio::test]
async fn respond_to_in_group_same_as_global_still_creates_override() {
let tmp = tempfile::tempdir().unwrap();
let _guard = HomeGuard::new(tmp.path());
let home = tmp.path().join(".opencrabs");
std::fs::create_dir_all(&home).unwrap();
std::fs::write(
home.join("config.toml"),
"[channels.telegram]\nenabled = true\nrespond_to = \"mention\"\n",
)
.unwrap();
let chat_id = "-5324478558";
let reply = handle_respond_to("mention", Some(chat_id)).await;
assert!(
reply.starts_with("✅"),
"expected success (not 'already in'), got: {reply}"
);
let raw = std::fs::read_to_string(home.join("config.toml")).unwrap();
assert!(
raw.contains("groups") && raw.contains(chat_id),
"config.toml is missing the groups override when value == global:\n{raw}"
);
let cfg = Config::load().expect("config must reload after group write");
let group = cfg
.channels
.telegram
.groups
.get(chat_id)
.expect("groups entry must exist even when value matches global");
assert!(matches!(group.respond_to, Some(RespondTo::Mention)));
assert!(matches!(
cfg.channels.telegram.respond_to,
RespondTo::Mention
));
}