//! 测试基础设施 — 事务回滚模式解决并行化问题
//!
//! 每个测试在独立事务中执行，测试结束自动回滚，无数据残留。
//! 多个测试共享同一个数据库连接池，无连接竞争。

use sea_orm::{
    ConnectOptions, Database, DatabaseConnection, DatabaseTransaction, TransactionTrait,
};
use std::sync::OnceLock;
use tokio::sync::OnceCell;

static DB_POOL: OnceCell<DatabaseConnection> = OnceCell::const_new();
static DB_URL: OnceLock<String> = OnceLock::new();

fn db_url() -> String {
    DB_URL
        .get_or_init(|| {
            std::env::var("TEST_DATABASE_URL")
                .unwrap_or_else(|_| "postgres://erp:erp@localhost:5432/erp_test".into())
        })
        .clone()
}

async fn db_pool() -> &'static DatabaseConnection {
    DB_POOL
        .get_or_init(|| async {
            let opt = ConnectOptions::new(db_url()).max_connections(5).to_owned();
            Database::connect(opt).await.expect("测试数据库连接失败")
        })
        .await
}

/// 创建测试用事务。测试结束自动回滚，无数据残留。
pub async fn test_txn() -> DatabaseTransaction {
    let pool = db_pool().await;
    pool.begin().await.expect("测试事务创建失败")
}
