mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
refactor: fix unit and documentation tests (#4754)
This commit is contained in:
11
.github/nextest.toml
vendored
Normal file
11
.github/nextest.toml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[profile.default]
|
||||||
|
status-level = "slow"
|
||||||
|
final-status-level = "leak"
|
||||||
|
failure-output = "final"
|
||||||
|
fail-fast = false
|
||||||
|
|
||||||
|
[profile.ci]
|
||||||
|
retries = 2
|
||||||
|
status-level = "all"
|
||||||
|
failure-output = "final"
|
||||||
|
fail-fast = false
|
||||||
55
.github/workflows/CI-pr.yml
vendored
55
.github/workflows/CI-pr.yml
vendored
@ -33,8 +33,8 @@ env:
|
|||||||
RUSTUP_MAX_RETRIES: 10
|
RUSTUP_MAX_RETRIES: 10
|
||||||
# Don't emit giant backtraces in the CI logs.
|
# Don't emit giant backtraces in the CI logs.
|
||||||
RUST_BACKTRACE: short
|
RUST_BACKTRACE: short
|
||||||
# Use cargo's sparse index protocol
|
# Use `sccache` for caching compilation artifacts
|
||||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
RUSTC_WRAPPER: sccache
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
formatting:
|
formatting:
|
||||||
@ -88,14 +88,7 @@ jobs:
|
|||||||
|
|
||||||
check-msrv:
|
check-msrv:
|
||||||
name: Check compilation on MSRV toolchain
|
name: Check compilation on MSRV toolchain
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: hyperswitch-runners
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-latest
|
|
||||||
# - macos-latest
|
|
||||||
# - windows-latest
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@ -122,14 +115,17 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: "${{ env.rust_version }}"
|
toolchain: "${{ env.rust_version }}"
|
||||||
|
|
||||||
- uses: Swatinem/rust-cache@v2.7.0
|
- name: Install sccache
|
||||||
|
uses: taiki-e/install-action@v2.33.28
|
||||||
with:
|
with:
|
||||||
save-if: false
|
tool: sccache
|
||||||
|
checksum: true
|
||||||
|
|
||||||
- name: Install cargo-hack
|
- name: Install cargo-hack
|
||||||
uses: baptiste0928/cargo-install@v2.2.0
|
uses: taiki-e/install-action@v2.33.28
|
||||||
with:
|
with:
|
||||||
crate: cargo-hack
|
tool: cargo-hack
|
||||||
|
checksum: true
|
||||||
|
|
||||||
- name: Deny warnings
|
- name: Deny warnings
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -210,14 +206,7 @@ jobs:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
name: Run tests on stable toolchain
|
name: Run tests on stable toolchain
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: hyperswitch-runners
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-latest
|
|
||||||
# - macos-latest
|
|
||||||
# - windows-latest
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
@ -256,19 +245,23 @@ jobs:
|
|||||||
toolchain: stable 2 weeks ago
|
toolchain: stable 2 weeks ago
|
||||||
components: clippy
|
components: clippy
|
||||||
|
|
||||||
- name: Install cargo-hack
|
- name: Install sccache
|
||||||
uses: baptiste0928/cargo-install@v2.2.0
|
uses: taiki-e/install-action@v2.33.28
|
||||||
with:
|
with:
|
||||||
crate: cargo-hack
|
tool: sccache
|
||||||
|
checksum: true
|
||||||
|
|
||||||
|
- name: Install cargo-hack
|
||||||
|
uses: taiki-e/install-action@v2.33.28
|
||||||
|
with:
|
||||||
|
tool: cargo-hack
|
||||||
|
checksum: true
|
||||||
|
|
||||||
# - name: Install cargo-nextest
|
# - name: Install cargo-nextest
|
||||||
# uses: baptiste0928/cargo-install@v2.2.0
|
# uses: taiki-e/install-action@v2.33.28
|
||||||
# with:
|
# with:
|
||||||
# crate: cargo-nextest
|
# tool: cargo-nextest
|
||||||
|
# checksum: true
|
||||||
- uses: Swatinem/rust-cache@v2.7.0
|
|
||||||
with:
|
|
||||||
save-if: false
|
|
||||||
|
|
||||||
# - name: Setup Embark Studios lint rules
|
# - name: Setup Embark Studios lint rules
|
||||||
# shell: bash
|
# shell: bash
|
||||||
|
|||||||
18
.github/workflows/CI-push.yml
vendored
18
.github/workflows/CI-push.yml
vendored
@ -39,14 +39,7 @@ jobs:
|
|||||||
|
|
||||||
check-msrv:
|
check-msrv:
|
||||||
name: Check compilation on MSRV toolchain
|
name: Check compilation on MSRV toolchain
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-latest
|
|
||||||
# - macos-latest
|
|
||||||
# - windows-latest
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@ -115,14 +108,7 @@ jobs:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
name: Run tests on stable toolchain
|
name: Run tests on stable toolchain
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-latest
|
|
||||||
# - macos-latest
|
|
||||||
# - windows-latest
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
|||||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -6030,7 +6030,9 @@ dependencies = [
|
|||||||
name = "router_derive"
|
name = "router_derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"common_utils",
|
||||||
"diesel",
|
"diesel",
|
||||||
|
"error-stack",
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -6038,6 +6040,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"strum 0.26.2",
|
"strum 0.26.2",
|
||||||
"syn 2.0.57",
|
"syn 2.0.57",
|
||||||
|
"utoipa",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -314,6 +314,7 @@ mod tests {
|
|||||||
& payment_method /= voucher
|
& payment_method /= voucher
|
||||||
& payment_method /= gift_card
|
& payment_method /= gift_card
|
||||||
& payment_method /= card_redirect
|
& payment_method /= card_redirect
|
||||||
|
& payment_method /= real_time_payment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,7 +163,8 @@ pub trait FromEncoded: Sized {
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use your_module::{FromEncoded, masking::Secret, Vec};
|
/// use external_services::hashicorp_vault::core::FromEncoded;
|
||||||
|
/// use masking::Secret;
|
||||||
/// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string());
|
/// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string());
|
||||||
/// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string());
|
/// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string());
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@ -22,7 +22,7 @@ pub struct PaymentsAuthorizeData {
|
|||||||
pub payment_method_data: PaymentMethodData,
|
pub payment_method_data: PaymentMethodData,
|
||||||
/// total amount (original_amount + surcharge_amount + tax_on_surcharge_amount)
|
/// total amount (original_amount + surcharge_amount + tax_on_surcharge_amount)
|
||||||
/// If connector supports separate field for surcharge amount, consider using below functions defined on `PaymentsAuthorizeData` to fetch original amount and surcharge amount separately
|
/// If connector supports separate field for surcharge amount, consider using below functions defined on `PaymentsAuthorizeData` to fetch original amount and surcharge amount separately
|
||||||
/// ```
|
/// ```text
|
||||||
/// get_original_amount()
|
/// get_original_amount()
|
||||||
/// get_surcharge_amount()
|
/// get_surcharge_amount()
|
||||||
/// get_tax_on_surcharge_amount()
|
/// get_tax_on_surcharge_amount()
|
||||||
|
|||||||
@ -15,26 +15,43 @@ This solution has such advantages over alternatives:
|
|||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
To convert non-secret variable into secret use `new()`. Sample:
|
To convert a non-secret variable into a secret, use `Secret::new()`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
expiry_year: ccard.map(|x| Secret::new(x.card_exp_year.to_string())),
|
use masking::Secret;
|
||||||
// output: "expiry_year: *** alloc::string::String ***"
|
|
||||||
|
let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
|
||||||
|
assert_eq!(format!("{:?}", card_number), "*** alloc::string::String ***");
|
||||||
```
|
```
|
||||||
|
|
||||||
To get value from secret use `expose()`. Sample:
|
To get a reference to the inner value from the secret, use `peek()`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
last4_digits: Some(card_number.expose())
|
use masking::{PeekInterface, Secret};
|
||||||
|
|
||||||
|
let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
|
||||||
|
let last4_digits: &str = card_number.peek();
|
||||||
```
|
```
|
||||||
|
|
||||||
Most fields are under `Option`. To simplify dealing with `Option`, use `expose_option()`. Sample:
|
To get the owned inner value from the secret, use `expose()`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
card_info.push_str(
|
use masking::{ExposeInterface, Secret};
|
||||||
&card_detail
|
|
||||||
.card_holder_name
|
let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
|
||||||
.expose_option()
|
let last4_digits: String = card_number.expose();
|
||||||
.unwrap_or_default(),
|
```
|
||||||
);
|
|
||||||
|
For fields that are `Option<T>`, you can use `expose_option()`:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use masking::{ExposeOptionInterface, Secret};
|
||||||
|
|
||||||
|
let card_number: Option<Secret<String>> = Some(Secret::new(String::from("1234 5678 9012 3456")));
|
||||||
|
let card_number_str: String = card_number.expose_option().unwrap_or_default();
|
||||||
|
assert_eq!(format!("{}", card_number_str), "1234 5678 9012 3456");
|
||||||
|
|
||||||
|
let card_number: Option<Secret<String>> = None;
|
||||||
|
let card_number_str: String = card_number.expose_option().unwrap_or_default();
|
||||||
|
assert_eq!(format!("{}", card_number_str), "");
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1001,15 +1001,10 @@ mod hashmap_deserialization_test {
|
|||||||
fn test_payment_method_and_payment_method_types() {
|
fn test_payment_method_and_payment_method_types() {
|
||||||
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
||||||
|
|
||||||
let input_map: HashMap<String, String> = serde_json::json!({
|
let input_map: HashMap<String, String> = HashMap::from([
|
||||||
"bank_transfer": "ach,bacs",
|
("bank_transfer".to_string(), "ach,bacs".to_string()),
|
||||||
"wallet": "paypal,venmo",
|
("wallet".to_string(), "paypal,venmo".to_string()),
|
||||||
})
|
]);
|
||||||
.as_object()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
|
||||||
.collect();
|
|
||||||
let deserializer: MapDeserializer<
|
let deserializer: MapDeserializer<
|
||||||
'_,
|
'_,
|
||||||
std::collections::hash_map::IntoIter<String, String>,
|
std::collections::hash_map::IntoIter<String, String>,
|
||||||
@ -1035,15 +1030,10 @@ mod hashmap_deserialization_test {
|
|||||||
fn test_payment_method_and_payment_method_types_with_spaces() {
|
fn test_payment_method_and_payment_method_types_with_spaces() {
|
||||||
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
||||||
|
|
||||||
let input_map: HashMap<String, String> = serde_json::json!({
|
let input_map: HashMap<String, String> = HashMap::from([
|
||||||
" bank_transfer ": " ach , bacs ",
|
(" bank_transfer ".to_string(), " ach , bacs ".to_string()),
|
||||||
"wallet ": " paypal , pix , venmo ",
|
("wallet ".to_string(), " paypal , pix , venmo ".to_string()),
|
||||||
})
|
]);
|
||||||
.as_object()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
|
||||||
.collect();
|
|
||||||
let deserializer: MapDeserializer<
|
let deserializer: MapDeserializer<
|
||||||
'_,
|
'_,
|
||||||
std::collections::hash_map::IntoIter<String, String>,
|
std::collections::hash_map::IntoIter<String, String>,
|
||||||
@ -1073,15 +1063,10 @@ mod hashmap_deserialization_test {
|
|||||||
fn test_payment_method_deserializer_error() {
|
fn test_payment_method_deserializer_error() {
|
||||||
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
use diesel_models::enums::{PaymentMethod, PaymentMethodType};
|
||||||
|
|
||||||
let input_map: HashMap<String, String> = serde_json::json!({
|
let input_map: HashMap<String, String> = HashMap::from([
|
||||||
"unknown": "ach,bacs",
|
("unknown".to_string(), "ach,bacs".to_string()),
|
||||||
"wallet": "paypal,unknown",
|
("wallet".to_string(), "paypal,unknown".to_string()),
|
||||||
})
|
]);
|
||||||
.as_object()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
|
||||||
.collect();
|
|
||||||
let deserializer: MapDeserializer<
|
let deserializer: MapDeserializer<
|
||||||
'_,
|
'_,
|
||||||
std::collections::hash_map::IntoIter<String, String>,
|
std::collections::hash_map::IntoIter<String, String>,
|
||||||
|
|||||||
@ -118,8 +118,8 @@ pub struct ThreeDSRequestor {
|
|||||||
/// External IP address (i.e., the device public IP address) used by the 3DS Requestor App when it connects to the
|
/// External IP address (i.e., the device public IP address) used by the 3DS Requestor App when it connects to the
|
||||||
/// 3DS Requestor environment. The value length is maximum 45 characters. Accepted values are:
|
/// 3DS Requestor environment. The value length is maximum 45 characters. Accepted values are:
|
||||||
///
|
///
|
||||||
/// IPv4 address is represented in the dotted decimal f. Refer to RFC 791.
|
/// - IPv4 address is represented in the dotted decimal f. Refer to RFC 791.
|
||||||
/// IPv6 address. Refer to RFC 4291.
|
/// - IPv6 address. Refer to RFC 4291.
|
||||||
///
|
///
|
||||||
/// This field is required when deviceChannel = 01 (APP) and unless market or regional mandate restricts sending
|
/// This field is required when deviceChannel = 01 (APP) and unless market or regional mandate restricts sending
|
||||||
/// this information.
|
/// this information.
|
||||||
@ -1454,17 +1454,17 @@ pub struct Sdk {
|
|||||||
/// The Split-SDK Server:
|
/// The Split-SDK Server:
|
||||||
/// Creates a JSON object of the following data as the JWS payload to be signed:
|
/// Creates a JSON object of the following data as the JWS payload to be signed:
|
||||||
///
|
///
|
||||||
/// SDK Reference Number -> Identifies the vendor and version of the 3DS SDK that is utilised for a specific
|
/// - SDK Reference Number -> Identifies the vendor and version of the 3DS SDK that is utilised for a specific
|
||||||
/// transaction. The value is assigned by EMVCo when the Letter of Approval of the
|
/// transaction. The value is assigned by EMVCo when the Letter of Approval of the
|
||||||
/// specific 3DS SDK is issued. The field is limited to 32 characters.
|
/// specific 3DS SDK is issued. The field is limited to 32 characters.
|
||||||
/// SDK Signature Timestamp -> Date and time indicating when the 3DS SDK generated the Split-SDK Server Signed
|
/// - SDK Signature Timestamp -> Date and time indicating when the 3DS SDK generated the Split-SDK Server Signed
|
||||||
/// Content converted into UTC. The value is limited to 14 characters. Accepted
|
/// Content converted into UTC. The value is limited to 14 characters. Accepted
|
||||||
/// format: YYYYMMDDHHMMSS.
|
/// format: YYYYMMDDHHMMSS.
|
||||||
/// SDK Transaction ID -> Universally unique transaction identifier assigned by the 3DS SDK to identify a
|
/// - SDK Transaction ID -> Universally unique transaction identifier assigned by the 3DS SDK to identify a
|
||||||
/// single transaction. The field is limited to 36 characters and it shall be in a
|
/// single transaction. The field is limited to 36 characters and it shall be in a
|
||||||
/// canonical format as defined in IETF RFC 4122. This may utilize any of the specified
|
/// canonical format as defined in IETF RFC 4122. This may utilize any of the specified
|
||||||
/// versions as long as the output meets specific requirements.
|
/// versions as long as the output meets specific requirements.
|
||||||
/// Split-SDK Server ID -> DS assigned Split-SDK Server identifier. Each DS can provide a unique ID to each
|
/// - Split-SDK Server ID -> DS assigned Split-SDK Server identifier. Each DS can provide a unique ID to each
|
||||||
/// Split-SDK Server on an individual basis. The field is limited to 32 characters.
|
/// Split-SDK Server on an individual basis. The field is limited to 32 characters.
|
||||||
/// Any individual DS may impose specific formatting and character requirements on the
|
/// Any individual DS may impose specific formatting and character requirements on the
|
||||||
/// contents of this field.
|
/// contents of this field.
|
||||||
@ -1473,8 +1473,8 @@ pub struct Sdk {
|
|||||||
/// Serialization. The parameter values for this version of the specification and to be included in the JWS
|
/// Serialization. The parameter values for this version of the specification and to be included in the JWS
|
||||||
/// header are:
|
/// header are:
|
||||||
///
|
///
|
||||||
/// "alg": PS2567 or ES256
|
/// - `alg`: PS2567 or ES256
|
||||||
/// "x5c": X.5C v3: Cert (PbSDK) and chaining certificates if present
|
/// - `x5c`: X.5C v3: Cert (PbSDK) and chaining certificates if present
|
||||||
///
|
///
|
||||||
/// All other parameters: optional
|
/// All other parameters: optional
|
||||||
///
|
///
|
||||||
|
|||||||
@ -3098,7 +3098,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_authenticate_client_secret_fulfillment_time_not_expired() {
|
fn test_authenticate_client_secret_session_not_expired() {
|
||||||
let payment_intent = PaymentIntent {
|
let payment_intent = PaymentIntent {
|
||||||
payment_id: "23".to_string(),
|
payment_id: "23".to_string(),
|
||||||
merchant_id: "22".to_string(),
|
merchant_id: "22".to_string(),
|
||||||
@ -3160,7 +3160,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_authenticate_client_secret_fulfillment_time_expired() {
|
fn test_authenticate_client_secret_session_expired() {
|
||||||
|
let created_at =
|
||||||
|
common_utils::date_time::now().saturating_sub(time::Duration::seconds(20 * 60));
|
||||||
let payment_intent = PaymentIntent {
|
let payment_intent = PaymentIntent {
|
||||||
payment_id: "23".to_string(),
|
payment_id: "23".to_string(),
|
||||||
merchant_id: "22".to_string(),
|
merchant_id: "22".to_string(),
|
||||||
@ -3177,7 +3179,7 @@ mod tests {
|
|||||||
billing_address_id: None,
|
billing_address_id: None,
|
||||||
statement_descriptor_name: None,
|
statement_descriptor_name: None,
|
||||||
statement_descriptor_suffix: None,
|
statement_descriptor_suffix: None,
|
||||||
created_at: common_utils::date_time::now().saturating_sub(time::Duration::seconds(20)),
|
created_at,
|
||||||
modified_at: common_utils::date_time::now(),
|
modified_at: common_utils::date_time::now(),
|
||||||
fingerprint_id: None,
|
fingerprint_id: None,
|
||||||
last_synced: None,
|
last_synced: None,
|
||||||
@ -3206,8 +3208,7 @@ mod tests {
|
|||||||
incremental_authorization_allowed: None,
|
incremental_authorization_allowed: None,
|
||||||
authorization_count: None,
|
authorization_count: None,
|
||||||
session_expiry: Some(
|
session_expiry: Some(
|
||||||
common_utils::date_time::now()
|
created_at.saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
|
||||||
.saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
|
|
||||||
),
|
),
|
||||||
request_external_three_ds_authentication: None,
|
request_external_three_ds_authentication: None,
|
||||||
charges: None,
|
charges: None,
|
||||||
|
|||||||
@ -754,7 +754,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert!(updated_event.is_webhook_notified);
|
assert!(updated_event.is_webhook_notified);
|
||||||
assert_eq!(updated_event.primary_object_id, "primary_object_tet");
|
assert_eq!(updated_event.primary_object_id, payment_id);
|
||||||
assert_eq!(updated_event.event_id, event_id);
|
assert_eq!(updated_event.event_id, event_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,20 +99,28 @@ mod tests {
|
|||||||
types::{self, storage::enums},
|
types::{self, storage::enums},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[actix_rt::test]
|
async fn create_single_connection_test_transaction_pool() -> routes::AppState {
|
||||||
#[ignore]
|
// Set pool size to 1 and minimum idle connection size to 0
|
||||||
async fn test_payment_attempt_insert() {
|
std::env::set_var("ROUTER__MASTER_DATABASE__POOL_SIZE", "1");
|
||||||
|
std::env::set_var("ROUTER__MASTER_DATABASE__MIN_IDLE", "0");
|
||||||
|
std::env::set_var("ROUTER__REPLICA_DATABASE__POOL_SIZE", "1");
|
||||||
|
std::env::set_var("ROUTER__REPLICA_DATABASE__MIN_IDLE", "0");
|
||||||
|
|
||||||
let conf = Settings::new().expect("invalid settings");
|
let conf = Settings::new().expect("invalid settings");
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
||||||
let api_client = Box::new(services::MockApiClient);
|
let api_client = Box::new(services::MockApiClient);
|
||||||
let state = Box::pin(routes::AppState::with_storage(
|
Box::pin(routes::AppState::with_storage(
|
||||||
conf,
|
conf,
|
||||||
StorageImpl::PostgresqlTest,
|
StorageImpl::PostgresqlTest,
|
||||||
tx,
|
tx,
|
||||||
api_client,
|
api_client,
|
||||||
))
|
))
|
||||||
.await;
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_payment_attempt_insert() {
|
||||||
|
let state = create_single_connection_test_transaction_pool().await;
|
||||||
let payment_id = Uuid::new_v4().to_string();
|
let payment_id = Uuid::new_v4().to_string();
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
let connector = types::Connector::DummyConnector1.to_string();
|
let connector = types::Connector::DummyConnector1.to_string();
|
||||||
@ -137,22 +145,11 @@ mod tests {
|
|||||||
assert_eq!(response.payment_id, payment_id.clone());
|
assert_eq!(response.payment_id, payment_id.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[tokio::test]
|
||||||
/// Example of unit test
|
/// Example of unit test
|
||||||
/// Kind of test: state-based testing
|
/// Kind of test: state-based testing
|
||||||
async fn test_find_payment_attempt() {
|
async fn test_find_payment_attempt() {
|
||||||
use crate::configs::settings::Settings;
|
let state = create_single_connection_test_transaction_pool().await;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
|
||||||
let api_client = Box::new(services::MockApiClient);
|
|
||||||
let state = Box::pin(routes::AppState::with_storage(
|
|
||||||
conf,
|
|
||||||
StorageImpl::PostgresqlTest,
|
|
||||||
tx,
|
|
||||||
api_client,
|
|
||||||
))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
let payment_id = Uuid::new_v4().to_string();
|
let payment_id = Uuid::new_v4().to_string();
|
||||||
let attempt_id = Uuid::new_v4().to_string();
|
let attempt_id = Uuid::new_v4().to_string();
|
||||||
@ -192,23 +189,12 @@ mod tests {
|
|||||||
assert_eq!(response.payment_id, payment_id);
|
assert_eq!(response.payment_id, payment_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[tokio::test]
|
||||||
/// Example of unit test
|
/// Example of unit test
|
||||||
/// Kind of test: state-based testing
|
/// Kind of test: state-based testing
|
||||||
async fn test_payment_attempt_mandate_field() {
|
async fn test_payment_attempt_mandate_field() {
|
||||||
use crate::configs::settings::Settings;
|
let state = create_single_connection_test_transaction_pool().await;
|
||||||
let conf = Settings::new().expect("invalid settings");
|
|
||||||
let uuid = Uuid::new_v4().to_string();
|
let uuid = Uuid::new_v4().to_string();
|
||||||
let tx: oneshot::Sender<()> = oneshot::channel().0;
|
|
||||||
|
|
||||||
let api_client = Box::new(services::MockApiClient);
|
|
||||||
let state = Box::pin(routes::AppState::with_storage(
|
|
||||||
conf,
|
|
||||||
StorageImpl::PostgresqlTest,
|
|
||||||
tx,
|
|
||||||
api_client,
|
|
||||||
))
|
|
||||||
.await;
|
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
let connector = types::Connector::DummyConnector1.to_string();
|
let connector = types::Connector::DummyConnector1.to_string();
|
||||||
|
|
||||||
|
|||||||
@ -20,5 +20,9 @@ strum = { version = "0.26.2", features = ["derive"] }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
diesel = { version = "2.1.5", features = ["postgres"] }
|
diesel = { version = "2.1.5", features = ["postgres"] }
|
||||||
|
error-stack = "0.4.1"
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.115"
|
serde_json = "1.0.115"
|
||||||
|
utoipa = "4.2.0"
|
||||||
|
|
||||||
|
common_utils = { version = "0.1.0", path = "../common_utils" }
|
||||||
|
|||||||
@ -63,7 +63,7 @@ pub fn debug_as_display_derive(input: proc_macro::TokenStream) -> proc_macro::To
|
|||||||
/// // yourself if required.
|
/// // yourself if required.
|
||||||
/// #[derive(strum::Display, strum::EnumString)]
|
/// #[derive(strum::Display, strum::EnumString)]
|
||||||
/// #[derive(Debug)]
|
/// #[derive(Debug)]
|
||||||
/// #[diesel_enum(storage_type = "pg_enum")]
|
/// #[diesel_enum(storage_type = "db_enum")]
|
||||||
/// enum Color {
|
/// enum Color {
|
||||||
/// Red,
|
/// Red,
|
||||||
/// Green,
|
/// Green,
|
||||||
@ -153,12 +153,14 @@ pub fn diesel_enum(
|
|||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// use router_derive::Setter;
|
/// use router_derive::Setter;
|
||||||
|
///
|
||||||
|
/// #[derive(Setter)]
|
||||||
/// struct Test {
|
/// struct Test {
|
||||||
/// test:u32
|
/// test:u32
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// The above Example will expand to
|
/// The above Example will expand to
|
||||||
/// ```
|
/// ```rust, ignore
|
||||||
/// impl Test {
|
/// impl Test {
|
||||||
/// fn set_test(&mut self, val: u32) -> &mut Self {
|
/// fn set_test(&mut self, val: u32) -> &mut Self {
|
||||||
/// self.test = val;
|
/// self.test = val;
|
||||||
@ -381,7 +383,7 @@ pub fn api_error_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
|
|||||||
/// - update_tracker
|
/// - update_tracker
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```
|
/// ```rust, ignore
|
||||||
/// use router_derive::Operation;
|
/// use router_derive::Operation;
|
||||||
///
|
///
|
||||||
/// #[derive(Operation)]
|
/// #[derive(Operation)]
|
||||||
@ -470,12 +472,14 @@ pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
|
|||||||
/// Generates different schemas with the ability to mark few fields as mandatory for certain schema
|
/// Generates different schemas with the ability to mark few fields as mandatory for certain schema
|
||||||
/// Usage
|
/// Usage
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use router_derive::PolymorphicSchema;
|
||||||
|
///
|
||||||
/// #[derive(PolymorphicSchema)]
|
/// #[derive(PolymorphicSchema)]
|
||||||
/// #[generate_schemas(PaymentsCreateRequest, PaymentsConfirmRequest)]
|
/// #[generate_schemas(PaymentsCreateRequest, PaymentsConfirmRequest)]
|
||||||
/// struct PaymentsRequest {
|
/// struct PaymentsRequest {
|
||||||
/// #[mandatory_in(PaymentsCreateRequest)]
|
/// #[mandatory_in(PaymentsCreateRequest = u64)]
|
||||||
/// amount: Option<u64>,
|
/// amount: Option<u64>,
|
||||||
/// #[mandatory_in(PaymentsCreateRequest)]
|
/// #[mandatory_in(PaymentsCreateRequest = String)]
|
||||||
/// currency: Option<String>,
|
/// currency: Option<String>,
|
||||||
/// payment_method: String,
|
/// payment_method: String,
|
||||||
/// }
|
/// }
|
||||||
@ -520,6 +524,17 @@ pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||||||
/// Implements the `Validate` trait to check if the config variable is present
|
/// Implements the `Validate` trait to check if the config variable is present
|
||||||
/// Usage
|
/// Usage
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use router_derive::ConfigValidate;
|
||||||
|
///
|
||||||
|
/// #[derive(ConfigValidate)]
|
||||||
|
/// struct ConnectorParams {
|
||||||
|
/// base_url: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// enum ApplicationError {
|
||||||
|
/// InvalidConfigurationValueError(String),
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// #[derive(ConfigValidate)]
|
/// #[derive(ConfigValidate)]
|
||||||
/// struct Connectors {
|
/// struct Connectors {
|
||||||
/// pub stripe: ConnectorParams,
|
/// pub stripe: ConnectorParams,
|
||||||
@ -529,7 +544,7 @@ pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||||||
///
|
///
|
||||||
/// This will call the `validate()` function for all the fields in the struct
|
/// This will call the `validate()` function for all the fields in the struct
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```rust, ignore
|
||||||
/// impl Connectors {
|
/// impl Connectors {
|
||||||
/// fn validate(&self) -> Result<(), ApplicationError> {
|
/// fn validate(&self) -> Result<(), ApplicationError> {
|
||||||
/// self.stripe.validate()?;
|
/// self.stripe.validate()?;
|
||||||
@ -549,9 +564,26 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
|||||||
/// Generates the function to get the value out of enum variant
|
/// Generates the function to get the value out of enum variant
|
||||||
/// Usage
|
/// Usage
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use router_derive::TryGetEnumVariant;
|
||||||
|
///
|
||||||
|
/// impl std::fmt::Display for RedisError {
|
||||||
|
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
/// match self {
|
||||||
|
/// Self::UnknownResult => write!(f, "Unknown result")
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl std::error::Error for RedisError {}
|
||||||
|
///
|
||||||
|
/// #[derive(Debug)]
|
||||||
|
/// enum RedisError {
|
||||||
|
/// UnknownResult
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// #[derive(TryGetEnumVariant)]
|
/// #[derive(TryGetEnumVariant)]
|
||||||
/// #[error(RedisError(UnknownResult))]
|
/// #[error(RedisError::UnknownResult)]
|
||||||
/// enum Result {
|
/// enum RedisResult {
|
||||||
/// Set(String),
|
/// Set(String),
|
||||||
/// Get(i32)
|
/// Get(i32)
|
||||||
/// }
|
/// }
|
||||||
@ -559,8 +591,8 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
|||||||
///
|
///
|
||||||
/// This will generate the function to get `String` and `i32` out of the variants
|
/// This will generate the function to get `String` and `i32` out of the variants
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```rust, ignore
|
||||||
/// impl Result {
|
/// impl RedisResult {
|
||||||
/// fn try_into_get(&self)-> Result<i32, RedisError> {
|
/// fn try_into_get(&self)-> Result<i32, RedisError> {
|
||||||
/// match self {
|
/// match self {
|
||||||
/// Self::Get(a) => Ok(a),
|
/// Self::Get(a) => Ok(a),
|
||||||
@ -575,6 +607,7 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
/// ```
|
||||||
#[proc_macro_derive(TryGetEnumVariant, attributes(error))]
|
#[proc_macro_derive(TryGetEnumVariant, attributes(error))]
|
||||||
pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||||
|
|||||||
@ -5,6 +5,9 @@ Environment of payment router: logger, basic config, its environment awareness.
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
use router_env::logger;
|
||||||
|
use tracing::{self, instrument};
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub fn sample() -> () {
|
pub fn sample() -> () {
|
||||||
logger::log!(
|
logger::log!(
|
||||||
|
|||||||
@ -152,7 +152,7 @@ where
|
|||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let formatting_layer = router_env::FormattingLayer::new(router_env::service_name!(),std::io::stdout, CompactFormatter);
|
/// let formatting_layer = router_env::FormattingLayer::new("my_service", std::io::stdout, serde_json::ser::CompactFormatter);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
pub fn new(service: &str, dst_writer: W, formatter: F) -> Self {
|
pub fn new(service: &str, dst_writer: W, formatter: F) -> Self {
|
||||||
|
|||||||
Reference in New Issue
Block a user