diff --git a/src/identity/adapters/output/db/postgres/create_verification_secret.rs b/src/identity/adapters/output/db/postgres/create_verification_secret.rs new file mode 100644 index 0000000..21aa8d2 --- /dev/null +++ b/src/identity/adapters/output/db/postgres/create_verification_secret.rs @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use sqlx::types::time::OffsetDateTime; + +use super::DBOutPostgresAdapter; +use crate::identity::application::port::output::db::{create_verification_secret::*, errors::*}; + +#[async_trait::async_trait] +impl CreateVerificationSecretOutDBPort for DBOutPostgresAdapter { + async fn create_verification_secret(&self, msg: CreateSecretMsg) -> OutDBPortResult<()> { + sqlx::query!( + "INSERT INTO verification_otp (secret, created_at, purpose, username) + VALUES ($1, $2, $3, $4);", + &msg.secret, + OffsetDateTime::now_utc(), + &msg.purpose, + &msg.username, + ) + .execute(&self.pool) + .await?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[actix_rt::test] + async fn test_postgres_create_verification_secret() { + let settings = crate::settings::tests::get_settings().await; + let db = super::DBOutPostgresAdapter::new( + sqlx::postgres::PgPool::connect(&settings.database.url) + .await + .unwrap(), + ); + + let msg = CreateSecretMsgBuilder::default() + .secret("secret".into()) + .purpose("purpose".into()) + .username("username".into()) + .build() + .unwrap(); + + db.create_verification_secret(msg.clone()).await.unwrap(); + + // duplicate: secret exists + assert_eq!( + db.create_verification_secret(msg).await.err(), + Some(OutDBPortError::VerificationOTPSecretExists) + ); + + settings.drop_db().await; + } +}