ynab-splitwise-connect / tests / test_ynab_utils.py
test_ynab_utils.py
Raw
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()