use actix_web::cookie::Cookie;
use crate::{
App,
Auth,
Secret,
UserData,
sessions::begin_session_for_user,
};
async fn create_test_session<A: App>(app: &mut A, user_id: A::UserID) -> (Secret, Auth<A>)
where A::DbError: std::fmt::Debug {
let user_data = _get_user_data(app, user_id)
.await;
let (session_id, session_token) = begin_session_for_user(app, &user_data.user)
.await
.expect(&format!("Failed to insert session for user {user_id}"));
(session_token, Auth {
user: user_data.user,
user_state: user_data.state,
session_id,
_deny_public_constructor: (),
})
}
pub trait WithTestAuth<A: App>
where A::DbError: std::fmt::Debug {
fn with_test_auth(self, app: &mut A, user_id: A::UserID) -> impl std::future::Future<Output = Self>;
fn with_existing_test_auth(self, app: &mut A, user_id: A::UserID, session_id: A::SessionID) -> impl std::future::Future<Output = Self>;
}
pub trait WithTestSession<A: App>
where A::DbError: std::fmt::Debug {
fn with_test_session(self, app: &mut A, user_id: A::UserID) -> impl std::future::Future<Output = Self>;
}
impl <R: actix_web::HttpMessage, A: App> WithTestAuth<A> for R
where A::DbError: std::fmt::Debug {
async fn with_test_auth(self, app: &mut A, user_id: A::UserID) -> Self {
let (_, auth) = create_test_session(app, user_id).await;
auth.into_maybe_auth()
.insert_into_request(&self);
self
}
async fn with_existing_test_auth(self, app: &mut A, user_id: <A>::UserID, session_id: <A>::SessionID) -> Self {
let user_data = _get_user_data(app, user_id).await;
let auth = Auth::<A> {
user: user_data.user,
user_state: user_data.state,
session_id,
_deny_public_constructor: (),
};
auth.into_maybe_auth()
.insert_into_request(&self);
self
}
}
impl <R: WithCookie, A: App> WithTestSession<A> for R
where A::DbError: std::fmt::Debug {
async fn with_test_session(self, app: &mut A, user_id: A::UserID) -> Self {
let (token, _) = create_test_session(app, user_id).await;
self.with_cookie(Cookie::new(
app.session_token_cookie_name(),
token.expose(),
))
}
}
trait WithCookie {
fn with_cookie(self, cookie: Cookie) -> Self;
}
impl WithCookie for actix_web::test::TestRequest {
fn with_cookie(self, cookie: Cookie) -> Self {
self.cookie(cookie)
}
}
impl WithCookie for awc::ClientRequest {
fn with_cookie(self, cookie: Cookie) -> Self {
self.cookie(cookie)
}
}
async fn _get_user_data<A: App>(app: &mut A, user_id: A::UserID) -> UserData<A>
where A::DbError: std::fmt::Debug {
app.get_user_data_by_id(user_id)
.await
.expect(&format!("Failed to fetch data for user {user_id}"))
.expect(&format!("No such user {user_id}"))
}