#![allow(missing_docs)]
use force::auth::TokenResponse;
use force::auth::{AccessToken, Authenticator, TokenManager};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Debug)]
struct DummyAuthenticator {
auth_count: Arc<AtomicUsize>,
refresh_count: Arc<AtomicUsize>,
}
impl DummyAuthenticator {
fn new() -> Self {
Self {
auth_count: Arc::new(AtomicUsize::new(0)),
refresh_count: Arc::new(AtomicUsize::new(0)),
}
}
}
#[async_trait::async_trait]
impl Authenticator for DummyAuthenticator {
async fn authenticate(&self) -> force::error::Result<AccessToken> {
let count = self.auth_count.fetch_add(1, Ordering::SeqCst);
let resp = TokenResponse {
access_token: format!("auth_token_{count}"),
instance_url: "https://test.salesforce.com".to_string(),
token_type: "Bearer".to_string(),
issued_at: chrono::Utc::now().timestamp_millis().to_string(),
signature: String::new(),
expires_in: None,
refresh_token: None,
};
Ok(AccessToken::from_response(resp))
}
async fn refresh(&self) -> force::error::Result<AccessToken> {
let count = self.refresh_count.fetch_add(1, Ordering::SeqCst);
let resp = TokenResponse {
access_token: format!("refresh_token_{count}"),
instance_url: "https://test.salesforce.com".to_string(),
token_type: "Bearer".to_string(),
issued_at: chrono::Utc::now().timestamp_millis().to_string(),
signature: String::new(),
expires_in: None,
refresh_token: None,
};
Ok(AccessToken::from_response(resp))
}
}
#[tokio::test]
async fn test_havoc_force_refresh_cleared() {
let auth = DummyAuthenticator::new();
let manager = Arc::new(TokenManager::new(auth));
#[allow(clippy::unwrap_used)]
let token = manager.token().await.unwrap();
assert_eq!(token.as_str(), "auth_token_0");
manager.clear().await;
#[allow(clippy::unwrap_used)]
let token2 = manager.force_refresh().await.unwrap();
assert_eq!(token2.as_str(), "auth_token_1");
}