feat(db): implement MerchantConnectorAccountInterface for MockDb (#1248)

Co-authored-by: jeeva <jeeva.ramu@codurance.com>
This commit is contained in:
Jeeva
2023-06-12 15:34:30 +01:00
committed by GitHub
parent c596d121a8
commit b002c97c9c
2 changed files with 156 additions and 30 deletions

View File

@ -1,5 +1,6 @@
use common_utils::ext_traits::{AsyncExt, ByteSliceExt, Encode}; use common_utils::ext_traits::{AsyncExt, ByteSliceExt, Encode};
use error_stack::{IntoReport, ResultExt}; use error_stack::{IntoReport, ResultExt};
use storage_models::merchant_connector_account::MerchantConnectorAccountUpdateInternal;
#[cfg(feature = "accounts_cache")] #[cfg(feature = "accounts_cache")]
use super::cache; use super::cache;
@ -138,7 +139,7 @@ where
async fn update_merchant_connector_account( async fn update_merchant_connector_account(
&self, &self,
this: domain::MerchantConnectorAccount, this: domain::MerchantConnectorAccount,
merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal, merchant_connector_account: MerchantConnectorAccountUpdateInternal,
) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>; ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>;
async fn delete_merchant_connector_account_by_merchant_id_merchant_connector_id( async fn delete_merchant_connector_account_by_merchant_id_merchant_connector_id(
@ -256,7 +257,7 @@ impl MerchantConnectorAccountInterface for Store {
async fn update_merchant_connector_account( async fn update_merchant_connector_account(
&self, &self,
this: domain::MerchantConnectorAccount, this: domain::MerchantConnectorAccount,
merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal, merchant_connector_account: MerchantConnectorAccountUpdateInternal,
) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
let _merchant_connector_id = this.merchant_connector_id.clone(); let _merchant_connector_id = this.merchant_connector_id.clone();
let update_call = || async { let update_call = || async {
@ -307,37 +308,71 @@ impl MerchantConnectorAccountInterface for Store {
#[async_trait::async_trait] #[async_trait::async_trait]
impl MerchantConnectorAccountInterface for MockDb { impl MerchantConnectorAccountInterface for MockDb {
// safety: only used for testing
#[allow(clippy::unwrap_used)]
async fn find_merchant_connector_account_by_merchant_id_connector_label( async fn find_merchant_connector_account_by_merchant_id_connector_label(
&self, &self,
merchant_id: &str, merchant_id: &str,
connector: &str, connector: &str,
) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
let accounts = self.merchant_connector_accounts.lock().await; match self
let account = accounts .merchant_connector_accounts
.lock()
.await
.iter() .iter()
.find(|account| { .find(|account| {
account.merchant_id == merchant_id && account.connector_name == connector account.merchant_id == merchant_id && account.connector_name == connector
}) })
.cloned() .cloned()
.unwrap(); .async_map(|account| async {
account account
.convert(self, merchant_id) .convert(self, merchant_id)
.await .await
.change_context(errors::StorageError::DecryptionError) .change_context(errors::StorageError::DecryptionError)
})
.await
{
Some(result) => result,
None => {
return Err(errors::StorageError::ValueNotFound(
"cannot find merchant connector account".to_string(),
)
.into())
}
}
} }
async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id( async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id(
&self, &self,
_merchant_id: &str, merchant_id: &str,
_merchant_connector_id: &str, merchant_connector_id: &str,
) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
// [#172]: Implement function for `MockDb` match self
Err(errors::StorageError::MockDbError)? .merchant_connector_accounts
.lock()
.await
.iter()
.find(|account| {
account.merchant_id == merchant_id
&& account.merchant_connector_id == merchant_connector_id
})
.cloned()
.async_map(|account| async {
account
.convert(self, merchant_id)
.await
.change_context(errors::StorageError::DecryptionError)
})
.await
{
Some(result) => result,
None => {
return Err(errors::StorageError::ValueNotFound(
"cannot find merchant connector account".to_string(),
)
.into())
}
}
} }
#[allow(clippy::panic)]
async fn insert_merchant_connector_account( async fn insert_merchant_connector_account(
&self, &self,
t: domain::MerchantConnectorAccount, t: domain::MerchantConnectorAccount,
@ -373,28 +408,91 @@ impl MerchantConnectorAccountInterface for MockDb {
async fn find_merchant_connector_account_by_merchant_id_and_disabled_list( async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
&self, &self,
_merchant_id: &str, merchant_id: &str,
_get_disabled: bool, get_disabled: bool,
) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError> { ) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError> {
// [#172]: Implement function for `MockDb` let accounts = self
Err(errors::StorageError::MockDbError)? .merchant_connector_accounts
.lock()
.await
.iter()
.filter(|account: &&storage::MerchantConnectorAccount| {
if get_disabled {
account.merchant_id == merchant_id
} else {
account.merchant_id == merchant_id && account.disabled == Some(false)
}
})
.cloned()
.collect::<Vec<storage::MerchantConnectorAccount>>();
let mut output = Vec::with_capacity(accounts.len());
for account in accounts.into_iter() {
output.push(
account
.convert(self, merchant_id)
.await
.change_context(errors::StorageError::DecryptionError)?,
)
}
Ok(output)
} }
async fn update_merchant_connector_account( async fn update_merchant_connector_account(
&self, &self,
_this: domain::MerchantConnectorAccount, merchant_connector_account: domain::MerchantConnectorAccount,
_merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal, updated_merchant_connector_account: MerchantConnectorAccountUpdateInternal,
) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
// [#172]: Implement function for `MockDb` match self
Err(errors::StorageError::MockDbError)? .merchant_connector_accounts
.lock()
.await
.iter_mut()
.find(|account| Some(account.id) == merchant_connector_account.id)
.map(|a| {
let updated =
updated_merchant_connector_account.create_merchant_connector_account(a.clone());
*a = updated.clone();
updated
})
.async_map(|account| async {
account
.convert(self, &merchant_connector_account.merchant_id)
.await
.change_context(errors::StorageError::DecryptionError)
})
.await
{
Some(result) => result,
None => {
return Err(errors::StorageError::ValueNotFound(
"cannot find merchant connector account to update".to_string(),
)
.into())
}
}
} }
async fn delete_merchant_connector_account_by_merchant_id_merchant_connector_id( async fn delete_merchant_connector_account_by_merchant_id_merchant_connector_id(
&self, &self,
_merchant_id: &str, merchant_id: &str,
_merchant_connector_id: &str, merchant_connector_id: &str,
) -> CustomResult<bool, errors::StorageError> { ) -> CustomResult<bool, errors::StorageError> {
// [#172]: Implement function for `MockDb` let mut accounts = self.merchant_connector_accounts.lock().await;
Err(errors::StorageError::MockDbError)? match accounts.iter().position(|account| {
account.merchant_id == merchant_id
&& account.merchant_connector_id == merchant_connector_id
}) {
Some(index) => {
accounts.remove(index);
return Ok(true);
}
None => {
return Err(errors::StorageError::ValueNotFound(
"cannot find merchant connector account to delete".to_string(),
)
.into())
}
}
} }
} }

View File

@ -1,5 +1,8 @@
use std::fmt::Debug;
use common_utils::pii; use common_utils::pii;
use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
use masking::Secret;
use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_connector_account}; use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_connector_account};
@ -29,7 +32,7 @@ pub struct MerchantConnectorAccount {
pub business_country: storage_enums::CountryAlpha2, pub business_country: storage_enums::CountryAlpha2,
pub business_label: String, pub business_label: String,
pub business_sub_label: Option<String>, pub business_sub_label: Option<String>,
pub frm_configs: Option<masking::Secret<serde_json::Value>>, pub frm_configs: Option<Secret<serde_json::Value>>,
pub created_at: time::PrimitiveDateTime, pub created_at: time::PrimitiveDateTime,
pub modified_at: time::PrimitiveDateTime, pub modified_at: time::PrimitiveDateTime,
} }
@ -50,7 +53,7 @@ pub struct MerchantConnectorAccountNew {
pub business_country: storage_enums::CountryAlpha2, pub business_country: storage_enums::CountryAlpha2,
pub business_label: String, pub business_label: String,
pub business_sub_label: Option<String>, pub business_sub_label: Option<String>,
pub frm_configs: Option<masking::Secret<serde_json::Value>>, pub frm_configs: Option<Secret<serde_json::Value>>,
pub created_at: time::PrimitiveDateTime, pub created_at: time::PrimitiveDateTime,
pub modified_at: time::PrimitiveDateTime, pub modified_at: time::PrimitiveDateTime,
} }
@ -67,6 +70,31 @@ pub struct MerchantConnectorAccountUpdateInternal {
pub merchant_connector_id: Option<String>, pub merchant_connector_id: Option<String>,
pub payment_methods_enabled: Option<Vec<serde_json::Value>>, pub payment_methods_enabled: Option<Vec<serde_json::Value>>,
pub metadata: Option<pii::SecretSerdeValue>, pub metadata: Option<pii::SecretSerdeValue>,
pub frm_configs: Option<masking::Secret<serde_json::Value>>, pub frm_configs: Option<Secret<serde_json::Value>>,
pub modified_at: Option<time::PrimitiveDateTime>, pub modified_at: Option<time::PrimitiveDateTime>,
} }
impl MerchantConnectorAccountUpdateInternal {
pub fn create_merchant_connector_account(
self,
source: MerchantConnectorAccount,
) -> MerchantConnectorAccount {
MerchantConnectorAccount {
merchant_id: self.merchant_id.unwrap_or(source.merchant_id),
connector_type: self.connector_type.unwrap_or(source.connector_type),
connector_account_details: self
.connector_account_details
.unwrap_or(source.connector_account_details),
test_mode: self.test_mode,
disabled: self.disabled,
merchant_connector_id: self
.merchant_connector_id
.unwrap_or(source.merchant_connector_id),
payment_methods_enabled: self.payment_methods_enabled,
frm_configs: self.frm_configs,
modified_at: self.modified_at.unwrap_or(source.modified_at),
..source
}
}
}