use cdk_sql_common::mint::SQLMintAuthDatabase;
use cdk_sql_common::SQLMintDatabase;
use crate::common::SqliteConnectionManager;
pub mod memory;
pub type MintSqliteDatabase = SQLMintDatabase<SqliteConnectionManager>;
pub type MintSqliteAuthDatabase = SQLMintAuthDatabase<SqliteConnectionManager>;
#[cfg(test)]
mod test {
use std::fs::remove_file;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use cdk_common::database::{self, MintAuthDatabase};
use cdk_common::secret::Secret;
use cdk_common::{mint_db_test, AuthProof, Id, SecretKey, State};
use cdk_sql_common::pool::Pool;
use cdk_sql_common::stmt::query;
use super::*;
use crate::common::Config;
async fn provide_db(_test_name: String) -> MintSqliteDatabase {
memory::empty().await.unwrap()
}
mint_db_test!(provide_db);
#[tokio::test]
async fn bug_opening_relative_path() {
let config: Config = "test.db".into();
let pool = Pool::<SqliteConnectionManager>::new(config);
let db = pool.get().await;
assert!(db.is_ok());
let _ = remove_file("test.db");
}
#[tokio::test]
async fn exhausted_in_memory_pool_times_out() {
let config: Config = ":memory:".into();
let pool = Pool::<SqliteConnectionManager>::new(config);
let _conn = pool.get().await.expect("valid connection");
let result = pool.get_timeout(Duration::from_millis(10)).await;
assert!(matches!(result, Err(cdk_sql_common::pool::Error::Timeout)));
}
async fn spend_auth_proof(
db: Arc<MintSqliteAuthDatabase>,
proof: AuthProof,
) -> Result<(), database::Error> {
let mut tx = db.as_ref().begin_transaction().await?;
tx.add_proof(proof).await?;
tx.commit().await
}
#[tokio::test]
async fn duplicate_auth_proof_insert_rejected() {
let path = std::env::temp_dir().join(format!(
"cdk-blind-auth-test-{}.sqlite",
uuid::Uuid::new_v4()
));
#[cfg(not(feature = "sqlcipher"))]
let db = Arc::new(
MintSqliteAuthDatabase::new(&path)
.await
.expect("auth database"),
);
#[cfg(feature = "sqlcipher")]
let db = Arc::new(
MintSqliteAuthDatabase::new((path.clone(), "test".to_owned()))
.await
.expect("auth database"),
);
let proof = AuthProof {
keyset_id: Id::from_str("00916bbf7ef91a36").expect("valid keyset id"),
secret: Secret::generate(),
c: SecretKey::generate().public_key(),
dleq: None,
};
let y = proof.y().expect("proof y");
spend_auth_proof(db.clone(), proof.clone())
.await
.expect("first spend");
let second = spend_auth_proof(db.clone(), proof).await;
assert!(matches!(second, Err(database::Error::Duplicate)));
assert_eq!(
db.get_proofs_states(&[y]).await.expect("proof state"),
vec![Some(State::Spent)]
);
drop(db);
remove_file(path).expect("remove auth database");
}
#[tokio::test]
async fn open_legacy_and_migrate() {
let file = format!(
"{}/db.sqlite",
std::env::temp_dir().to_str().unwrap_or_default()
);
{
let _ = remove_file(&file);
#[cfg(not(feature = "sqlcipher"))]
let config: Config = file.as_str().into();
#[cfg(feature = "sqlcipher")]
let config: Config = (file.as_str(), "test").into();
let pool = Pool::<SqliteConnectionManager>::new(config);
let conn = pool.get().await.expect("valid connection");
query(include_str!("../../tests/legacy-sqlx.sql"))
.expect("query")
.execute(&*conn)
.await
.expect("create former db failed");
}
#[cfg(not(feature = "sqlcipher"))]
let conn = MintSqliteDatabase::new(file.as_str()).await;
#[cfg(feature = "sqlcipher")]
let conn = MintSqliteDatabase::new((file.as_str(), "test")).await;
assert!(conn.is_ok(), "Failed with {:?}", conn.unwrap_err());
let _ = remove_file(&file);
}
}