use salvo_core::http::Request;
use crate::CaptchaFinder;
#[derive(Debug)]
pub struct CaptchaQueryFinder {
pub token_name: String,
pub answer_name: String,
}
impl CaptchaQueryFinder {
pub fn new() -> Self {
Self::default()
}
pub fn token_name(mut self, token_name: String) -> Self {
self.token_name = token_name;
self
}
pub fn answer_name(mut self, answer_name: String) -> Self {
self.answer_name = answer_name;
self
}
}
impl Default for CaptchaQueryFinder {
fn default() -> Self {
Self {
token_name: "c_t".to_string(),
answer_name: "c_a".to_string(),
}
}
}
impl CaptchaFinder for CaptchaQueryFinder {
async fn find_token(&self, req: &mut Request) -> Option<Option<String>> {
req.queries()
.get(&self.token_name)
.map(|o| Some(o.to_owned()))
}
async fn find_answer(&self, req: &mut Request) -> Option<Option<String>> {
req.queries()
.get(&self.answer_name)
.map(|o| Some(o.to_owned()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
#[rstest::rstest]
#[case::not_found(None, None, None, None, None, None)]
#[case::normal(
None,
None,
Some(("c_t", "token")),
Some(("c_a", "answer")),
Some(Some("token")),
Some(Some("answer"))
)]
#[case::custom_keys(
Some("cc_t"),
Some("cc_a"),
Some(("cc_t", "token")),
Some(("cc_a", "answer")),
Some(Some("token")),
Some(Some("answer"))
)]
#[case::only_token(
None,
None,
Some(("c_t", "token")),
None,
Some(Some("token")),
None
)]
#[case::only_answer(None, None, None, Some(("c_a", "ans")), None, Some(Some("ans")))]
#[case::custom_not_found(Some("cc_t"), Some("cc_a"), None, None, None, None)]
#[case::custom_not_found_with_query(
Some("cc_t"),
Some("cc_a"),
Some(("c_t", "token")),
Some(("c_a", "answer")),
None,
None
)]
async fn test_query_finder(
#[case] custom_token_key: Option<&'static str>,
#[case] custom_answer_key: Option<&'static str>,
#[case] token_key_val: Option<(&'static str, &'static str)>,
#[case] answer_key_val: Option<(&'static str, &'static str)>,
#[case] excepted_token: Option<Option<&'static str>>,
#[case] excepted_answer: Option<Option<&'static str>>,
) {
let mut req = Request::default();
let mut finder = CaptchaQueryFinder::new();
if let Some(token_key) = custom_token_key {
finder = finder.token_name(token_key.to_string())
}
if let Some(answer_key) = custom_answer_key {
finder = finder.answer_name(answer_key.to_string())
}
let queries = req.queries_mut();
if let Some((k, v)) = token_key_val {
queries.insert(k.to_owned(), v.to_owned());
}
if let Some((k, v)) = answer_key_val {
queries.insert(k.to_owned(), v.to_owned());
}
assert_eq!(
finder.find_token(&mut req).await,
excepted_token.map(|o| o.map(ToOwned::to_owned))
);
assert_eq!(
finder.find_answer(&mut req).await,
excepted_answer.map(|o| o.map(ToOwned::to_owned))
);
}
}