From 1d4fb1d2474190ea0a70810e416c61883fab34b8 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com> Date: Tue, 30 Jul 2024 20:21:29 +0530 Subject: [PATCH] refactor(id_type): use macros for defining ID types and implementing common traits (#5471) --- crates/common_utils/src/id_type/customer.rs | 112 ++---------- crates/common_utils/src/id_type/merchant.rs | 110 ++--------- .../common_utils/src/id_type/organization.rs | 114 ++---------- crates/common_utils/src/lib.rs | 4 +- crates/common_utils/src/macros.rs | 172 +++++++++++++++++- crates/router/src/core/admin.rs | 6 +- crates/router/src/core/payment_methods.rs | 15 +- .../router/src/core/payment_methods/cards.rs | 2 +- crates/router/src/core/payments.rs | 2 +- crates/router/src/core/payments/helpers.rs | 8 +- .../payments/operations/payment_create.rs | 2 +- .../payments/operations/payment_reject.rs | 2 +- crates/router/src/core/user.rs | 2 +- .../src/core/webhooks/webhook_events.rs | 11 +- crates/router/src/db/api_keys.rs | 8 +- crates/router/src/db/dispute.rs | 41 +++-- crates/router/src/db/events.rs | 4 +- crates/router/src/db/merchant_account.rs | 2 +- .../src/db/merchant_connector_account.rs | 14 +- crates/router/src/db/merchant_key_store.rs | 10 +- crates/router/src/db/user_role.rs | 3 +- crates/router/src/routes/recon.rs | 4 +- crates/router/src/services/email/types.rs | 3 +- crates/router/src/types/domain/user.rs | 2 +- .../src/types/storage/payment_attempt.rs | 4 +- crates/router/src/utils/user/sample_data.rs | 5 +- crates/router/src/workflows/payment_sync.rs | 3 +- crates/router/tests/connectors/aci.rs | 10 +- crates/router/tests/connectors/cashtocode.rs | 2 +- crates/router/tests/connectors/utils.rs | 4 +- crates/router/tests/integration_demo.rs | 3 +- crates/router/tests/payments.rs | 8 +- crates/router/tests/payments2.rs | 8 +- crates/router/tests/utils.rs | 5 +- 34 files changed, 321 insertions(+), 384 deletions(-) diff --git a/crates/common_utils/src/id_type/customer.rs b/crates/common_utils/src/id_type/customer.rs index 00bd565d9e..6504912596 100644 --- a/crates/common_utils/src/id_type/customer.rs +++ b/crates/common_utils/src/id_type/customer.rs @@ -1,104 +1,14 @@ -use std::{borrow::Cow, fmt::Debug}; - -use diesel::{ - backend::Backend, - deserialize::FromSql, - expression::AsExpression, - serialize::{Output, ToSql}, - sql_types, Queryable, -}; -use error_stack::{Result, ResultExt}; -use serde::{Deserialize, Serialize}; - -use crate::{ - consts::{MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH}, - errors, generate_customer_id_of_default_length, - id_type::LengthId, -}; - -/// A type for customer_id that can be used for customer ids -#[derive(Clone, Serialize, Deserialize, Hash, PartialEq, Eq, AsExpression)] -#[diesel(sql_type = sql_types::Text)] -pub struct CustomerId( - LengthId, +crate::id_type!( + CustomerId, + "A type for customer_id that can be used for customer ids" ); +crate::impl_id_type_methods!(CustomerId, "customer_id"); -impl Default for CustomerId { - fn default() -> Self { - generate_customer_id_of_default_length() - } -} +// This is to display the `CustomerId` as CustomerId(abcd) +crate::impl_debug_id_type!(CustomerId); +crate::impl_default_id_type!(CustomerId, "cus"); +crate::impl_try_from_cow_str_id_type!(CustomerId, "customer_id"); -/// This is to display the `CustomerId` as CustomerId(abcd) -impl Debug for CustomerId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("CustomerId").field(&self.0 .0 .0).finish() - } -} - -impl Queryable for CustomerId -where - DB: Backend, - Self: FromSql, -{ - type Row = Self; - - fn build(row: Self::Row) -> diesel::deserialize::Result { - Ok(row) - } -} - -impl CustomerId { - pub(crate) fn new( - merchant_ref_id: LengthId< - MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, - MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH, - >, - ) -> Self { - Self(merchant_ref_id) - } - - /// Get the string representation of customer id - pub fn get_string_repr(&self) -> &str { - &self.0 .0 .0 - } - - /// Create a Customer id from string - pub fn from(input_string: Cow<'static, str>) -> Result { - let merchant_ref_id = LengthId::from(input_string).change_context( - errors::ValidationError::IncorrectValueProvided { - field_name: "customer_id", - }, - )?; - - Ok(Self(merchant_ref_id)) - } -} - -impl masking::SerializableSecret for CustomerId {} - -impl ToSql for CustomerId -where - DB: Backend, - LengthId: - ToSql, -{ - fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> diesel::serialize::Result { - self.0.to_sql(out) - } -} - -impl FromSql for CustomerId -where - DB: Backend, - LengthId: - FromSql, -{ - fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result { - LengthId::< - MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, - MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH, - >::from_sql(value) - .map(Self) - } -} +crate::impl_serializable_secret_id_type!(CustomerId); +crate::impl_queryable_id_type!(CustomerId); +crate::impl_to_sql_from_sql_id_type!(CustomerId); diff --git a/crates/common_utils/src/id_type/merchant.rs b/crates/common_utils/src/id_type/merchant.rs index 838cc52c1d..476d1d87a7 100644 --- a/crates/common_utils/src/id_type/merchant.rs +++ b/crates/common_utils/src/id_type/merchant.rs @@ -3,51 +3,29 @@ //! Ids for merchant account are derived from the merchant name //! If there are any special characters, they are removed -use std::{ - borrow::Cow, - fmt::{Debug, Display}, -}; - -use diesel::{ - backend::Backend, - deserialize::FromSql, - expression::AsExpression, - serialize::{Output, ToSql}, - sql_types, Queryable, -}; -use error_stack::{Result, ResultExt}; -use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; +use std::fmt::Display; use crate::{ - consts::{MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH}, - date_time, errors, generate_id_with_default_len, generate_ref_id_with_default_length, + date_time, generate_id_with_default_len, id_type::{AlphaNumericId, LengthId}, new_type::MerchantName, types::keymanager, }; -/// A type for merchant_id that can be used for merchant ids -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, AsExpression, Hash, ToSchema)] -#[diesel(sql_type = sql_types::Text)] -#[schema(value_type = String)] -pub struct MerchantId( - LengthId, +crate::id_type!( + MerchantId, + "A type for merchant_id that can be used for merchant ids" ); +crate::impl_id_type_methods!(MerchantId, "merchant_id"); -/// This is to display the `MerchantId` as MerchantId(abcd) -impl Debug for MerchantId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("MerchantId").field(&self.0 .0 .0).finish() - } -} +// This is to display the `MerchantId` as MerchantId(abcd) +crate::impl_debug_id_type!(MerchantId); +crate::impl_default_id_type!(MerchantId, "mer"); +crate::impl_try_from_cow_str_id_type!(MerchantId, "merchant_id"); -/// This should be temporary, we should not have direct impl of Display for merchant id -impl Display for MerchantId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.get_string_repr()) - } -} +crate::impl_serializable_secret_id_type!(MerchantId); +crate::impl_queryable_id_type!(MerchantId); +crate::impl_to_sql_from_sql_id_type!(MerchantId); #[cfg(feature = "metrics")] /// This is implemented so that we can use merchant id directly as attribute in metrics @@ -58,41 +36,7 @@ impl From for router_env::opentelemetry::Value { } } -impl Queryable for MerchantId -where - DB: Backend, - Self: FromSql, -{ - type Row = Self; - - fn build(row: Self::Row) -> diesel::deserialize::Result { - Ok(row) - } -} - -impl Default for MerchantId { - fn default() -> Self { - Self(generate_ref_id_with_default_length("mer")) - } -} - impl MerchantId { - /// Get the string representation of merchant id - pub fn get_string_repr(&self) -> &str { - &self.0 .0 .0 - } - - /// Create a Merchant id from string - pub fn from(input_string: Cow<'static, str>) -> Result { - let length_id = LengthId::from(input_string).change_context( - errors::ValidationError::IncorrectValueProvided { - field_name: "merchant_id", - }, - )?; - - Ok(Self(length_id)) - } - /// Create a Merchant id from MerchantName pub fn from_merchant_name(merchant_name: MerchantName) -> Self { let merchant_name_string = merchant_name.into_inner(); @@ -144,34 +88,6 @@ impl From for keymanager::Identifier { } } -impl masking::SerializableSecret for MerchantId {} - -impl ToSql for MerchantId -where - DB: Backend, - LengthId: - ToSql, -{ - fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> diesel::serialize::Result { - self.0.to_sql(out) - } -} - -impl FromSql for MerchantId -where - DB: Backend, - LengthId: - FromSql, -{ - fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result { - LengthId::< - MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, - MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH, - >::from_sql(value) - .map(Self) - } -} - /// All the keys that can be formed from merchant id impl MerchantId { /// get step up enabled key diff --git a/crates/common_utils/src/id_type/organization.rs b/crates/common_utils/src/id_type/organization.rs index cd2b6c202f..336442e605 100644 --- a/crates/common_utils/src/id_type/organization.rs +++ b/crates/common_utils/src/id_type/organization.rs @@ -1,106 +1,14 @@ -use std::{borrow::Cow, fmt::Debug}; - -use diesel::{ - backend::Backend, - deserialize::FromSql, - expression::AsExpression, - serialize::{Output, ToSql}, - sql_types, Queryable, -}; -use error_stack::{Result, ResultExt}; -use serde::{Deserialize, Serialize}; - -use crate::{ - consts::{MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH}, - errors, generate_organization_id_of_default_length, - id_type::LengthId, -}; - -/// A type for customer_id that can be used for customer ids -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, AsExpression, Hash)] -#[diesel(sql_type = sql_types::Text)] -pub struct OrganizationId( - LengthId, +crate::id_type!( + OrganizationId, + "A type for organization_id that can be used for organization ids" ); +crate::impl_id_type_methods!(OrganizationId, "organization_id"); -impl Default for OrganizationId { - fn default() -> Self { - generate_organization_id_of_default_length() - } -} +// This is to display the `OrganizationId` as OrganizationId(abcd) +crate::impl_debug_id_type!(OrganizationId); +crate::impl_default_id_type!(OrganizationId, "org"); +crate::impl_try_from_cow_str_id_type!(OrganizationId, "organization_id"); -/// This is to display the `OrganizationId` as OrganizationId(abcd) -impl Debug for OrganizationId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("OrganizationId") - .field(&self.0 .0 .0) - .finish() - } -} - -impl Queryable for OrganizationId -where - DB: Backend, - Self: FromSql, -{ - type Row = Self; - - fn build(row: Self::Row) -> diesel::deserialize::Result { - Ok(row) - } -} - -impl OrganizationId { - pub(crate) fn new( - organization_id: LengthId< - MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, - MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH, - >, - ) -> Self { - Self(organization_id) - } - - /// Get the string representation of customer id - pub fn get_string_repr(&self) -> &str { - &self.0 .0 .0 - } - - /// Create a Customer id from string - pub fn from(input_string: Cow<'static, str>) -> Result { - let organization_id = LengthId::from(input_string).change_context( - errors::ValidationError::IncorrectValueProvided { - field_name: "customer_id", - }, - )?; - - Ok(Self(organization_id)) - } -} - -impl masking::SerializableSecret for OrganizationId {} - -impl ToSql for OrganizationId -where - DB: Backend, - LengthId: - ToSql, -{ - fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> diesel::serialize::Result { - self.0.to_sql(out) - } -} - -impl FromSql for OrganizationId -where - DB: Backend, - LengthId: - FromSql, -{ - fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result { - LengthId::< - MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, - MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH, - >::from_sql(value) - .map(Self) - } -} +crate::impl_serializable_secret_id_type!(OrganizationId); +crate::impl_queryable_id_type!(OrganizationId); +crate::impl_to_sql_from_sql_id_type!(OrganizationId); diff --git a/crates/common_utils/src/lib.rs b/crates/common_utils/src/lib.rs index e7a8076195..197996629f 100644 --- a/crates/common_utils/src/lib.rs +++ b/crates/common_utils/src/lib.rs @@ -217,12 +217,12 @@ fn generate_ref_id_with_default_length id_type::CustomerId { - id_type::CustomerId::new(generate_ref_id_with_default_length("cus")) + id_type::CustomerId::default() } /// Generate a organization id with default length, with prefix as `org` pub fn generate_organization_id_of_default_length() -> id_type::OrganizationId { - id_type::OrganizationId::new(generate_ref_id_with_default_length("org")) + id_type::OrganizationId::default() } /// Generate a nanoid with the given prefix and a default length diff --git a/crates/common_utils/src/macros.rs b/crates/common_utils/src/macros.rs index 9491187156..abd24ac867 100644 --- a/crates/common_utils/src/macros.rs +++ b/crates/common_utils/src/macros.rs @@ -1,9 +1,10 @@ -#![allow(missing_docs)] +//! Utility macros +#[allow(missing_docs)] #[macro_export] macro_rules! newtype_impl { ($is_pub:vis, $name:ident, $ty_path:path) => { - impl std::ops::Deref for $name { + impl core::ops::Deref for $name { type Target = $ty_path; fn deref(&self) -> &Self::Target { @@ -11,7 +12,7 @@ macro_rules! newtype_impl { } } - impl std::ops::DerefMut for $name { + impl core::ops::DerefMut for $name { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } @@ -31,6 +32,7 @@ macro_rules! newtype_impl { }; } +#[allow(missing_docs)] #[macro_export] macro_rules! newtype { ($is_pub:vis $name:ident = $ty_path:path) => { @@ -59,6 +61,7 @@ macro_rules! openapi_route { }}; } +#[allow(missing_docs)] #[macro_export] macro_rules! fallback_reverse_lookup_not_found { ($a:expr,$b:expr) => { @@ -81,6 +84,8 @@ macro_rules! fallback_reverse_lookup_not_found { }; } +/// Collects names of all optional fields that are `None`. +/// This is typically useful for constructing error messages including a list of all missing fields. #[macro_export] macro_rules! collect_missing_value_keys { [$(($key:literal, $option:expr)),+] => { @@ -96,6 +101,8 @@ macro_rules! collect_missing_value_keys { }; } +/// Implements the `ToSql` and `FromSql` traits on a type to allow it to be serialized/deserialized +/// to/from JSON data in the database. #[macro_export] macro_rules! impl_to_sql_from_sql_json { ($type:ty, $diesel_type:ty) => { @@ -135,3 +142,162 @@ macro_rules! impl_to_sql_from_sql_json { $crate::impl_to_sql_from_sql_json!($type, diesel::sql_types::Jsonb); }; } + +mod id_type { + /// Defines an ID type. + #[macro_export] + macro_rules! id_type { + ($type:ident, $doc:literal, $diesel_type:ty, $max_length:expr, $min_length:expr) => { + #[doc = $doc] + #[derive( + Clone, + Hash, + PartialEq, + Eq, + serde::Serialize, + serde::Deserialize, + diesel::expression::AsExpression, + )] + #[diesel(sql_type = $diesel_type)] + pub struct $type($crate::id_type::LengthId<$max_length, $min_length>); + }; + ($type:ident, $doc:literal) => { + $crate::id_type!( + $type, + $doc, + diesel::sql_types::Text, + { $crate::consts::MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH }, + { $crate::consts::MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH } + ); + }; + } + + /// Implements common methods on the specified ID type. + #[macro_export] + macro_rules! impl_id_type_methods { + ($type:ty, $field_name:literal) => { + impl $type { + /// Get the string representation of the ID type. + pub fn get_string_repr(&self) -> &str { + &self.0 .0 .0 + } + } + }; + } + + /// Implements the `Debug` trait on the specified ID type. + #[macro_export] + macro_rules! impl_debug_id_type { + ($type:ty) => { + impl core::fmt::Debug for $type { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_tuple(stringify!($type)) + .field(&self.0 .0 .0) + .finish() + } + } + }; + } + + /// Implements the `TryFrom>` trait on the specified ID type. + #[macro_export] + macro_rules! impl_try_from_cow_str_id_type { + ($type:ty, $field_name:literal) => { + impl TryFrom> for $type { + type Error = error_stack::Report<$crate::errors::ValidationError>; + + fn try_from(value: std::borrow::Cow<'static, str>) -> Result { + use error_stack::ResultExt; + + let merchant_ref_id = $crate::id_type::LengthId::from(value).change_context( + $crate::errors::ValidationError::IncorrectValueProvided { + field_name: $field_name, + }, + )?; + + Ok(Self(merchant_ref_id)) + } + } + }; + } + + /// Implements the `Default` trait on the specified ID type. + #[macro_export] + macro_rules! impl_default_id_type { + ($type:ty, $prefix:literal) => { + impl Default for $type { + fn default() -> Self { + Self($crate::generate_ref_id_with_default_length($prefix)) + } + } + }; + } + + /// Implements the `SerializableSecret` trait on the specified ID type. + #[macro_export] + macro_rules! impl_serializable_secret_id_type { + ($type:ty) => { + impl masking::SerializableSecret for $type {} + }; + } + + /// Implements the `ToSql` and `FromSql` traits on the specified ID type. + #[macro_export] + macro_rules! impl_to_sql_from_sql_id_type { + ($type:ty, $diesel_type:ty, $max_length:expr, $min_length:expr) => { + impl diesel::serialize::ToSql<$diesel_type, DB> for $type + where + DB: diesel::backend::Backend, + $crate::id_type::LengthId<$max_length, $min_length>: + diesel::serialize::ToSql<$diesel_type, DB>, + { + fn to_sql<'b>( + &'b self, + out: &mut diesel::serialize::Output<'b, '_, DB>, + ) -> diesel::serialize::Result { + self.0.to_sql(out) + } + } + + impl diesel::deserialize::FromSql<$diesel_type, DB> for $type + where + DB: diesel::backend::Backend, + $crate::id_type::LengthId<$max_length, $min_length>: + diesel::deserialize::FromSql<$diesel_type, DB>, + { + fn from_sql(value: DB::RawValue<'_>) -> diesel::deserialize::Result { + $crate::id_type::LengthId::<$max_length, $min_length>::from_sql(value).map(Self) + } + } + }; + ($type:ty) => { + $crate::impl_to_sql_from_sql_id_type!( + $type, + diesel::sql_types::Text, + { $crate::consts::MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH }, + { $crate::consts::MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH } + ); + }; + } + + /// Implements the `Queryable` trait on the specified ID type. + #[macro_export] + macro_rules! impl_queryable_id_type { + ($type:ty, $diesel_type:ty) => { + impl diesel::Queryable<$diesel_type, DB> for $type + where + DB: diesel::backend::Backend, + Self: diesel::deserialize::FromSql<$diesel_type, DB>, + { + type Row = Self; + + fn build(row: Self::Row) -> diesel::deserialize::Result { + Ok(row) + } + } + }; + ($type:ty) => { + $crate::impl_queryable_id_type!($type, diesel::sql_types::Text); + }; + } +} diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index adee4b1445..530f857950 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -2018,7 +2018,7 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate { connector_webhook_details.encode_to_value( ) .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable(format!("Failed to serialize api_models::admin::MerchantConnectorWebhookDetails for Merchant: {}", business_profile.merchant_id)) + .attach_printable(format!("Failed to serialize api_models::admin::MerchantConnectorWebhookDetails for Merchant: {:?}", business_profile.merchant_id)) .map(Some)? .map(Secret::new) } @@ -2186,7 +2186,7 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate { connector_webhook_details.encode_to_value( ) .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable(format!("Failed to serialize api_models::admin::MerchantConnectorWebhookDetails for Merchant: {}", business_profile.merchant_id)) + .attach_printable(format!("Failed to serialize api_models::admin::MerchantConnectorWebhookDetails for Merchant: {:?}", business_profile.merchant_id)) .map(Some)? .map(Secret::new) } @@ -3592,7 +3592,7 @@ async fn locker_recipient_create_call( let merchant_id_string = merchant_id.get_string_repr().to_owned(); - let cust_id = id_type::CustomerId::from(merchant_id_string.into()) + let cust_id = id_type::CustomerId::try_from(std::borrow::Cow::from(merchant_id_string)) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to convert to CustomerId")?; diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs index 6566d30e12..988d6beeb8 100644 --- a/crates/router/src/core/payment_methods.rs +++ b/crates/router/src/core/payment_methods.rs @@ -1,10 +1,13 @@ -use std::collections::HashSet; pub mod cards; pub mod migration; pub mod surcharge_decision_configs; pub mod transformers; pub mod utils; +mod validator; pub mod vault; + +use std::{borrow::Cow, collections::HashSet}; + pub use api_models::enums::Connector; #[cfg(feature = "payouts")] pub use api_models::{enums::PayoutConnectors, payouts as payout_types}; @@ -37,7 +40,6 @@ use crate::{ domain, storage, }, }; -mod validator; const PAYMENT_METHOD_STATUS_UPDATE_TASK: &str = "PAYMENT_METHOD_STATUS_UPDATE"; const PAYMENT_METHOD_STATUS_TAG: &str = "PAYMENT_METHOD_STATUS"; @@ -146,11 +148,10 @@ pub async fn initiate_pm_collect_link( req.return_url.clone(), ) .await?; - let customer_id = CustomerId::from(pm_collect_link.primary_reference.into()).change_context( - errors::ApiErrorResponse::InvalidDataValue { + let customer_id = CustomerId::try_from(Cow::from(pm_collect_link.primary_reference)) + .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "customer_id", - }, - )?; + })?; // Return response let url = pm_collect_link.url.peek(); @@ -259,7 +260,7 @@ pub async fn render_pm_collect_link( // else, send back form link } else { let customer_id = - CustomerId::from(pm_collect_link.primary_reference.clone().into()) + CustomerId::try_from(Cow::from(pm_collect_link.primary_reference.clone())) .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "customer_id", })?; diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index c867824c65..a0b5f7755f 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -2371,7 +2371,7 @@ pub async fn list_payment_methods( })?; format!( "pm_filters_cgraph_{}_{}", - merchant_account.get_id(), + merchant_account.get_id().get_string_repr(), profile_id ) }; diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index a165264117..f1dce992d1 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -1723,7 +1723,7 @@ pub async fn get_merchant_bank_data_for_open_banking_connectors( if contains { // Customer Id for OpenBanking connectors will be merchant_id as the account data stored at locker belongs to the merchant let merchant_id_str = merchant_account.get_id().get_string_repr().to_owned(); - let cust_id = id_type::CustomerId::from(merchant_id_str.into()) + let cust_id = id_type::CustomerId::try_from(std::borrow::Cow::from(merchant_id_str)) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to convert to CustomerId")?; let locker_resp = cards::get_payment_method_from_hs_locker( diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index f6bdd78fc2..6c598e67a3 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -784,7 +784,8 @@ pub fn validate_merchant_id( utils::when(merchant_id.ne(request_merchant_id), || { Err(report!(errors::ApiErrorResponse::PreconditionFailed { message: format!( - "Invalid `merchant_id`: {request_merchant_id} not found in merchant account" + "Invalid `merchant_id`: {} not found in merchant account", + request_merchant_id.get_string_repr() ) })) }) @@ -5029,7 +5030,10 @@ pub fn get_redis_key_for_extended_card_info( merchant_id: &id_type::MerchantId, payment_id: &str, ) -> String { - format!("{merchant_id}_{payment_id}_extended_card_info") + format!( + "{}_{payment_id}_extended_card_info", + merchant_id.get_string_repr() + ) } pub fn check_integrity_based_on_flow( diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 07233be399..1723084d0f 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -1229,7 +1229,7 @@ async fn create_payment_link( format!( "{}/payment_link/s/{}/{}", domain_name, - merchant_id.clone(), + merchant_id.get_string_repr(), payment_id.clone() ) }); diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs index 4e46791c8e..35cdafe002 100644 --- a/crates/router/src/core/payments/operations/payment_reject.rs +++ b/crates/router/src/core/payments/operations/payment_reject.rs @@ -117,7 +117,7 @@ impl GetTracker, PaymentsCancelRequest> for P .await .change_context(errors::ApiErrorResponse::PaymentNotFound) .attach_printable_lazy(|| { - format!("Error while retrieving frm_response, merchant_id: {}, payment_id: {attempt_id}", merchant_account.get_id()) + format!("Error while retrieving frm_response, merchant_id: {:?}, payment_id: {attempt_id}", merchant_account.get_id()) }); let profile_id = payment_intent diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index ba85a382db..40741c7619 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -949,7 +949,7 @@ pub async fn resend_invite( if e.current_context().is_db_not_found() { e.change_context(UserErrors::InvalidRoleOperation) .attach_printable(format!( - "User role with user_id = {} and merchant_id = {} is not found", + "User role with user_id = {} and merchant_id = {:?} is not found", user.get_user_id(), user_from_token.merchant_id )) diff --git a/crates/router/src/core/webhooks/webhook_events.rs b/crates/router/src/core/webhooks/webhook_events.rs index 034cf936c1..f8799ca82d 100644 --- a/crates/router/src/core/webhooks/webhook_events.rs +++ b/crates/router/src/core/webhooks/webhook_events.rs @@ -272,11 +272,12 @@ async fn determine_identifier_and_get_key_store( ) -> errors::RouterResult<(MerchantAccountOrBusinessProfile, domain::MerchantKeyStore)> { let store = state.store.as_ref(); let key_manager_state = &(&state).into(); - let merchant_id = - common_utils::id_type::MerchantId::from(merchant_id_or_profile_id.clone().into()) - .change_context(errors::ApiErrorResponse::InvalidDataValue { - field_name: "merchant_id", - })?; + let merchant_id = common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from( + merchant_id_or_profile_id.clone(), + )) + .change_context(errors::ApiErrorResponse::InvalidDataValue { + field_name: "merchant_id", + })?; match store .get_merchant_key_store_by_merchant_id( key_manager_state, diff --git a/crates/router/src/db/api_keys.rs b/crates/router/src/db/api_keys.rs index 186bd004c1..62d261aa3c 100644 --- a/crates/router/src/db/api_keys.rs +++ b/crates/router/src/db/api_keys.rs @@ -372,6 +372,8 @@ impl ApiKeyInterface for MockDb { #[cfg(test)] mod tests { + use std::borrow::Cow; + use storage_impl::redis::{ cache::{self, CacheKey, CacheKind, ACCOUNTS_CACHE}, kv_store::RedisConnInterface, @@ -392,7 +394,8 @@ mod tests { .await .expect("Failed to create Mock store"); - let merchant_id = common_utils::id_type::MerchantId::from("merchant1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant1")).unwrap(); let key1 = mockdb .insert_api_key(storage::ApiKeyNew { @@ -478,7 +481,8 @@ mod tests { #[allow(clippy::unwrap_used)] #[tokio::test] async fn test_api_keys_cache() { - let merchant_id = common_utils::id_type::MerchantId::from("test_merchant".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("test_merchant")).unwrap(); #[allow(clippy::expect_used)] let db = MockDb::new(&redis_interface::RedisSettings::default()) diff --git a/crates/router/src/db/dispute.rs b/crates/router/src/db/dispute.rs index 073b725448..9d6093bfe3 100644 --- a/crates/router/src/db/dispute.rs +++ b/crates/router/src/db/dispute.rs @@ -361,8 +361,10 @@ impl DisputeInterface for MockDb { #[cfg(test)] mod tests { - #[allow(clippy::unwrap_used)] + #![allow(clippy::expect_used, clippy::unwrap_used)] mod mockdb_dispute_interface { + use std::borrow::Cow; + use api_models::disputes::DisputeListConstraints; use diesel_models::{ dispute::DisputeNew, @@ -410,12 +412,12 @@ mod tests { #[tokio::test] async fn test_insert_dispute() { - #[allow(clippy::expect_used)] let mockdb = MockDb::new(&RedisSettings::default()) .await .expect("Failed to create a mock DB"); - let merchant_id = common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); let created_dispute = mockdb .insert_dispute(create_dispute_new(DisputeNewIds { @@ -443,9 +445,9 @@ mod tests { #[tokio::test] async fn test_find_by_merchant_id_payment_id_connector_dispute_id() { - let merchant_id = common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); - #[allow(clippy::expect_used)] let mockdb = MockDb::new(&RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -488,8 +490,9 @@ mod tests { #[tokio::test] async fn test_find_dispute_by_merchant_id_dispute_id() { - let merchant_id = common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); - #[allow(clippy::expect_used)] + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); + let mockdb = MockDb::new(&RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -526,8 +529,9 @@ mod tests { #[tokio::test] async fn test_find_disputes_by_merchant_id() { - let merchant_id = common_utils::id_type::MerchantId::from("merchant_2".into()).unwrap(); - #[allow(clippy::expect_used)] + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_2")).unwrap(); + let mockdb = MockDb::new(&RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -581,8 +585,9 @@ mod tests { #[tokio::test] async fn test_find_disputes_by_merchant_id_payment_id() { - let merchant_id = common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); - #[allow(clippy::expect_used)] + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); + let mockdb = MockDb::new(&RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -620,6 +625,8 @@ mod tests { } mod update_dispute { + use std::borrow::Cow; + use diesel_models::{ dispute::DisputeUpdate, enums::{DisputeStage, DisputeStatus}, @@ -639,8 +646,8 @@ mod tests { #[tokio::test] async fn test_update_dispute_update() { let merchant_id = - common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); - #[allow(clippy::expect_used)] + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); + let mockdb = MockDb::new(&redis_interface::RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -720,8 +727,8 @@ mod tests { #[tokio::test] async fn test_update_dispute_update_status() { let merchant_id = - common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); - #[allow(clippy::expect_used)] + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); + let mockdb = MockDb::new(&redis_interface::RedisSettings::default()) .await .expect("Failed to create Mock store"); @@ -796,8 +803,8 @@ mod tests { #[tokio::test] async fn test_update_dispute_update_evidence() { let merchant_id = - common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); - #[allow(clippy::expect_used)] + common_utils::id_type::MerchantId::try_from(Cow::from("merchant_1")).unwrap(); + let mockdb = MockDb::new(&redis_interface::RedisSettings::default()) .await .expect("Failed to create Mock store"); diff --git a/crates/router/src/db/events.rs b/crates/router/src/db/events.rs index 4cb05ba5ba..0cecea9c62 100644 --- a/crates/router/src/db/events.rs +++ b/crates/router/src/db/events.rs @@ -806,7 +806,9 @@ mod tests { let state = &Arc::new(app_state) .get_session_state("public", || {}) .unwrap(); - let merchant_id = common_utils::id_type::MerchantId::from("merchant_1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from("merchant_1")) + .unwrap(); let business_profile_id = "profile1"; let payment_id = "test_payment_id"; let key_manager_state = &state.into(); diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs index aee54b3e1b..d707ec17c3 100644 --- a/crates/router/src/db/merchant_account.rs +++ b/crates/router/src/db/merchant_account.rs @@ -583,7 +583,7 @@ async fn publish_and_redact_merchant_account_cache( CacheKind::CGraph( format!( "cgraph_{}_{}", - merchant_account.get_id().clone(), + merchant_account.get_id().get_string_repr(), profile_id, ) .into(), diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index 22f67b3538..31f5e285c4 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -226,7 +226,7 @@ impl MerchantConnectorAccountInterface for Store { { cache::get_or_populate_in_memory( self, - &format!("{}_{}", merchant_id, connector_label), + &format!("{}_{}", merchant_id.get_string_repr(), connector_label), find_call, &cache::ACCOUNTS_CACHE, ) @@ -1061,7 +1061,9 @@ mod merchant_connector_account_cache_tests { .await .unwrap(); - let merchant_id = common_utils::id_type::MerchantId::from("test_merchant".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from("test_merchant")) + .unwrap(); let connector_label = "stripe_USA"; let merchant_connector_id = "simple_merchant_connector_id"; @@ -1157,7 +1159,7 @@ mod merchant_connector_account_cache_tests { }; let _: storage::MerchantConnectorAccount = cache::get_or_populate_in_memory( &db, - &format!("{}_{}", merchant_id, profile_id), + &format!("{}_{}", merchant_id.get_string_repr(), profile_id), find_call, &ACCOUNTS_CACHE, ) @@ -1174,7 +1176,9 @@ mod merchant_connector_account_cache_tests { cache::publish_and_redact( &db, - CacheKind::Accounts(format!("{}_{}", merchant_id, connector_label).into()), + CacheKind::Accounts( + format!("{}_{}", merchant_id.get_string_repr(), connector_label).into(), + ), delete_call, ) .await @@ -1182,7 +1186,7 @@ mod merchant_connector_account_cache_tests { assert!(ACCOUNTS_CACHE .get_val::(CacheKey { - key: format!("{}_{}", merchant_id, connector_label), + key: format!("{}_{}", merchant_id.get_string_repr(), connector_label), prefix: String::default(), },) .await diff --git a/crates/router/src/db/merchant_key_store.rs b/crates/router/src/db/merchant_key_store.rs index 9540a420e9..1fe24999b6 100644 --- a/crates/router/src/db/merchant_key_store.rs +++ b/crates/router/src/db/merchant_key_store.rs @@ -106,7 +106,8 @@ impl MerchantKeyStoreInterface for Store { #[cfg(feature = "accounts_cache")] { - let key_store_cache_key = format!("merchant_key_store_{}", merchant_id); + let key_store_cache_key = + format!("merchant_key_store_{}", merchant_id.get_string_repr()); cache::get_or_populate_in_memory( self, &key_store_cache_key, @@ -318,7 +319,7 @@ impl MerchantKeyStoreInterface for MockDb { #[cfg(test)] mod tests { - use std::sync::Arc; + use std::{borrow::Cow, sync::Arc}; use common_utils::types::keymanager::Identifier; use time::macros::datetime; @@ -354,7 +355,8 @@ mod tests { .await .expect("Failed to create mock DB"); let master_key = mock_db.get_master_key(); - let merchant_id = common_utils::id_type::MerchantId::from("merchant1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(Cow::from("merchant1")).unwrap(); let identifier = Identifier::Merchant(merchant_id.clone()); let key_manager_state = &state.into(); let merchant_key1 = mock_db @@ -410,7 +412,7 @@ mod tests { assert!(insert_duplicate_merchant_key1_result.is_err()); let non_existent_merchant_id = - common_utils::id_type::MerchantId::from("non_existent".into()).unwrap(); + common_utils::id_type::MerchantId::try_from(Cow::from("non_existent")).unwrap(); let find_non_existent_merchant_key_result = mock_db .get_merchant_key_store_by_merchant_id( diff --git a/crates/router/src/db/user_role.rs b/crates/router/src/db/user_role.rs index 8689dfc653..203860728c 100644 --- a/crates/router/src/db/user_role.rs +++ b/crates/router/src/db/user_role.rs @@ -380,7 +380,8 @@ impl UserRoleInterface for MockDb { Err(errors::StorageError::ValueNotFound(format!( "No user role available for user_id = {} and merchant_id = {}", - user_id, merchant_id + user_id, + merchant_id.get_string_repr() )) .into()) } diff --git a/crates/router/src/routes/recon.rs b/crates/router/src/routes/recon.rs index 910e2e8f96..96a935aef5 100644 --- a/crates/router/src/routes/recon.rs +++ b/crates/router/src/routes/recon.rs @@ -143,7 +143,7 @@ pub async fn send_recon_request( .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { - format!("Failed while updating merchant's recon status: {merchant_id}") + format!("Failed while updating merchant's recon status: {merchant_id:?}") })?; Ok(service_api::ApplicationResponse::Json( @@ -197,7 +197,7 @@ pub async fn recon_merchant_account_update( .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { - format!("Failed while updating merchant's recon status: {merchant_id}") + format!("Failed while updating merchant's recon status: {merchant_id:?}") })?; let email_contents = email_types::ReconActivation { diff --git a/crates/router/src/services/email/types.rs b/crates/router/src/services/email/types.rs index 56505316a6..3a17966fac 100644 --- a/crates/router/src/services/email/types.rs +++ b/crates/router/src/services/email/types.rs @@ -127,11 +127,12 @@ pub mod html { Dashboard Pro Feature Request, Feature name : {feature_name} -Merchant ID : {merchant_id} +Merchant ID : {} Merchant Name : {user_name} Email : {user_email} (note: This is an auto generated email. Use merchant email for any further communications)", + merchant_id.get_string_repr() ), EmailBody::ApiKeyExpiryReminder { expires_in, diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 2de6bc44fb..1a2ac3fa05 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -340,7 +340,7 @@ impl MerchantId { impl TryFrom for id_type::MerchantId { type Error = error_stack::Report; fn try_from(value: MerchantId) -> Result { - Self::from(value.0.into()) + Self::try_from(std::borrow::Cow::from(value.0)) .change_context(UserErrors::MerchantIdParsingError) .attach_printable("Could not convert user merchant_id to merchant_id type") } diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs index 18560837bc..02182c25ec 100644 --- a/crates/router/src/types/storage/payment_attempt.rs +++ b/crates/router/src/types/storage/payment_attempt.rs @@ -195,7 +195,9 @@ mod tests { async fn test_payment_attempt_mandate_field() { let state = create_single_connection_test_transaction_pool().await; let uuid = Uuid::new_v4().to_string(); - let merchant_id = common_utils::id_type::MerchantId::from("merchant1".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from("merchant1")) + .unwrap(); let current_time = common_utils::date_time::now(); let connector = types::Connector::DummyConnector1.to_string(); diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs index b1ab16ac03..86607234d4 100644 --- a/crates/router/src/utils/user/sample_data.rs +++ b/crates/router/src/utils/user/sample_data.rs @@ -145,8 +145,9 @@ pub async fn generate_sample_data( } // This has to be an internal server error because, this function failing means that the intended functionality is not working as expected - let dashboard_customer_id = id_type::CustomerId::from("hs-dashboard-user".into()) - .change_context(SampleDataError::InternalServerError)?; + let dashboard_customer_id = + id_type::CustomerId::try_from(std::borrow::Cow::from("hs-dashboard-user")) + .change_context(SampleDataError::InternalServerError)?; for num in 1..=sample_data_size { let payment_id = common_utils::generate_id_with_default_len("test"); diff --git a/crates/router/src/workflows/payment_sync.rs b/crates/router/src/workflows/payment_sync.rs index d626241e32..ebac4e08d5 100644 --- a/crates/router/src/workflows/payment_sync.rs +++ b/crates/router/src/workflows/payment_sync.rs @@ -289,7 +289,8 @@ mod tests { #[test] fn test_get_default_schedule_time() { - let merchant_id = common_utils::id_type::MerchantId::from("-".into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from("-")).unwrap(); let schedule_time_delta = scheduler_utils::get_schedule_time( process_data::ConnectorPTMapping::default(), &merchant_id, diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs index 72663079f2..b1e6bbed29 100644 --- a/crates/router/tests/connectors/aci.rs +++ b/crates/router/tests/connectors/aci.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, str::FromStr, sync::Arc}; +use std::{borrow::Cow, marker::PhantomData, str::FromStr, sync::Arc}; use api_models::payments::{Address, AddressDetails, PhoneDetails}; use common_utils::id_type; @@ -20,12 +20,12 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData { .aci .expect("Missing ACI connector authentication configuration"); - let merchant_id = id_type::MerchantId::from("aci".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("aci")).unwrap(); types::RouterData { flow: PhantomData, merchant_id, - customer_id: Some(id_type::CustomerId::from("aci".into()).unwrap()), + customer_id: Some(id_type::CustomerId::try_from(Cow::from("aci")).unwrap()), connector: "aci".to_string(), payment_id: uuid::Uuid::new_v4().to_string(), attempt_id: uuid::Uuid::new_v4().to_string(), @@ -133,12 +133,12 @@ fn construct_refund_router_data() -> types::RefundsRouterData { .aci .expect("Missing ACI connector authentication configuration"); - let merchant_id = id_type::MerchantId::from("aci".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("aci")).unwrap(); types::RouterData { flow: PhantomData, merchant_id, - customer_id: Some(id_type::CustomerId::from("aci".into()).unwrap()), + customer_id: Some(id_type::CustomerId::try_from(Cow::from("aci")).unwrap()), connector: "aci".to_string(), payment_id: uuid::Uuid::new_v4().to_string(), attempt_id: uuid::Uuid::new_v4().to_string(), diff --git a/crates/router/tests/connectors/cashtocode.rs b/crates/router/tests/connectors/cashtocode.rs index 3af6e277de..7656cd67de 100644 --- a/crates/router/tests/connectors/cashtocode.rs +++ b/crates/router/tests/connectors/cashtocode.rs @@ -42,7 +42,7 @@ impl CashtocodeTest { payment_method_type: Option, payment_method_data: domain::PaymentMethodData, ) -> Option { - let cust_id = id_type::CustomerId::from("John Doe".into()); + let cust_id = id_type::CustomerId::try_from(std::borrow::Cow::from("John Doe")); Some(types::PaymentsAuthorizeData { amount: 1000, currency: enums::Currency::EUR, diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 47e7274c05..16e1d6a7c2 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -481,7 +481,9 @@ pub trait ConnectorActions: Connector { req: Req, info: Option, ) -> RouterData { - let merchant_id = common_utils::id_type::MerchantId::from(self.get_name().into()).unwrap(); + let merchant_id = + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from(self.get_name())) + .unwrap(); RouterData { flow: PhantomData, diff --git a/crates/router/tests/integration_demo.rs b/crates/router/tests/integration_demo.rs index 773f3c3ab7..5ee50c1263 100644 --- a/crates/router/tests/integration_demo.rs +++ b/crates/router/tests/integration_demo.rs @@ -16,7 +16,8 @@ async fn create_merchant_account() { let expected = "merchant_12345"; let expected_merchant_id_type = - common_utils::id_type::MerchantId::from("merchant_12345".into()).unwrap(); + common_utils::id_type::MerchantId::try_from(std::borrow::Cow::from("merchant_12345")) + .unwrap(); let hlist_pat![merchant_id, _api_key]: HList![MerchantId, ApiKey] = admin_client .create_merchant_account(&server, expected.to_owned()) diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs index 31d5e52c3c..8a5235a536 100644 --- a/crates/router/tests/payments.rs +++ b/crates/router/tests/payments.rs @@ -2,7 +2,7 @@ mod utils; -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; use common_utils::{id_type, types::MinorUnit}; use router::{ @@ -286,7 +286,7 @@ async fn payments_create_core() { )) .await; - let merchant_id = id_type::MerchantId::from("juspay_merchant".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("juspay_merchant")).unwrap(); let state = Arc::new(app_state) .get_session_state("public", || {}) @@ -478,7 +478,7 @@ async fn payments_create_core_adyen_no_redirect() { .unwrap(); let customer_id = format!("cust_{}", Uuid::new_v4()); - let merchant_id = id_type::MerchantId::from("juspay_merchant".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("juspay_merchant")).unwrap(); let payment_id = "pay_mbabizu24mvu3mela5njyhpit10".to_string(); let key_manager_state = &(&state).into(); let key_store = state @@ -506,7 +506,7 @@ async fn payments_create_core_adyen_no_redirect() { amount_to_capture: Some(MinorUnit::new(6540)), capture_on: Some(datetime!(2022-09-10 10:11:12)), confirm: Some(true), - customer_id: Some(id_type::CustomerId::from(customer_id.into()).unwrap()), + customer_id: Some(id_type::CustomerId::try_from(Cow::from(customer_id)).unwrap()), description: Some("Its my first payment request".to_string()), return_url: Some(url::Url::parse("http://example.com/payments").unwrap()), setup_future_usage: Some(api_enums::FutureUsage::OnSession), diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs index 20bf10da72..aa984b9a0e 100644 --- a/crates/router/tests/payments2.rs +++ b/crates/router/tests/payments2.rs @@ -2,7 +2,7 @@ mod utils; -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; use common_utils::{id_type, types::MinorUnit}; use router::{ @@ -46,7 +46,7 @@ async fn payments_create_core() { )) .await; - let merchant_id = id_type::MerchantId::from("juspay_merchant".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("juspay_merchant")).unwrap(); let state = Arc::new(app_state) .get_session_state("public", || {}) @@ -245,7 +245,7 @@ async fn payments_create_core_adyen_no_redirect() { .unwrap(); let customer_id = format!("cust_{}", Uuid::new_v4()); - let merchant_id = id_type::MerchantId::from("juspay_merchant".into()).unwrap(); + let merchant_id = id_type::MerchantId::try_from(Cow::from("juspay_merchant")).unwrap(); let payment_id = "pay_mbabizu24mvu3mela5njyhpit10".to_string(); let key_manager_state = &(&state).into(); let key_store = state @@ -273,7 +273,7 @@ async fn payments_create_core_adyen_no_redirect() { amount_to_capture: Some(MinorUnit::new(6540)), capture_on: Some(datetime!(2022-09-10 10:11:12)), confirm: Some(true), - customer_id: Some(id_type::CustomerId::from(customer_id.into()).unwrap()), + customer_id: Some(id_type::CustomerId::try_from(Cow::from(customer_id)).unwrap()), description: Some("Its my first payment request".to_string()), return_url: Some(url::Url::parse("http://example.com/payments").unwrap()), setup_future_usage: Some(api_enums::FutureUsage::OffSession), diff --git a/crates/router/tests/utils.rs b/crates/router/tests/utils.rs index 96ea3c7d02..c6632798ab 100644 --- a/crates/router/tests/utils.rs +++ b/crates/router/tests/utils.rs @@ -112,7 +112,10 @@ impl AppClient { B: MessageBody, { let request = TestRequest::post() - .uri(&format!("/account/{merchant_id}/connectors")) + .uri(&format!( + "/account/{}/connectors", + merchant_id.get_string_repr() + )) .append_header(("api-key".to_owned(), self.state.authkey.clone())) .set_json(mk_connector(connector_name, api_key)) .to_request();