use crate::sqlite::SessionStore as Store;
use crate::TableOperations;
use async_session::{chrono::Utc, serde_json, Session, SessionStore};
use r2d2_sqlite::rusqlite;
use std::time::Duration;
async fn test_store() -> anyhow::Result<Store> {
Store::from_memory("testing".to_string())
}
#[async_std::test]
async fn creating_a_new_session_with_no_expiry() -> async_session::Result {
let store = test_store().await?;
let mut session = Session::new();
session.insert("key", "value")?;
let cloned = session.clone();
let cookie_value = store.store_session(session).await?.unwrap();
let (id, expires, serialized, count): (String, Option<i64>, String, i64) =
store.connection()?.query_row(
"select id, expires, session, count(*) from testing",
rusqlite::params![],
|row| {
Ok((
row.get("id")?,
row.get("expires")?,
row.get("session")?,
row.get("count(*)")?,
))
},
)?;
assert_eq!(1, count);
assert_eq!(id, cloned.id());
assert_eq!(expires, None);
let deserialized_session: Session = serde_json::from_str(&serialized)?;
assert_eq!(cloned.id(), deserialized_session.id());
assert_eq!("value", &deserialized_session.get::<String>("key").unwrap());
let loaded_session = store.load_session(cookie_value).await?.unwrap();
assert_eq!(cloned.id(), loaded_session.id());
assert_eq!("value", &loaded_session.get::<String>("key").unwrap());
assert!(!loaded_session.is_expired());
store.clear_store().await
}
#[async_std::test]
async fn updating_a_session() -> async_session::Result {
let store = test_store().await?;
let mut session = Session::new();
let original_id = session.id().to_owned();
session.insert("key", "value")?;
let cookie_value = store.store_session(session).await?.unwrap();
let mut session = store.load_session(cookie_value.clone()).await?.unwrap();
session.insert("key", "other value")?;
assert_eq!(None, store.store_session(session).await?);
let session = store.load_session(cookie_value.clone()).await?.unwrap();
assert_eq!(session.get::<String>("key").unwrap(), "other value");
let (id, count): (String, i64) = store.connection()?.query_row(
"select id, count(*) from testing",
rusqlite::params![],
|row| Ok((row.get("id")?, row.get("count(*)")?)),
)?;
assert_eq!(1, count);
assert_eq!(original_id, id);
store.clear_store().await
}
#[async_std::test]
async fn updating_a_session_extending_expiry() -> async_session::Result {
let store = test_store().await?;
let mut session = Session::new();
session.expire_in(Duration::from_secs(10));
let original_id = session.id().to_owned();
let original_expires = session.expiry().unwrap().clone();
let cookie_value = store.store_session(session).await?.unwrap();
let mut session = store.load_session(cookie_value.clone()).await?.unwrap();
assert_eq!(session.expiry().unwrap(), &original_expires);
session.expire_in(Duration::from_secs(20));
let new_expires = session.expiry().unwrap().clone();
store.store_session(session).await?;
let session = store.load_session(cookie_value.clone()).await?.unwrap();
assert_eq!(session.expiry().unwrap(), &new_expires);
let (id, expires, count): (String, i64, i64) = store.connection()?.query_row(
"select id, expires, count(*) from testing",
rusqlite::params![],
|row| Ok((row.get("id")?, row.get("expires")?, row.get("count(*)")?)),
)?;
assert_eq!(1, count);
assert_eq!(expires, new_expires.timestamp());
assert_eq!(original_id, id);
store.clear_store().await
}
#[async_std::test]
async fn creating_a_new_session_with_expiry() -> async_session::Result {
let store = test_store().await?;
let mut session = Session::new();
session.expire_in(Duration::from_secs(1));
session.insert("key", "value")?;
let cloned = session.clone();
let cookie_value = store.store_session(session).await?.unwrap();
let (id, expires, serialized, count): (String, Option<i64>, String, i64) =
store.connection()?.query_row(
"select id, expires, session, count(*) from testing",
rusqlite::params![],
|row| {
Ok((
row.get("id")?,
row.get("expires")?,
row.get("session")?,
row.get("count(*)")?,
))
},
)?;
assert_eq!(1, count);
assert_eq!(id, cloned.id());
assert!(expires.unwrap() > Utc::now().timestamp());
let deserialized_session: Session = serde_json::from_str(&serialized)?;
assert_eq!(cloned.id(), deserialized_session.id());
assert_eq!("value", &deserialized_session.get::<String>("key").unwrap());
let loaded_session = store.load_session(cookie_value.clone()).await?.unwrap();
assert_eq!(cloned.id(), loaded_session.id());
assert_eq!("value", &loaded_session.get::<String>("key").unwrap());
assert!(!loaded_session.is_expired());
async_std::task::sleep(Duration::from_secs(1)).await;
assert_eq!(None, store.load_session(cookie_value).await?);
store.clear_store().await
}
#[async_std::test]
async fn destroying_a_single_session() -> async_session::Result {
let store = test_store().await?;
for _ in 0..3i8 {
store.store_session(Session::new()).await?;
}
let cookie = store.store_session(Session::new()).await?.unwrap();
assert_eq!(4, store.count()?);
let session = store.load_session(cookie.clone()).await?.unwrap();
store.destroy_session(session.clone()).await.unwrap();
assert_eq!(None, store.load_session(cookie).await?);
assert_eq!(3, store.count()?);
store.clear_store().await
}
#[async_std::test]
async fn clearing_the_whole_store() -> async_session::Result {
let store = test_store().await?;
for _ in 0..3i8 {
store.store_session(Session::new()).await?;
}
assert_eq!(3, store.count()?);
store.clear_store().await.unwrap();
assert_eq!(0, store.count()?);
store.clear_store().await
}