diff --git a/src/identity/adapters/output/db/postgres/get_verification_secret.rs b/src/identity/adapters/output/db/postgres/get_verification_secret.rs new file mode 100644 index 0000000..cb6deca --- /dev/null +++ b/src/identity/adapters/output/db/postgres/get_verification_secret.rs @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use super::errors::*; +use super::DBOutPostgresAdapter; +use crate::identity::application::port::output::db::{errors::*, get_verification_secret::*}; + +#[async_trait::async_trait] +impl GetVerificationSecretOutDBPort for DBOutPostgresAdapter { + async fn get_verification_secret(&self, username: &str) -> OutDBPortResult { + struct Secret { + secret: String, + } + let res = sqlx::query_as!( + Secret, + "SELECT + secret + FROM + verification_otp + WHERE + username = $1 + AND + purpose = $2;", + username, + REGISTRATION_SECRET_PURPOSE, + ) + .fetch_one(&self.pool) + .await + .map_err(|e| map_row_not_found_err(e, OutDBPortError::VerificationOTPSecretNotFound))?; + Ok(res.secret) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::identity::application::port::output::db::create_verification_secret::*; + + #[actix_rt::test] + async fn test_postgres_get_verification_secret() { + let username = "batman"; + let secret = "bsdasdf"; + let settings = crate::settings::tests::get_settings().await; + let db = super::DBOutPostgresAdapter::new( + sqlx::postgres::PgPool::connect(&settings.database.url) + .await + .unwrap(), + ); + assert_eq!( + db.get_verification_secret(username).await.err(), + Some(OutDBPortError::VerificationOTPSecretNotFound) + ); + + let create_msg = CreateSecretMsgBuilder::default() + .secret(secret.into()) + .username(username.into()) + .build() + .unwrap(); + + db.create_verification_secret(create_msg).await.unwrap(); + + assert_eq!(db.get_verification_secret(username).await.unwrap(), secret); + + settings.drop_db().await; + } +} diff --git a/src/identity/adapters/output/db/postgres/mod.rs b/src/identity/adapters/output/db/postgres/mod.rs index 9a1e7dd..324c52f 100644 --- a/src/identity/adapters/output/db/postgres/mod.rs +++ b/src/identity/adapters/output/db/postgres/mod.rs @@ -13,6 +13,7 @@ pub mod create_verification_secret; pub mod delete_verification_secret; pub mod email_exists; mod errors; +pub mod get_verification_secret; pub mod username_exists; pub mod verification_secret_exists; diff --git a/src/identity/application/port/output/db/get_verification_secret.rs b/src/identity/application/port/output/db/get_verification_secret.rs new file mode 100644 index 0000000..5550423 --- /dev/null +++ b/src/identity/application/port/output/db/get_verification_secret.rs @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use mockall::predicate::*; +use mockall::*; + +pub use super::create_verification_secret::REGISTRATION_SECRET_PURPOSE; +use super::errors::*; +#[cfg(test)] +#[allow(unused_imports)] +pub use tests::*; + +#[automock] +#[async_trait::async_trait] +pub trait GetVerificationSecretOutDBPort: Send + Sync { + async fn get_verification_secret(&self, username: &str) -> OutDBPortResult; +} + +pub type GetVerificationSecretOutDBPortObj = std::sync::Arc; + +#[cfg(test)] +pub mod tests { + use super::*; + + use std::sync::Arc; + + pub fn mock_get_verification_secret_db_port( + times: Option, + returning_secret: String, + ) -> GetVerificationSecretOutDBPortObj { + let mut m = MockGetVerificationSecretOutDBPort::new(); + if let Some(times) = times { + m.expect_get_verification_secret() + .times(times) + .returning(move |_| Ok(returning_secret.clone())); + } else { + m.expect_get_verification_secret() + .returning(move |_| Ok(returning_secret.clone())); + } + + Arc::new(m) + } +}