use crate::error::TokenStoreError;
use crate::token::{TokenSet, Unvalidated};
use async_trait::async_trait;
#[async_trait]
pub trait TokenStore: Send + Sync {
async fn load(&self) -> Result<Option<TokenSet<Unvalidated>>, TokenStoreError>;
async fn save(&self, tokens: &TokenSet) -> Result<(), TokenStoreError>;
async fn clear(&self) -> Result<(), TokenStoreError>;
}
#[cfg(test)]
mod tests {
use super::TokenStore;
use crate::error::TokenStoreError;
use crate::token::{TokenSet, Unvalidated};
use std::time::{Duration, SystemTime};
struct NoopStore;
#[async_trait::async_trait]
impl TokenStore for NoopStore {
async fn load(&self) -> Result<Option<TokenSet<Unvalidated>>, TokenStoreError> {
Ok(None)
}
async fn save(&self, _tokens: &TokenSet) -> Result<(), TokenStoreError> {
Ok(())
}
async fn clear(&self) -> Result<(), TokenStoreError> {
Ok(())
}
}
fn make_token_set() -> TokenSet {
TokenSet::new(
"access".to_string(),
None,
Some(SystemTime::now() + Duration::from_secs(3600)),
"Bearer".to_string(),
None,
Vec::new(),
)
.into_validated()
}
#[tokio::test]
async fn noop_store_load_returns_none() {
let store = NoopStore;
let result = store.load().await;
assert!(matches!(result, Ok(None)));
}
#[tokio::test]
async fn noop_store_save_returns_ok() {
let store = NoopStore;
let tokens = make_token_set();
let result = store.save(&tokens).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn noop_store_clear_returns_ok() {
let store = NoopStore;
let result = store.clear().await;
assert!(result.is_ok());
}
#[tokio::test]
async fn token_store_is_object_safe() {
let store: Box<dyn TokenStore> = Box::new(NoopStore);
let result = store.load().await;
assert!(matches!(result, Ok(None)));
}
}