diff --git a/db/db-core/src/lib.rs b/db/db-core/src/lib.rs index 410d14be..aaccd9d6 100644 --- a/db/db-core/src/lib.rs +++ b/db/db-core/src/lib.rs @@ -232,6 +232,26 @@ pub trait MCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase { /// record PoWConfig confirms async fn record_confirm(&self, key: &str) -> DBResult<()>; + + /// featch PoWConfig fetches + async fn fetch_config_fetched(&self, user: &str, key: &str) -> DBResult>; + + /// featch PoWConfig solves + async fn fetch_solve(&self, user: &str, key: &str) -> DBResult>; + + /// featch PoWConfig confirms + async fn fetch_confirm(&self, user: &str, key: &str) -> DBResult>; +} + +#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)] +/// Captcha statistics with time recorded in UNIX epoch formats +pub struct StatsUnixTimestamp { + /// times at which the configuration were fetched + pub config_fetches: Vec, + /// times at which the PoW was solved + pub solves: Vec, + /// times at which the PoW token was verified + pub confirms: Vec, } #[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)] diff --git a/db/db-core/src/tests.rs b/db/db-core/src/tests.rs index 47986c1a..e5b351c4 100644 --- a/db/db-core/src/tests.rs +++ b/db/db-core/src/tests.rs @@ -209,14 +209,42 @@ pub async fn database_works<'a, T: MCDatabase>( let levels = db.get_captcha_levels(None, c.key).await.unwrap(); assert_eq!(levels, l); - // delete captcha levels - db.delete_captcha_levels(p.username, c.key).await.unwrap(); + /* + * Test stats + * 1. record fetch config + * 2. record solve + * 3. record token verify + * 4. fetch config fetches + * 5. fetch solves + * 6. fetch token verify + */ - // update captcha; set description = username and duration *= duration; - let mut c2 = c.clone(); - c2.duration *= c2.duration; - c2.description = p.username; - db.update_captcha_metadata(p.username, &c2).await.unwrap(); + assert!(db + .fetch_config_fetched(p.username, c.key) + .await + .unwrap() + .is_empty()); + assert!(db.fetch_solve(p.username, c.key).await.unwrap().is_empty()); + assert!(db + .fetch_confirm(p.username, c.key) + .await + .unwrap() + .is_empty()); + + db.record_fetch(c.key).await.unwrap(); + db.record_solve(c.key).await.unwrap(); + db.record_confirm(c.key).await.unwrap(); + + assert_eq!(db.fetch_solve(p.username, c.key).await.unwrap().len(), 1); + assert_eq!( + db.fetch_config_fetched(p.username, c.key) + .await + .unwrap() + .len(), + 1 + ); + assert_eq!(db.fetch_solve(p.username, c.key).await.unwrap().len(), 1); + assert_eq!(db.fetch_confirm(p.username, c.key).await.unwrap().len(), 1); // update captcha key; set key = username; db.update_captcha_key(p.username, c.key, p.username) @@ -230,6 +258,15 @@ pub async fn database_works<'a, T: MCDatabase>( .await .unwrap()); + // delete captcha levels + db.delete_captcha_levels(p.username, c.key).await.unwrap(); + + // update captcha; set description = username and duration *= duration; + let mut c2 = c.clone(); + c2.duration *= c2.duration; + c2.description = p.username; + db.update_captcha_metadata(p.username, &c2).await.unwrap(); + // delete captcha; updated key = p.username so invoke delete with it db.delete_captcha(p.username, p.username).await.unwrap(); assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());