use std::collections::BTreeMap;
use crate::{
Endpoint, IntoResponse, Request, handler,
http::{HeaderValue, header},
session::Session,
web::{Path, cookie::Cookie},
};
#[derive(Default)]
pub(crate) struct TestClient {
cookies: BTreeMap<String, String>,
}
impl TestClient {
pub(crate) async fn call(&mut self, ep: impl Endpoint, action: i32) {
let mut req = Request::builder()
.uri(format!("/{action}").parse().unwrap())
.finish();
let mut cookie = String::new();
for (name, value) in &self.cookies {
cookie += &format!("{name}={value};");
}
if !cookie.is_empty() {
req.headers_mut()
.insert(header::COOKIE, HeaderValue::from_str(&cookie).unwrap());
}
let resp = ep.call(req).await.unwrap().into_response();
for s in resp.headers().get_all(header::SET_COOKIE) {
if let Ok(s) = s.to_str() {
let cookie = Cookie::parse(s).unwrap();
if cookie.value_str().is_empty() {
self.cookies.remove(cookie.name());
} else {
self.cookies
.insert(cookie.name().to_string(), cookie.value_str().to_string());
}
}
}
}
pub(crate) fn assert_cookies<'a>(&self, cookies: impl IntoIterator<Item = (&'a str, &'a str)>) {
assert_eq!(
self.cookies,
cookies
.into_iter()
.map(|(name, value)| (name.to_string(), value.to_string()))
.collect::<BTreeMap<_, _>>()
);
}
}
#[handler(internal)]
pub(crate) fn index(Path(action): Path<i32>, session: &Session) {
match action {
1 => {
session.set("a", 10);
session.set("b", 20);
}
2 => {
assert_eq!(session.get::<i32>("a"), Some(10));
assert_eq!(session.get::<i32>("b"), Some(20));
session.set("c", 30);
}
3 => {
assert_eq!(session.get::<i32>("a"), Some(10));
assert_eq!(session.get::<i32>("b"), Some(20));
assert_eq!(session.get::<i32>("c"), Some(30));
session.remove("b");
}
4 => {
assert_eq!(session.get::<i32>("a"), Some(10));
assert_eq!(session.get::<i32>("b"), None);
assert_eq!(session.get::<i32>("c"), Some(30));
session.clear();
}
5 => {
assert!(session.is_empty());
session.purge();
}
6 => {
session.renew();
}
7 => {
assert_eq!(session.get::<i32>("a"), Some(10));
assert_eq!(session.get::<i32>("b"), Some(20));
assert_eq!(session.get::<i32>("c"), Some(30));
}
_ => {}
}
}