use std::sync::OnceLock;
use axum_test::{TestServer, TestServerConfig};
#[cfg(feature = "with-db")]
use sea_orm::DatabaseConnection;
use crate::{
app::{AppContext, Hooks},
boot::{self, BootResult},
environment::Environment,
Result,
};
static CLEANUP_USER_MODEL: OnceLock<Vec<(&'static str, &'static str)>> = OnceLock::new();
static CLEANUP_DATE: OnceLock<Vec<(&'static str, &'static str)>> = OnceLock::new();
static CLEANUP_MODEL: OnceLock<Vec<(&'static str, &'static str)>> = OnceLock::new();
static CLEANUP_MAIL: OnceLock<Vec<(&'static str, &'static str)>> = OnceLock::new();
pub fn get_cleanup_user_model() -> &'static Vec<(&'static str, &'static str)> {
CLEANUP_USER_MODEL.get_or_init(|| {
vec![
(
r"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})",
"PID",
),
(r"password: (.*{60}),", "password: \"PASSWORD\","),
(r"([A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*)", "TOKEN"),
]
})
}
pub fn get_cleanup_date() -> &'static Vec<(&'static str, &'static str)> {
CLEANUP_DATE.get_or_init(|| {
vec![
(
r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?\+\d{2}:\d{2}",
"DATE",
), (r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+", "DATE"),
(r"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})", "DATE"),
]
})
}
pub fn get_cleanup_model() -> &'static Vec<(&'static str, &'static str)> {
CLEANUP_MODEL.get_or_init(|| vec![(r"id: \d+,", "id: ID")])
}
pub fn get_cleanup_mail() -> &'static Vec<(&'static str, &'static str)> {
CLEANUP_MAIL.get_or_init(|| {
vec![
(r"[0-9A-Za-z]+{40}", "IDENTIFIER"),
(
r"\w+, \d{1,2} \w+ \d{4} \d{2}:\d{2}:\d{2} [+-]\d{4}",
"DATE",
),
(
r"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})",
"RANDOM_ID",
),
(
r"([0-9a-fA-F]{8}-[0-9a-fA-F]{4})-[0-9a-fA-F]{4}-.*[0-9a-fA-F]{2}",
"RANDOM_ID",
),
]
})
}
#[must_use]
pub fn cleanup_user_model() -> Vec<(&'static str, &'static str)> {
let mut combined_filters = get_cleanup_user_model().clone();
combined_filters.extend(get_cleanup_date().iter().copied());
combined_filters.extend(get_cleanup_model().iter().copied());
combined_filters
}
#[must_use]
pub fn cleanup_email() -> Vec<(&'static str, &'static str)> {
let mut combined_filters = get_cleanup_mail().clone();
combined_filters.extend(get_cleanup_date().iter().copied());
combined_filters
}
pub async fn boot_test<H: Hooks>() -> Result<BootResult> {
H::boot(boot::StartMode::ServerOnly, &Environment::Test).await
}
#[cfg(feature = "with-db")]
pub async fn seed<H: Hooks>(db: &DatabaseConnection) -> Result<()> {
let path = std::path::Path::new("src/fixtures");
H::seed(db, path).await
}
#[allow(clippy::future_not_send)]
#[allow(clippy::future_not_send)]
pub async fn request<H: Hooks, F, Fut>(callback: F)
where
F: FnOnce(TestServer, AppContext) -> Fut,
Fut: std::future::Future<Output = ()>,
{
let boot = boot_test::<H>().await.unwrap();
let config = TestServerConfig {
default_content_type: Some("application/json".to_string()),
..Default::default()
};
let server = TestServer::new_with_config(boot.router.unwrap(), config).unwrap();
callback(server, boot.app_context.clone()).await;
}