1use cdk_sql_common::mint::SQLMintAuthDatabase;
4use cdk_sql_common::SQLMintDatabase;
5
6use crate::common::SqliteConnectionManager;
7
8pub mod memory;
9
10pub type MintSqliteDatabase = SQLMintDatabase<SqliteConnectionManager>;
12
13pub type MintSqliteAuthDatabase = SQLMintAuthDatabase<SqliteConnectionManager>;
15
16#[cfg(test)]
17mod test {
18 use std::fs::remove_file;
19 use std::str::FromStr;
20 use std::sync::Arc;
21 use std::time::Duration;
22
23 use cdk_common::database::{self, MintAuthDatabase};
24 use cdk_common::secret::Secret;
25 use cdk_common::{mint_db_test, AuthProof, Id, SecretKey, State};
26 use cdk_sql_common::pool::Pool;
27 use cdk_sql_common::stmt::query;
28
29 use super::*;
30 use crate::common::Config;
31
32 async fn provide_db(_test_name: String) -> MintSqliteDatabase {
33 memory::empty().await.unwrap()
34 }
35
36 mint_db_test!(provide_db);
37
38 #[tokio::test]
39 async fn bug_opening_relative_path() {
40 let config: Config = "test.db".into();
41
42 let pool = Pool::<SqliteConnectionManager>::new(config);
43 let db = pool.get().await;
44 assert!(db.is_ok());
45 let _ = remove_file("test.db");
46 }
47
48 #[tokio::test]
49 async fn exhausted_in_memory_pool_times_out() {
50 let config: Config = ":memory:".into();
51 let pool = Pool::<SqliteConnectionManager>::new(config);
52
53 let _conn = pool.get().await.expect("valid connection");
54 let result = pool.get_timeout(Duration::from_millis(10)).await;
55
56 assert!(matches!(result, Err(cdk_sql_common::pool::Error::Timeout)));
57 }
58
59 async fn spend_auth_proof(
60 db: Arc<MintSqliteAuthDatabase>,
61 proof: AuthProof,
62 ) -> Result<(), database::Error> {
63 let mut tx = db.as_ref().begin_transaction().await?;
64 tx.add_proof(proof).await?;
65 tx.commit().await
66 }
67
68 #[tokio::test]
69 async fn duplicate_auth_proof_insert_rejected() {
70 let path = std::env::temp_dir().join(format!(
71 "cdk-blind-auth-test-{}.sqlite",
72 uuid::Uuid::new_v4()
73 ));
74
75 #[cfg(not(feature = "sqlcipher"))]
76 let db = Arc::new(
77 MintSqliteAuthDatabase::new(&path)
78 .await
79 .expect("auth database"),
80 );
81 #[cfg(feature = "sqlcipher")]
82 let db = Arc::new(
83 MintSqliteAuthDatabase::new((path.clone(), "test".to_owned()))
84 .await
85 .expect("auth database"),
86 );
87
88 let proof = AuthProof {
89 keyset_id: Id::from_str("00916bbf7ef91a36").expect("valid keyset id"),
90 secret: Secret::generate(),
91 c: SecretKey::generate().public_key(),
92 dleq: None,
93 };
94 let y = proof.y().expect("proof y");
95
96 spend_auth_proof(db.clone(), proof.clone())
97 .await
98 .expect("first spend");
99 let second = spend_auth_proof(db.clone(), proof).await;
100
101 assert!(matches!(second, Err(database::Error::Duplicate)));
102 assert_eq!(
103 db.get_proofs_states(&[y]).await.expect("proof state"),
104 vec![Some(State::Spent)]
105 );
106
107 drop(db);
108 remove_file(path).expect("remove auth database");
109 }
110
111 #[tokio::test]
112 async fn open_legacy_and_migrate() {
113 let file = format!(
114 "{}/db.sqlite",
115 std::env::temp_dir().to_str().unwrap_or_default()
116 );
117
118 {
119 let _ = remove_file(&file);
120 #[cfg(not(feature = "sqlcipher"))]
121 let config: Config = file.as_str().into();
122 #[cfg(feature = "sqlcipher")]
123 let config: Config = (file.as_str(), "test").into();
124
125 let pool = Pool::<SqliteConnectionManager>::new(config);
126
127 let conn = pool.get().await.expect("valid connection");
128
129 query(include_str!("../../tests/legacy-sqlx.sql"))
130 .expect("query")
131 .execute(&*conn)
132 .await
133 .expect("create former db failed");
134 }
135
136 #[cfg(not(feature = "sqlcipher"))]
137 let conn = MintSqliteDatabase::new(file.as_str()).await;
138
139 #[cfg(feature = "sqlcipher")]
140 let conn = MintSqliteDatabase::new((file.as_str(), "test")).await;
141
142 assert!(conn.is_ok(), "Failed with {:?}", conn.unwrap_err());
143
144 let _ = remove_file(&file);
145 }
146}