use async_trait::async_trait;
use crate::bus::OutboundMessage;
use crate::error::Result;
#[async_trait]
pub trait Channel: Send + Sync {
fn name(&self) -> &str;
async fn start(&mut self) -> Result<()>;
async fn stop(&mut self) -> Result<()>;
async fn send(&self, msg: OutboundMessage) -> Result<()>;
fn is_running(&self) -> bool;
fn is_allowed(&self, user_id: &str) -> bool;
}
#[derive(Debug, Clone, Default)]
pub struct BaseChannelConfig {
pub name: String,
pub allowlist: Vec<String>,
pub deny_by_default: bool,
}
impl BaseChannelConfig {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
allowlist: Vec::new(),
deny_by_default: false,
}
}
pub fn with_allowlist(name: &str, allowlist: Vec<String>) -> Self {
Self {
name: name.to_string(),
allowlist,
deny_by_default: false,
}
}
pub fn is_allowed(&self, user_id: &str) -> bool {
if self.allowlist.is_empty() {
!self.deny_by_default
} else {
self.allowlist.contains(&user_id.to_string())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_base_channel_config_new() {
let config = BaseChannelConfig::new("telegram");
assert_eq!(config.name, "telegram");
assert!(config.allowlist.is_empty());
}
#[test]
fn test_base_channel_config_with_allowlist() {
let config = BaseChannelConfig::with_allowlist(
"discord",
vec!["user1".to_string(), "user2".to_string()],
);
assert_eq!(config.name, "discord");
assert_eq!(config.allowlist.len(), 2);
}
#[test]
fn test_base_channel_config() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec!["user1".to_string()],
..Default::default()
};
assert!(config.is_allowed("user1"));
assert!(!config.is_allowed("user2"));
}
#[test]
fn test_empty_allowlist() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec![],
..Default::default()
};
assert!(config.is_allowed("anyone")); }
#[test]
fn test_allowlist_with_multiple_users() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec![
"user1".to_string(),
"user2".to_string(),
"user3".to_string(),
],
..Default::default()
};
assert!(config.is_allowed("user1"));
assert!(config.is_allowed("user2"));
assert!(config.is_allowed("user3"));
assert!(!config.is_allowed("user4"));
}
#[test]
fn test_base_channel_config_default() {
let config = BaseChannelConfig::default();
assert!(config.name.is_empty());
assert!(config.allowlist.is_empty());
assert!(!config.deny_by_default);
assert!(config.is_allowed("anyone"));
}
#[test]
fn test_base_channel_config_clone() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec!["user1".to_string()],
..Default::default()
};
let cloned = config.clone();
assert_eq!(cloned.name, "test");
assert_eq!(cloned.allowlist, vec!["user1"]);
}
#[test]
fn test_deny_by_default_empty_allowlist_rejects() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec![],
deny_by_default: true,
};
assert!(!config.is_allowed("anyone"));
}
#[test]
fn test_deny_by_default_with_allowlist_checks() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec!["user1".to_string()],
deny_by_default: true,
};
assert!(config.is_allowed("user1"));
assert!(!config.is_allowed("user2"));
}
#[test]
fn test_deny_by_default_false_allows_all() {
let config = BaseChannelConfig {
name: "test".to_string(),
allowlist: vec![],
deny_by_default: false,
};
assert!(config.is_allowed("anyone"));
}
#[test]
fn test_deny_by_default_defaults_to_false() {
let config = BaseChannelConfig::new("test");
assert!(!config.deny_by_default);
assert!(config.is_allowed("anyone"));
}
}