Skip to content

Commit

Permalink
chore: remove default features
Browse files Browse the repository at this point in the history
  • Loading branch information
itsyaasir committed Nov 8, 2023
1 parent abbfa0d commit 3fe3064
Show file tree
Hide file tree
Showing 10 changed files with 646 additions and 384 deletions.
29 changes: 11 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,25 @@ readme = "./README.md"
license = "MIT"

[dependencies]
chrono = {version = "0.4", optional = true, default-features = false, features = ["clock", "serde"] }
openssl = {version = "0.10", optional = true}
reqwest = {version = "0.11", features = ["json"]}
serde = {version="1.0", features= ["derive"]}
chrono = { version = "0.4", optional = true, default-features = false, features = [
"clock",
"serde",
] }
openssl = { version = "0.10", optional = true }
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_repr = "0.1"
thiserror = "1.0.37"
wiremock = "0.5"


[dev-dependencies]
dotenv = "0.15"
tokio = {version = "1", features = ["rt", "rt-multi-thread", "macros"]}
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
wiremock = "0.5"

[features]
default = [
"account_balance",
"b2b",
"b2c",
"bill_manager",
"c2b_register",
"c2b_simulate",
"express_request",
"transaction_reversal",
"transaction_status"
]
default = ["account_balance", "express_request", "transaction_status"]
account_balance = ["dep:openssl"]
b2b = ["dep:openssl"]
b2c = ["dep:openssl"]
Expand All @@ -44,4 +37,4 @@ c2b_register = []
c2b_simulate = []
express_request = ["dep:chrono"]
transaction_reversal = ["dep:openssl"]
transaction_status= ["dep:openssl"]
transaction_status = ["dep:openssl"]
23 changes: 19 additions & 4 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use crate::environment::ApiEnvironment;
use crate::services::{
AccountBalanceBuilder, B2bBuilder, B2cBuilder, BulkInvoiceBuilder, C2bRegisterBuilder,
C2bSimulateBuilder, CancelInvoiceBuilder, MpesaExpressRequestBuilder, OnboardBuilder,
OnboardModifyBuilder, ReconciliationBuilder, SingleInvoiceBuilder, TransactionReversalBuilder,
TransactionStatusBuilder,
AccountBalanceBuilder, MpesaExpressRequestBuilder, TransactionStatusBuilder,
};
use crate::{ApiError, MpesaError};
use openssl::base64;
Expand All @@ -13,6 +10,24 @@ use reqwest::Client as HttpClient;
use serde_json::Value;
use std::cell::RefCell;

#[cfg(feature = "b2b")]
pub use crate::services::B2bBuilder;
#[cfg(feature = "b2c")]
pub use crate::services::B2cBuilder;
#[cfg(feature = "bill_manager")]
pub use crate::services::{
BulkInvoiceBuilder, CancelInvoiceBuilder, OnboardBuilder, OnboardModifyBuilder,
ReconciliationBuilder, SingleInvoiceBuilder,
};

#[cfg(feature = "c2b_register")]
pub use crate::services::C2bRegisterBuilder;
#[cfg(feature = "c2b_simulate")]
pub use crate::services::C2bSimulateBuilder;

#[cfg(feature = "transaction_reversal")]
pub use crate::services::TransactionReversalBuilder;

/// Source: [test credentials](https://developer.safaricom.co.ke/test_credentials)
const DEFAULT_INITIATOR_PASSWORD: &str = "Safcom496!";
/// Get current package version from metadata
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ pub mod environment;
mod errors;
pub mod services;

#[cfg(test)]
mod test_utils;

pub use client::{Mpesa, MpesaResult};
pub use constants::{
CommandId, IdentifierTypes, Invoice, InvoiceItem, ResponseType, SendRemindersTypes,
Expand Down
141 changes: 141 additions & 0 deletions src/services/express_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,144 @@ impl<'mpesa, Env: ApiEnvironment> MpesaExpressRequestBuilder<'mpesa, Env> {
Err(MpesaError::MpesaExpressRequestError(value))
}
}

#[cfg(test)]
mod tests {
use crate::get_mpesa_client;
use mpesa::MpesaError;
use serde_json::json;
use wiremock::matchers::{method, path};
use wiremock::{Mock, ResponseTemplate};

#[tokio::test]
async fn stk_push_success_success() {
let (client, server) = get_mpesa_client!();
let sample_response_body = json!({
"MerchantRequestID": "16813-1590513-1",
"CheckoutRequestID": "ws_CO_DMZ_12321_23423476",
"ResponseDescription": "Accept the service request successfully.",
"ResponseCode": "0",
"CustomerMessage": "Success. Request accepeted for processing"
});
Mock::given(method("POST"))
.and(path("/mpesa/stkpush/v1/processrequest"))
.respond_with(ResponseTemplate::new(200).set_body_json(sample_response_body))
.expect(1)
.mount(&server)
.await;
let response = client
.express_request("174379")
.phone_number("254708374149")
.amount(500)
.callback_url("https://test.example.com/api")
.send()
.await
.unwrap();
assert_eq!(response.merchant_request_id, "16813-1590513-1");
assert_eq!(response.checkout_request_id, "ws_CO_DMZ_12321_23423476");
assert_eq!(
response.response_description,
"Accept the service request successfully."
);
assert_eq!(
response.customer_message,
"Success. Request accepeted for processing"
);
}

#[tokio::test]
async fn stk_push_fails_if_no_amount_is_provided() {
let (client, server) = get_mpesa_client!(expected_auth_requests = 0);
let sample_response_body = json!({
"MerchantRequestID": "16813-1590513-1",
"CheckoutRequestID": "ws_CO_DMZ_12321_23423476",
"ResponseDescription": "Accept the service request successfully.",
"ResponseCode": "0",
"CustomerMessage": "Success. Request accepeted for processing"
});
Mock::given(method("POST"))
.and(path("/mpesa/stkpush/v1/processrequest"))
.respond_with(ResponseTemplate::new(200).set_body_json(sample_response_body))
.expect(0)
.mount(&server)
.await;
if let Err(e) = client
.express_request("174379")
.phone_number("254708374149")
.callback_url("https://test.example.com/api")
.send()
.await
{
let MpesaError::Message(msg) = e else {
panic!("Expected MpesaError::Message, but found {}", e);
};
assert_eq!(msg, "amount is required")
} else {
panic!("Expected error");
}
}

#[tokio::test]
async fn stk_push_fails_if_no_callback_url_is_provided() {
let (client, server) = get_mpesa_client!(expected_auth_requests = 0);
let sample_response_body = json!({
"MerchantRequestID": "16813-1590513-1",
"CheckoutRequestID": "ws_CO_DMZ_12321_23423476",
"ResponseDescription": "Accept the service request successfully.",
"ResponseCode": "0",
"CustomerMessage": "Success. Request accepeted for processing"
});
Mock::given(method("POST"))
.and(path("/mpesa/stkpush/v1/processrequest"))
.respond_with(ResponseTemplate::new(200).set_body_json(sample_response_body))
.expect(0)
.mount(&server)
.await;
if let Err(e) = client
.express_request("174379")
.phone_number("254708374149")
.amount(500)
.send()
.await
{
let MpesaError::Message(msg) = e else {
panic!("Expected MpesaError::Message, but found {}", e);
};
assert_eq!(msg, "callback_url is required")
} else {
panic!("Expected error");
}
}

#[tokio::test]
async fn stk_push_fails_if_no_phone_number_is_provided() {
let (client, server) = get_mpesa_client!(expected_auth_requests = 0);
let sample_response_body = json!({
"MerchantRequestID": "16813-1590513-1",
"CheckoutRequestID": "ws_CO_DMZ_12321_23423476",
"ResponseDescription": "Accept the service request successfully.",
"ResponseCode": "0",
"CustomerMessage": "Success. Request accepeted for processing"
});
Mock::given(method("POST"))
.and(path("/mpesa/stkpush/v1/processrequest"))
.respond_with(ResponseTemplate::new(200).set_body_json(sample_response_body))
.expect(0)
.mount(&server)
.await;
if let Err(e) = client
.express_request("174379")
.amount(500)
.callback_url("https://test.example.com/api")
.send()
.await
{
let MpesaError::Message(msg) = e else {
panic!("Expected MpesaError::Message, but found {}", e);
};
assert_eq!(msg, "phone_number is required")
} else {
panic!("Expected error");
}
}
}
9 changes: 9 additions & 0 deletions src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@
//! 7. [Transaction Reversal](https://developer.safaricom.co.ke/docs#reversal)
//! 8. [Bill Manager](https://developer.safaricom.co.ke/APIs/BillManager)
#[cfg(feature = "account_balance")]
mod account_balance;
#[cfg(feature = "b2b")]
mod b2b;
#[cfg(feature = "b2c")]
mod b2c;
#[cfg(feature = "bill_manager")]
mod bill_manager;
#[cfg(feature = "c2b_register")]
mod c2b_register;
#[cfg(feature = "c2b_simulate")]
mod c2b_simulate;
#[cfg(feature = "express_request")]
mod express_request;
#[cfg(feature = "transaction_reversal")]
mod transaction_reversal;
#[cfg(feature = "transaction_status")]
mod transaction_status;

#[cfg(feature = "account_balance")]
Expand Down
Loading

0 comments on commit 3fe3064

Please sign in to comment.