#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use std::collections::VecDeque;
use std::sync::Mutex;
use super::port::{PasAuthPort, PasFailure};
use crate::oauth::{TokenResponse, UserInfo};
#[derive(Debug)]
struct RefreshExpect {
rt_in: String,
returns: Result<TokenResponse, PasFailure>,
}
#[derive(Debug)]
struct UserinfoExpect {
at_in: String,
returns: Result<UserInfo, PasFailure>,
}
#[derive(Debug, Default)]
pub struct MemoryPasAuth {
refresh_script: Mutex<VecDeque<RefreshExpect>>,
userinfo_script: Mutex<VecDeque<UserinfoExpect>>,
}
impl MemoryPasAuth {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn expect_refresh(
self,
rt: impl Into<String>,
returns: Result<TokenResponse, PasFailure>,
) -> Self {
self.refresh_script
.lock()
.unwrap()
.push_back(RefreshExpect { rt_in: rt.into(), returns });
self
}
#[must_use]
pub fn expect_userinfo(
self,
at: impl Into<String>,
returns: Result<UserInfo, PasFailure>,
) -> Self {
self.userinfo_script
.lock()
.unwrap()
.push_back(UserinfoExpect { at_in: at.into(), returns });
self
}
}
impl PasAuthPort for MemoryPasAuth {
async fn refresh(&self, rt: &str) -> Result<TokenResponse, PasFailure> {
let exp = self
.refresh_script
.lock()
.unwrap()
.pop_front()
.expect("MemoryPasAuth: refresh called with no expect_refresh queued");
assert_eq!(
exp.rt_in, rt,
"MemoryPasAuth: refresh token mismatch (expected={:?}, actual={:?})",
exp.rt_in, rt
);
exp.returns
}
async fn userinfo(&self, at: &str) -> Result<UserInfo, PasFailure> {
let exp = self
.userinfo_script
.lock()
.unwrap()
.pop_front()
.expect("MemoryPasAuth: userinfo called with no expect_userinfo queued");
assert_eq!(
exp.at_in, at,
"MemoryPasAuth: access token mismatch (expected={:?}, actual={:?})",
exp.at_in, at
);
exp.returns
}
}
impl Drop for MemoryPasAuth {
fn drop(&mut self) {
if std::thread::panicking() {
return;
}
let r = self.refresh_script.get_mut().unwrap();
if !r.is_empty() {
panic!(
"MemoryPasAuth dropped with {} unconsumed refresh expectation(s)",
r.len()
);
}
let u = self.userinfo_script.get_mut().unwrap();
if !u.is_empty() {
panic!(
"MemoryPasAuth dropped with {} unconsumed userinfo expectation(s)",
u.len()
);
}
}
}