use super::{validate_length, validate_not_empty};
use crate::constants::validation;
use crate::errors::prelude::{CliError, Result as CliResult};
pub fn validate_chat_id(chat_id: &str) -> CliResult<()> {
validate_not_empty(chat_id, "Chat ID")?;
validate_length(
chat_id,
"Chat ID",
validation::MIN_USERNAME_LENGTH,
validation::MAX_USERNAME_LENGTH,
)?;
if !chat_id
.chars()
.all(|c| c.is_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '@')
{
return Err(CliError::InputError(
"Chat ID contains invalid characters. Only alphanumeric, underscore, dot, hyphen, and @ are allowed".to_string()
));
}
Ok(())
}
pub fn validate_chat_title(title: &str) -> CliResult<()> {
validate_not_empty(title, "Chat title")?;
validate_length(
title,
"Chat title",
validation::MIN_CHAT_TITLE_LENGTH,
validation::MAX_CHAT_TITLE_LENGTH,
)?;
Ok(())
}
pub fn validate_chat_about(about: &str) -> CliResult<()> {
validate_not_empty(about, "Chat description")?;
validate_length(about, "Chat description", 1, validation::MAX_MESSAGE_LENGTH)?;
Ok(())
}
pub fn validate_chat_action(action: &str) -> CliResult<()> {
use crate::constants::api::actions;
match action {
actions::TYPING | actions::LOOKING => Ok(()),
_ => Err(CliError::InputError(format!(
"Invalid action: {}. Available actions: {}, {}",
action,
actions::TYPING,
actions::LOOKING
))),
}
}
pub fn validate_cursor(cursor: &str) -> CliResult<()> {
cursor
.parse::<u32>()
.map_err(|_| CliError::InputError("Cursor must be a valid number".to_string()))?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
#[test]
fn test_validate_chat_id_valid() {
assert!(validate_chat_id("user123").is_ok());
assert!(validate_chat_id("@username").is_ok());
assert!(validate_chat_id("chat.group-1").is_ok());
assert!(validate_chat_id("test_user").is_ok());
}
#[test]
fn test_validate_chat_id_invalid() {
assert!(validate_chat_id("").is_err());
assert!(validate_chat_id(" ").is_err());
assert!(validate_chat_id("user with spaces").is_err());
assert!(validate_chat_id("user#invalid").is_err());
}
#[test]
fn test_validate_chat_title() {
assert!(validate_chat_title("Valid Title").is_ok());
assert!(validate_chat_title("").is_err());
assert!(validate_chat_title(" ").is_err());
}
#[test]
fn test_validate_chat_action() {
assert!(validate_chat_action("typing").is_ok());
assert!(validate_chat_action("looking").is_ok());
assert!(validate_chat_action("invalid").is_err());
}
#[test]
fn test_validate_cursor() {
assert!(validate_cursor("123").is_ok());
assert!(validate_cursor("0").is_ok());
assert!(validate_cursor("abc").is_err());
assert!(validate_cursor("12.5").is_err());
}
proptest! {
#[test]
fn prop_validate_chat_id_random(s in ".{0,128}") {
let _ = validate_chat_id(&s);
}
#[test]
fn prop_validate_chat_title_random(s in ".{0,128}") {
let _ = validate_chat_title(&s);
}
#[test]
fn prop_validate_chat_action_random(s in ".{0,32}") {
let _ = validate_chat_action(&s);
}
#[test]
fn prop_validate_cursor_random(s in ".{0,32}") {
let _ = validate_cursor(&s);
}
}
}