import os import json import unittest from unittest.mock import MagicMock from ynab_sdk import YNAB from ynab_sdk.api.models.requests.transaction import TransactionRequest from ynab_splitwise_connect.ynab_utils import YNABClient from ynab_sdk.api.models.responses.budget_summary import BudgetSummaryResponse from ynab_sdk.api.models.responses.accounts import AccountsResponse from ynab_sdk.api.models.responses.transactions import TransactionsResponse from ynab_sdk.api.models.responses.payees import PayeesResponse from ynab_sdk.api.models.responses.categories import CategoriesResponse class TestYNABClient(unittest.TestCase): def setUp(self): config = { "api_key": "test_api_key", "budget_name": "Test Budget", "account_name": "Test Account", "expense_account": "Test Expense Account" } self.client = YNABClient(config) self.client.ynab = MagicMock(spec=YNAB) with open("tests/mock_data.json", "r") as f: self.mock_data = json.load(f) def test_budgets(self): budgets_response = BudgetSummaryResponse.from_dict(self.mock_data["budgets_response"]) self.client.ynab.budgets.get_budgets.return_value = budgets_response budgets = self.client.budgets self.assertEqual(budgets, budgets_response.data.budgets) def test_budget_ids(self): # Test that budget_ids property returns a dictionary with the correct budget names and IDs budgets_response = BudgetSummaryResponse.from_dict(self.mock_data["budgets_response"]) self.client.ynab.budgets.get_budgets.return_value = budgets_response budget_ids = self.client.budget_ids expected_budget_ids = {b.name: b.id for b in budgets_response.data.budgets} self.assertEqual(budget_ids, expected_budget_ids) def test_budget_id(self): # Test that budget_id property returns the correct budget ID for the configured budget name budgets_response = BudgetSummaryResponse.from_dict(self.mock_data["budgets_response"]) self.client.ynab.budgets.get_budgets.return_value = budgets_response budget_id = self.client.budget_id expected_budget_id = self.client.budget_ids[self.client.budget] self.assertEqual(budget_id, expected_budget_id) # Similar test functions can be written for accounts, account_ids, account_id, payees, payee_ids, category_groups, categories, and category_ids properties def test_transactions(self): # Test that transactions property returns the correct list of transactions for the configured account transactions_response = TransactionsResponse.from_dict(self.mock_data["transactions_response"]) self.client.ynab.transactions.get_transactions.return_value = transactions_response transactions = self.client.transactions self.assertEqual(transactions, transactions_response.data.transactions) def test_get_payee_id(self): # Test that get_payee_id method returns the correct payee ID for the given payee name payee_name = "Test Payee" payees_response = PayeesResponse.from_dict(self.mock_data["payees_response"]) self.client.ynab.payees.get_payees.return_value = payees_response payee_id = self.client.get_payee_id(payee_name) expected_payee_id = self.client.payee_ids[payee_name] self.assertEqual(payee_id, expected_payee_id) def test_create_transaction(self): # Test that create_transaction method creates a TransactionRequest object with the correct values date = "2023-04-23" amount = 1000 payee_name = "Test Payee" payees_response = PayeesResponse.from_dict(self.mock_data["payees_response"]) self.client.ynab.payees.get_payees.return_value = payees_response payee_id = self.client.get_payee_id(payee_name) memo = "Test Memo" category_id = self.client.category_ids["Some Category"] txn = self.client.create_transaction(date, amount, payee_name, payee_id, memo, category_id) expected_txn = TransactionRequest( account_id=self.client.account_id, date=date, amount=amount, payee_id=payee_id, payee_name=payee_name, memo=memo, category_id=category_id ) self.assertEqual(txn, expected_txn) def test_get_latest_tnx_id(self): # Test that get_latest_tnx_id method returns the ID of the latest transaction in the configured account transactions_response = TransactionsResponse.from_dict(self.mock_data["transactions_response"]) self.client.ynab.transactions.get_transactions.return_value = transactions_response latest_tnx_id = self.client.get_latest_tnx_id() expected_latest_tnx_id = transactions_response.data.transactions[-1].id self.assertEqual(latest_tnx_id, expected_latest_tnx_id) def test_accounts(self): # Test that accounts property returns the correct list of accounts for the configured budget accounts_response = AccountsResponse.from_dict(self.mock_data["accounts_response"]) self.client.ynab.accounts.get_accounts.return_value = accounts_response accounts = self.client.accounts self.assertEqual(accounts, accounts_response.data.accounts) def test_account_ids(self): # Test that account_ids property returns a dictionary with the correct account names and IDs accounts_response = AccountsResponse.from_dict(self.mock_data["accounts_response"]) self.client.ynab.accounts.get_accounts.return_value = accounts_response account_ids = self.client.account_ids expected_account_ids = {a.name: a.id for a in accounts_response.data.accounts} self.assertEqual(account_ids, expected_account_ids) def test_account_id(self): # Test that account_id property returns the correct account ID for the configured account name budgets_response = BudgetSummaryResponse.from_dict(self.mock_data["budgets_response"]) accounts_response = AccountsResponse.from_dict(self.mock_data["accounts_response"]) self.client.ynab.budgets.get_budgets.return_value = budgets_response self.client.ynab.accounts.get_accounts(self.client.budget_id).return_value = accounts_response self.budgets = budgets_response.data.budgets self.client.accounts = accounts_response.data.accounts account_id = self.client.account_id expected_account_id = self.client.account_ids[self.client.account] self.assertEqual(account_id, expected_account_id) def test_payees(self): # Test that payees property returns the correct list of payees for the configured budget payees_response = PayeesResponse.from_dict(self.mock_data["payees_response"]) self.client.ynab.payees.get_payees.return_value = payees_response payees = self.client.payees self.assertEqual(payees, payees_response.data.payees) def test_category_groups(self): # Test that category_groups property returns the correct list of category groups for the configured budget categories_response = CategoriesResponse.from_dict(self.mock_data["categories_response"]) self.client.ynab.categories.get_categories.return_value = categories_response category_groups = self.client.category_groups self.assertEqual(category_groups, categories_response.data.category_groups) def test_categories(self): # Test that categories property returns the correct list of categories for the configured budget categories_response = CategoriesResponse.from_dict(self.mock_data["categories_response"]) self.client.ynab.categories.get_categories.return_value = categories_response categories = self.client.categories expected_categories = [] for group in categories_response.data.category_groups: expected_categories.extend(group.categories) self.assertEqual(categories, expected_categories) if __name__ == '__main__': unittest.main()