diff options
| author | Joe Carstairs <me@joeac.net> | 2024-11-21 21:21:03 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2024-11-21 21:21:03 +0000 |
| commit | 6174d31572fb4d6582029a6ec2ea4391d704a7cb (patch) | |
| tree | 4369e7958bc15de7c947a8507f968f752241087f /rust/actualbudget_queries/tests/common | |
| parent | 4967cbabfc2fddc903dfaa17b11b2baa006fb218 (diff) | |
Wicked cool actualbudget transaction integration testing
Diffstat (limited to 'rust/actualbudget_queries/tests/common')
6 files changed, 411 insertions, 0 deletions
diff --git a/rust/actualbudget_queries/tests/common/account_names.rs b/rust/actualbudget_queries/tests/common/account_names.rs new file mode 100644 index 0000000..1abee4b --- /dev/null +++ b/rust/actualbudget_queries/tests/common/account_names.rs @@ -0,0 +1,17 @@ +pub const ACCOUNT_NAMES: &[&'static str] = &[ + "My bank account", + "My cash account", + "Category transfers", +]; + +pub struct AccountNamesDict { + pub bank_account: &'static str, + pub cash_account: &'static str, + pub transfers_account: &'static str, +} + +pub const ACCOUNT_NAMES_DICT: AccountNamesDict = AccountNamesDict { + bank_account: ACCOUNT_NAMES[0], + cash_account: ACCOUNT_NAMES[1], + transfers_account: ACCOUNT_NAMES[2], +}; diff --git a/rust/actualbudget_queries/tests/common/category_names.rs b/rust/actualbudget_queries/tests/common/category_names.rs new file mode 100644 index 0000000..a2f7d84 --- /dev/null +++ b/rust/actualbudget_queries/tests/common/category_names.rs @@ -0,0 +1,29 @@ +pub const CATEGORY_NAMES: &[&'static str] = &[ + "Food", + "General", + "Bills", + "Bills (Flexible)", + "Savings", + "Starting Balances", + "Income", +]; + +pub struct CategoryNamesDict { + pub food: &'static str, + pub general: &'static str, + pub bills: &'static str, + pub bills_flexible: &'static str, + pub savings: &'static str, + pub starting_balances: &'static str, + pub income: &'static str, +} + +pub const CATEGORY_NAMES_DICT: CategoryNamesDict = CategoryNamesDict { + food: CATEGORY_NAMES[0], + general: CATEGORY_NAMES[1], + bills: CATEGORY_NAMES[2], + bills_flexible: CATEGORY_NAMES[3], + savings: CATEGORY_NAMES[4], + starting_balances: CATEGORY_NAMES[5], + income: CATEGORY_NAMES[6], +}; diff --git a/rust/actualbudget_queries/tests/common/db_url.rs b/rust/actualbudget_queries/tests/common/db_url.rs new file mode 100644 index 0000000..ff778a8 --- /dev/null +++ b/rust/actualbudget_queries/tests/common/db_url.rs @@ -0,0 +1 @@ +pub const DB_URL: &str = "tests/resources/actualbudget_test_db.sqlite"; diff --git a/rust/actualbudget_queries/tests/common/get_reference_data.rs b/rust/actualbudget_queries/tests/common/get_reference_data.rs new file mode 100644 index 0000000..d317a00 --- /dev/null +++ b/rust/actualbudget_queries/tests/common/get_reference_data.rs @@ -0,0 +1,45 @@ +use std::collections::HashMap; + +use actualbudget_models::{actualbudget_account::ActualbudgetAccount, actualbudget_category::ActualbudgetCategory}; +use actualbudget_queries::{actualbudget_accounts::get_all_actualbudget_accounts, actualbudget_categories::get_all_actualbudget_categories, actualbudget_transactions::{get_all_actualbudget_transactions, get_first_actualbudget_transaction_date}}; +use diesel::SqliteConnection; + +use super::{account_names::ACCOUNT_NAMES, category_names::CATEGORY_NAMES}; + +pub fn get_accounts(connection: &mut SqliteConnection) -> HashMap<String, ActualbudgetAccount> { + let accounts = get_all_actualbudget_accounts(connection).expect("failed to get accounts"); + let mut accounts_hash_map = HashMap::new(); + + for &account_name in ACCOUNT_NAMES { + let account = accounts + .clone() + .into_iter() + .find(|a| a.name.as_str() == account_name) + .expect(&format!("failed to get account: {}", account_name)); + accounts_hash_map.insert( + String::from(account_name), + account, + ); + } + + accounts_hash_map +} + +pub fn get_categories(connection: &mut SqliteConnection) -> HashMap<String, ActualbudgetCategory> { + let categories = get_all_actualbudget_categories(connection).expect("failed to get categories"); + let mut categories_hash_map = HashMap::new(); + + for &category_name in CATEGORY_NAMES { + let category = categories + .clone() + .into_iter() + .find(|a| a.name.as_str() == category_name) + .expect(&format!("failed to get category: {}", category_name)); + categories_hash_map.insert( + String::from(category_name), + category, + ); + } + + categories_hash_map +} diff --git a/rust/actualbudget_queries/tests/common/mod.rs b/rust/actualbudget_queries/tests/common/mod.rs new file mode 100644 index 0000000..01112b3 --- /dev/null +++ b/rust/actualbudget_queries/tests/common/mod.rs @@ -0,0 +1,5 @@ +pub mod account_names; +pub mod category_names; +pub mod db_url; +pub mod get_reference_data; +pub mod transaction_matchers; diff --git a/rust/actualbudget_queries/tests/common/transaction_matchers.rs b/rust/actualbudget_queries/tests/common/transaction_matchers.rs new file mode 100644 index 0000000..f245723 --- /dev/null +++ b/rust/actualbudget_queries/tests/common/transaction_matchers.rs @@ -0,0 +1,314 @@ +use std::collections::HashMap; + +use actualbudget_models::{actualbudget_account::ActualbudgetAccount, actualbudget_category::ActualbudgetCategory, actualbudget_transaction::ActualbudgetTransaction}; + +use super::{account_names::ACCOUNT_NAMES_DICT, category_names::CATEGORY_NAMES_DICT}; + +pub fn get_transaction_matchers() -> Vec<Box<dyn Fn(&ActualbudgetTransaction, &HashMap<String, ActualbudgetAccount>, &HashMap<String, ActualbudgetCategory>) -> bool>> { + vec![ + Box::new(|t, a, c| matches_bank_account_initial_transaction(t, a, c)), + Box::new(|t, a, c| matches_cash_account_initial_transaction(t, a, c)), + Box::new(|t, a, c| matches_income_transaction(t, a, c, "08")), + Box::new(|t, a, c| matches_income_transaction(t, a, c, "09")), + Box::new(|t, a, c| matches_income_transaction(t, a, c, "10")), + Box::new(|t, a, c| matches_income_transaction(t, a, c, "11")), + Box::new(|t, a, c| matches_food_transaction(t, a, c, "08")), + Box::new(|t, a, c| matches_food_transaction(t, a, c, "09")), + Box::new(|t, a, c| matches_food_transaction(t, a, c, "10")), + Box::new(|t, a, c| matches_food_transaction(t, a, c, "11")), + Box::new(|t, a, c| matches_category_transfer_parent_transaction(t, a, c)), + Box::new(|t, a, c| matches_category_transfer_child_out_transaction(t, a, c)), + Box::new(|t, a, c| matches_category_transfer_child_in_transaction(t, a, c)), + Box::new(|t, a, c| matches_account_transfer_out_transaction(t, a, c)), + Box::new(|t, a, c| matches_account_transfer_in_transaction(t, a, c)), + ] +} + +fn matches_bank_account_initial_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let bank_account_id = accounts + .get(ACCOUNT_NAMES_DICT.bank_account) + .expect("failed to find bank account") + .id + .clone(); + + let starting_balances_category_id = categories + .get(CATEGORY_NAMES_DICT.starting_balances) + .expect("failed to find starting balances category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id: Some(category_id), + amount: 1200_00, + date, + .. + } => *account_id == bank_account_id + && *category_id == starting_balances_category_id + && date.to_iso() == "2024-08-01", + _ => false, + } +} + +fn matches_cash_account_initial_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let bank_account_id = accounts + .get(ACCOUNT_NAMES_DICT.cash_account) + .expect("failed to find cash account") + .id + .clone(); + + let starting_balances_category_id = categories + .get(CATEGORY_NAMES_DICT.starting_balances) + .expect("failed to find starting balances category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id: Some(category_id), + amount: 45_10, + date, + .. + } => *account_id == bank_account_id + && *category_id == starting_balances_category_id + && date.to_iso() == "2024-08-01", + _ => false, + } +} + +fn matches_income_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, + month: &str, +) -> bool { + let bank_account_id = accounts + .get(ACCOUNT_NAMES_DICT.bank_account) + .expect("failed to find bank account") + .id + .clone(); + + let income_category_id = categories + .get(CATEGORY_NAMES_DICT.income) + .expect("failed to find income category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id, + amount: 846_46, + date, + notes: Some(notes), + .. + } => *account_id == bank_account_id + && *category_id == Some(income_category_id) + && date.to_iso() == format!("2024-{}-21", month) + && *notes == String::from("Salary"), + _ => false, + } +} + +fn matches_food_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, + month: &str, +) -> bool { + let bank_account_id = accounts + .get(ACCOUNT_NAMES_DICT.bank_account) + .expect("failed to find bank account") + .id + .clone(); + + let income_category_id = categories + .get(CATEGORY_NAMES_DICT.food) + .expect("failed to find food category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id, + amount: -200_00, + date, + .. + } => *account_id == bank_account_id + && *category_id == Some(income_category_id) + && date.to_iso() == format!("2024-{}-08", month), + _ => false, + } +} + +fn matches_category_transfer_parent_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + _categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let category_transfers_account_id = accounts + .get(ACCOUNT_NAMES_DICT.transfers_account) + .expect("failed to find transfers account") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: true, + is_child: false, + parent_id: None, + account_id, + category_id: None, + amount: 0, + date, + .. + } => *account_id == category_transfers_account_id + && date.to_iso() == "2024-10-23", + _ => false, + } +} + +fn matches_category_transfer_child_out_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let category_transfers_account_id = accounts + .get(ACCOUNT_NAMES_DICT.transfers_account) + .expect("failed to find transfers account") + .id + .clone(); + + let savings_category_id = categories + .get(CATEGORY_NAMES_DICT.savings) + .expect("failed to find savings category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: true, + parent_id: Some(_), + account_id, + category_id: Some(category_id), + amount: -120_00, + date, + .. + } => *account_id == category_transfers_account_id + && *category_id == savings_category_id + && date.to_iso() == "2024-10-23", + _ => false, + } +} + +fn matches_category_transfer_child_in_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let category_transfers_account_id = accounts + .get(ACCOUNT_NAMES_DICT.transfers_account) + .expect("failed to find transfers account") + .id + .clone(); + + let savings_category_id = categories + .get(CATEGORY_NAMES_DICT.general) + .expect("failed to find general category") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: true, + parent_id: Some(_), + account_id, + category_id: Some(category_id), + amount: 120_00, + date, + .. + } => *account_id == category_transfers_account_id + && *category_id == savings_category_id + && date.to_iso() == "2024-10-23", + _ => false, + } +} + +fn matches_account_transfer_out_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let bank_account_id = accounts + .get(ACCOUNT_NAMES_DICT.bank_account) + .expect("failed to find bank account") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id: None, + amount: -80_00, + date, + .. + } => *account_id == bank_account_id + && date.to_iso() == "2024-09-10", + _ => false, + } +} + +fn matches_account_transfer_in_transaction( + t: &ActualbudgetTransaction, + accounts: &HashMap<String, ActualbudgetAccount>, + categories: &HashMap<String, ActualbudgetCategory>, +) -> bool { + let cash_account_id = accounts + .get(ACCOUNT_NAMES_DICT.cash_account) + .expect("failed to find cash account") + .id + .clone(); + + match t { + ActualbudgetTransaction { + is_parent: false, + is_child: false, + parent_id: None, + account_id, + category_id: None, + amount: 80_00, + date, + .. + } => *account_id == cash_account_id + && date.to_iso() == "2024-09-10", + _ => false, + } +} |
