Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test cases for balance api #520

Draft
wants to merge 11 commits into
base: release/eleanor-rigby
Choose a base branch
from
249 changes: 178 additions & 71 deletions bundler/Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ actix-service = "2.0.2"
futures = "0.3.28"
jwks-client = "0.2.0"
rs-firebase-admin-sdk = "1.2.1"
mockall = "0.11.4"
tokio = "1.33.0"
54 changes: 54 additions & 0 deletions bundler/src/contracts/usdc_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ abigen!(ERC20, "abi/ERC20.json");
#[derive(Clone)]
pub struct USDCProvider;

#[mockall::automock]
impl USDCProvider {
pub fn init_abi(address: Address, client: Arc<Provider<Http>>) -> ERC20<Provider<Http>> {
let contract: ERC20<Provider<Http>> = ERC20::new(address, client);
Expand Down Expand Up @@ -57,3 +58,56 @@ impl USDCProvider {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

use crate::provider::web3_client::tests::setup_mock_client;
use crate::provider::web3_provider::tests::setup_mock_provider;

#[tokio::test]
async fn test_init_abi() {
let provider = setup_mock_provider();
let mock_init = MockUSDCProvider::init_abi_context();

mock_init.expect().returning(|address, client| {
let contract: ERC20<Provider<Http>> = ERC20::new(address, client);
return contract;
});

let abi = MockUSDCProvider::init_abi(Address::zero(), Arc::new(provider.clone()));

assert_eq!(
abi.address(),
ERC20::new(Address::zero(), Arc::new(provider)).address()
)
}

#[tokio::test]
async fn test_balance_of_success() {
let web3_client = setup_mock_client();

let mock_balance = MockUSDCProvider::balance_of_context();
mock_balance.expect().returning(|_, _| Ok(U256::zero()));

let result = MockUSDCProvider::balance_of(&web3_client, Address::zero()).await;

assert!(result.is_ok());
assert_eq!(result.unwrap(), U256::zero());
}

#[tokio::test]
async fn test_balance_of_failure() {
let web3_client = setup_mock_client();

let mock_balance = MockUSDCProvider::balance_of_context();
mock_balance
.expect()
.returning(|_, _| Err(ProviderError("failed to get balance".to_string())));

let result = MockUSDCProvider::balance_of(&web3_client, Address::zero()).await;

assert!(result.is_err());
}
}
38 changes: 34 additions & 4 deletions bundler/src/db/connection.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use log::warn;
use sqlx::{PgPool, Postgres};
use sqlx::{Error, PgPool, Pool, Postgres};
use std::process::exit;

pub struct DatabaseConnection;

#[mockall::automock]
impl DatabaseConnection {
pub async fn init() -> sqlx::Pool<Postgres> {
pub async fn init() -> Result<Pool<Postgres>, Error> {
let database_url: String;
match std::env::var("DATABASE_URL") {
Ok(url) => database_url = url,
Expand All @@ -14,7 +15,36 @@ impl DatabaseConnection {
exit(1)
}
}
let connection = PgPool::connect(&database_url).await;
connection.unwrap()
PgPool::connect(&database_url).await
}
}

#[cfg(test)]
mod tests {
use super::*;
use sqlx::{Pool, Postgres};

#[sqlx::test]
async fn test_init_success(pool: Pool<Postgres>) {
let mock_pool = MockDatabaseConnection::init_context();

mock_pool.expect().returning(move || Ok(pool.clone()));

let result = MockDatabaseConnection::init().await;

assert!(result.is_ok());
mock_pool.checkpoint();
}

#[tokio::test]
async fn test_init_failure() {
let mock_pool = MockDatabaseConnection::init_context();

mock_pool.expect().returning(|| Err(Error::PoolClosed));

let result = MockDatabaseConnection::init().await;

assert!(result.is_err());
mock_pool.checkpoint();
}
}
50 changes: 50 additions & 0 deletions bundler/src/db/dao/token_metadata_dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::errors::DatabaseError;
#[derive(Clone)]
pub struct TokenMetadataDao;

#[mockall::automock]
impl TokenMetadataDao {
pub async fn add_metadata(
pool: &Pool<Postgres>,
Expand Down Expand Up @@ -111,3 +112,52 @@ pub struct TokenMetadata {
pub chain_name: Option<String>,
pub token_image_url: Option<String>,
}

#[cfg(test)]
mod test {
use super::*;
use sqlx::{Pool, Postgres};

#[sqlx::test]
async fn test_get_metadata_for_chain_no_records(pool: Pool<Postgres>) {
let context = MockTokenMetadataDao::get_metadata_for_chain_context();

context.expect().returning(|_, _, _| Ok(vec![]));

let result =
MockTokenMetadataDao::get_metadata_for_chain(&pool, String::from("chain"), None).await;

assert!(result.is_ok());
}

#[sqlx::test]
async fn test_get_metadata_for_chain_one_record(pool: Pool<Postgres>) {
let context = MockTokenMetadataDao::get_metadata_for_chain_context();

context
.expect()
.returning(|_, _, _| Ok(vec![TokenMetadata::default()]));

let result =
MockTokenMetadataDao::get_metadata_for_chain(&pool, String::from("chain"), None).await;

assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 1);
}

#[sqlx::test]
async fn test_get_metadata_for_chain_failure(pool: Pool<Postgres>) {
let context = MockTokenMetadataDao::get_metadata_for_chain_context();

context.expect().returning(|_, _, _| {
Err(DatabaseError::ServerError(String::from(
"Failed to get currencies",
)))
});

let result =
MockTokenMetadataDao::get_metadata_for_chain(&pool, String::from("chain"), None).await;

assert!(result.is_err());
}
}
2 changes: 1 addition & 1 deletion bundler/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod services;

lazy_static! {
static ref CONFIG: Settings = Settings::new().expect("Failed to load config.");
static ref PROVIDER: Provider<Http> = Web3Provider::new(CONFIG.get_chain().get_url());
static ref PROVIDER: Provider<Http> = Web3Provider::init_provider(CONFIG.get_chain().get_url());
}

#[actix_web::main]
Expand Down
59 changes: 57 additions & 2 deletions bundler/src/provider/web3_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ pub struct Web3Client {
pub client: Arc<Provider<Http>>,
}

#[mockall::automock]
impl Web3Client {
pub fn new(client: Arc<Provider<Http>>) -> Self {
Self { client }
pub fn init_client(client: Arc<Provider<Http>>) -> Web3Client {
Web3Client { client }
}

pub fn get_usdc_provider(&self) -> ERC20<Provider<Http>> {
Expand Down Expand Up @@ -79,3 +80,57 @@ impl Web3Client {
.unwrap()
}
}

#[cfg(test)]
pub mod tests {
use super::*;

use crate::provider::web3_provider::tests::setup_mock_provider;

pub fn setup_mock_client() -> Web3Client {
let provider = setup_mock_provider();
let mock_client = MockWeb3Client::init_client_context();
mock_client
.expect()
.returning(|client| Web3Client { client });

MockWeb3Client::init_client(Arc::new(provider.clone()))
}

#[tokio::test]
async fn test_new_client() {
let provider = setup_mock_provider();

let mock_client = MockWeb3Client::init_client_context();
mock_client
.expect()
.returning(|client| Web3Client { client });

let web3_client = MockWeb3Client::init_client(Arc::new(provider.clone()));

assert_eq!(
web3_client.client.url(),
Web3Client {
client: Arc::new(provider)
}
.client
.url()
)
}

#[tokio::test]
async fn test_usdc_provider() {
let provider = setup_mock_provider();

let mut client = MockWeb3Client::new();
let abi = USDCProvider::init_abi(Address::zero(), Arc::new(provider.clone()));

client
.expect_get_usdc_provider()
.returning(move || USDCProvider::init_abi(Address::zero(), Arc::new(provider.clone())));

let usdc_provider = client.get_usdc_provider();

assert_eq!(usdc_provider.address(), abi.address())
}
}
31 changes: 30 additions & 1 deletion bundler/src/provider/web3_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ use crate::PROVIDER;
#[derive(Clone)]
pub struct Web3Provider {}

#[mockall::automock]
impl Web3Provider {
pub fn new(chain_url: String) -> Provider<Http> {
pub fn init_provider(chain_url: String) -> Provider<Http> {
let provider = Provider::try_from(chain_url).unwrap();
provider
}
Expand Down Expand Up @@ -160,3 +161,31 @@ impl Web3Provider {
};
}
}

#[cfg(test)]
pub mod tests {
use super::*;

pub fn setup_mock_provider() -> Provider<Http> {
let mock_provider = MockWeb3Provider::init_provider_context();
mock_provider.expect().returning(|chain| {
let provider: Provider<Http> = Provider::try_from(chain).unwrap();
return provider;
});
MockWeb3Provider::init_provider("http://localhost:8545".to_string())
}
#[tokio::test]
async fn test_new_provider() {
let mock_provider = MockWeb3Provider::init_provider_context();
mock_provider.expect().returning(|chain| {
let provider: Provider<Http> = Provider::try_from(chain).unwrap();
return provider;
});

let provider = MockWeb3Provider::init_provider("http://localhost:8545".to_string());
assert_eq!(
provider.url(),
Provider::try_from("http://localhost:8545").unwrap().url()
)
}
}
4 changes: 2 additions & 2 deletions bundler/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ pub async fn init_services() -> ToadService {

ToadService {
hello_world_service: HelloWorldService {},
web3_client: Web3Client::new(client.clone()),
db_pool: DatabaseConnection::init().await,
web3_client: Web3Client::init_client(client.clone()),
db_pool: DatabaseConnection::init().await.unwrap(),
}
}

Expand Down
34 changes: 34 additions & 0 deletions bundler/src/services/balance_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::PROVIDER;
#[derive(Clone)]
pub struct BalanceService;

#[mockall::automock]
impl BalanceService {
pub async fn get_wallet_balance(
pool: &Pool<Postgres>,
Expand Down Expand Up @@ -60,3 +61,36 @@ impl BalanceService {
})
}
}

#[cfg(test)]
mod tests {
use super::*;

use crate::provider::web3_client::tests::setup_mock_client;

#[sqlx::test]
async fn test_get_balance_usdc(pool: Pool<Postgres>) {
let web3_client = setup_mock_client();

let mock_balance = MockBalanceService::get_wallet_balance_context();
mock_balance.expect().returning(|_, _, _, currency, user| {
Ok(BalanceResponse::new(
"0".to_string(),
user.wallet_address,
currency.clone(),
18,
))
});

let balance_result = MockBalanceService::get_wallet_balance(
&pool,
&web3_client,
&"chain".to_string(),
&"usdc".to_string(),
User::default(),
)
.await;

assert!(balance_result.is_ok());
}
}
Loading