finance-watcher / test / database / test_finance_database.py
test_finance_database.py
Raw
from database.database_classes import (
    AccountType, Account, Business, BusinessType, Transaction, User, Budget
)
from finance_watcher_dataclasses.enums import AccountTypeEnum, BusinessTypeEnum
from database.finance_database import FinanceDatabase
from unittest.mock import Mock, patch
from test.test_objects import *
from typing import List
from finance_watcher_dataclasses.import_dataclasses import AccountRow


def create_mock_database() -> Mock:
    mock_database = Mock()
    mock_config = create_mock_config()
    mock_database.config = mock_config
    return mock_database


def create_mock_config() -> Mock:
    mock_config = Mock()
    mock_config.host = 'MOCK_HOST'
    mock_config.port = '1234'
    mock_config.database = 'MOCK_DATABASE'
    mock_config.user = 'MOCK_USER'
    mock_config.password = 'MOCK_PASSWORD'
    return mock_config


test_database = FinanceDatabase(create_mock_config())

class TestFinanceDatabase:
    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_ensure_account_type(self, mock_run_query):

        mock_run_query.return_value = []
        return_value = test_database.ensure_account_type(
            AccountTypeEnum.BALANCE
        )
        assert return_value == None
        
        account_type = create_mock_account_type(name='Balance')
        mock_run_query.return_value = [
            [1, 'Balance', True, False]
        ]
        return_value = test_database.ensure_account_type(
            AccountTypeEnum.BALANCE
        )
        assert isinstance(return_value, AccountType)
        assert return_value.id == account_type.id
        assert return_value.name == account_type.name
        assert return_value.is_income == account_type.is_income
        assert return_value.is_expense == account_type.is_expense

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_ensure_business(self, mock_run_query):

        test_name = 'TestBusiness'
        test_id = 1

        mock_run_query.return_value = []
        return_value = test_database.ensure_business(
            test_name, test_id
        )
        assert return_value == None
        
        mock_business = create_mock_business(
            name=test_name, business_type_id=test_id
        )
        mock_run_query.return_value = [
            [1, 'TestBusiness', 1]
        ]
        return_value = test_database.ensure_business(
            test_name, test_id
        )
        assert isinstance(return_value, Business)
        assert return_value.id == mock_business.id
        assert return_value.name == mock_business.name
        assert return_value.business_type_id == mock_business.business_type_id

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_business_type(self, mock_run_query):

        mock_run_query.return_value = []
        return_value = test_database.get_business_type(
            BusinessTypeEnum.AUTO
        )
        assert return_value == None
        
        account_type = create_mock_business_type(name='AUTO')
        mock_run_query.return_value = [
            [1, 'AUTO']
        ]
        return_value = test_database.get_business_type(
            BusinessTypeEnum.AUTO
        )
        assert isinstance(return_value, BusinessType)
        assert return_value.id == account_type.id
        assert return_value.name == account_type.name

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_dashboard_user(self, mock_run_query):

        test_id = 12345

        mock_run_query.return_value = []
        return_value = test_database.get_dashboard_user(test_id)
        assert return_value == None
        
        account_type = create_mock_user(id=test_id)
        mock_run_query.return_value = [
            [12345, 'name', datetime.now().date()]
        ]
        return_value = test_database.get_dashboard_user(test_id)
        assert isinstance(return_value, User)
        assert return_value.id == account_type.id
        assert return_value.name == account_type.name
        assert return_value.created_date == account_type.created_date

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_update_user_password(self, mock_run_query):

        test_id = 12345
        test_pass = 'stupidPass'

        mock_run_query.return_value = []
        return_value = test_database.update_user_password(test_id, test_pass)
        assert return_value == False
        
        mock_run_query.return_value = [
            [test_id]
        ]
        return_value = test_database.update_user_password(test_id, test_pass)
        assert return_value == True

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_transactions(self, mock_run_query):
        date_init = datetime(1990, 10, 1)
        date_later = datetime(2010, 5, 1)
        test_id = 12345

        # test expected None from parameters
        return_value = test_database.get_transactions(
            test_id, start_date=date_init
        )
        assert return_value == None

        return_value = test_database.get_transactions(
            test_id, end_date=date_init
        )
        assert return_value == None

        return_value = test_database.get_transactions(
            test_id, start_date=date_later, end_date=date_init
        )
        assert return_value == None


        test_transactions = [
            create_mock_transaction(i)
            for i in range(5)
        ]

        mock_run_query.return_value = []
        return_value = test_database.get_transactions(test_id)
        assert return_value == []
        
        mock_run_query.return_value = [
            [
                t.id,
                t.dashboard_user_id,
                t.amount,
                t.business_id,
                t.is_expense,
                t.created_date
            ] for t in test_transactions
        ]
        return_value = test_database.get_transactions(test_id)
        assert isinstance(return_value, List)
        assert isinstance(return_value[0], Transaction)
        assert len(return_value) == 5
    

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_account_type(self, mock_run_query):

        mock_run_query.return_value = []
        return_value = test_database.get_account_type(
            AccountTypeEnum.BALANCE
        )
        assert return_value == None
        
        account_type = create_mock_account_type(name='BALANCE')
        mock_run_query.return_value = [
            [1, 'BALANCE', True, True]
        ]
        return_value = test_database.get_account_type(
            AccountTypeEnum.BALANCE
        )
        assert isinstance(return_value, AccountType)
        assert return_value.id == account_type.id

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_ensure_account(self, mock_run_query):

        test_name = 'name'
        test_type_id = 4
        test_user_id = 1

        mock_run_query.return_value = []
        return_value = test_database.ensure_account(
            test_name, test_type_id, test_user_id
        )
        assert return_value == None
        
        account = create_mock_account(
            name='name', account_type_id=4, dashboard_user_id=1
        )
        mock_run_query.return_value = [
            [1, 'name', 4, datetime.now().date(), None, 1]
        ]
        return_value = test_database.ensure_account(
            test_name, test_type_id, test_user_id
        )
        assert isinstance(return_value, Account)
        assert return_value.id == account.id
        assert return_value.dashboard_user_id == account.dashboard_user_id
        assert return_value.name == account.name
        assert return_value.account_type_id == account.account_type_id
        assert return_value.created_date == account.created_date
        assert return_value.updated_date == account.updated_date

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_insert_dashboard_user(self, mock_run_query):
        test_name = 'TestName'
        test_email = 'abc@defg.com'
        test_pass = 'badPassword'

        mock_user = create_mock_user(name=test_name, email=test_email)

        mock_run_query.return_value = []
        return_value = test_database.insert_dashboard_user(
            test_name, test_email, test_pass
        )
        assert return_value == None

        mock_run_query.return_value = [
            [1, 'TestName', datetime.now().date(), None]
        ]
        return_value = test_database.insert_dashboard_user(
            test_name, test_email, test_pass
        )
        assert isinstance(return_value, User)
        assert return_value.id == mock_user.id
        assert return_value.name == mock_user.name
        assert return_value.created_date == mock_user.created_date
        assert return_value.updated_date == mock_user.updated_date

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_insert_account_totals(self, mock_run_query):

        return_value = test_database.insert_account_totals([])
        assert return_value == True

        account_rows = [
            AccountRow(account_id=1, date_to_amount={
                datetime.now().date(): 10.0
            })
        ]

        mock_run_query.return_value = []
        return_value = test_database.insert_account_totals(account_rows)
        assert return_value == False

        mock_run_query.return_value = [
            [1, 10.0, datetime.now().date()]
        ]
        return_value = test_database.insert_account_totals(account_rows)
        assert return_value == True


    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_all_accounts_and_latest_totals(self, mock_run_query):
        test_id = 12345

        mock_run_query.return_value = []
        return_value = test_database.get_all_accounts_and_latest_totals(test_id)
        assert return_value == {}

        mock_run_query.return_value = [
            ['testName', 1, 2000], ['testNameTwo', 4, 12500]
        ]
        return_value = test_database.get_all_accounts_and_latest_totals(test_id)
        assert return_value == {
            1: ('testName', 2000),
            4: ('testNameTwo', 12500)
        }

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_latest_account_percentages(self, mock_run_query):
        test_id = 12345

        mock_run_query.return_value = []
        return_value = test_database.get_latest_account_percentages(
            test_id
        )
        assert return_value == {}

        mock_run_query.return_value = [
            ['testName', 1, 2000], ['testNameTwo', 4, 12500]
        ]
        return_value = test_database.get_latest_account_percentages(
            test_id
        )
        assert return_value == {
            'testName': 0.13793103448275862,
            'testNameTwo': 0.8620689655172413
        }

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_insert_account(self, mock_run_query):
        mock_run_query.return_value = []
        return_value = test_database.insert_account('AccountName', 3, 2)
        assert return_value == None

        mock_account = create_mock_account()

        mock_run_query.return_value = [
            [1, 'AccountName', 3, datetime.now().date(), None, 2]
        ]
        return_value = test_database.insert_account('AccountName', 3, 2)
        assert isinstance(return_value, Account)
        assert return_value.id == mock_account.id
        assert return_value.name == mock_account.name
        assert return_value.account_type_id == mock_account.account_type_id
        assert return_value.created_date == mock_account.created_date
        assert return_value.dashboard_user_id == mock_account.dashboard_user_id

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_insert_businesses(self, mock_run_query):
        mock_business = create_mock_business(name='testName', business_type_id=1)
        mock_business2 = create_mock_business(id=12345,name='testName2', business_type_id=4)

        mock_run_query.return_value = []
        return_value = test_database.insert_business('testName', 1)
        assert return_value == None

        mock_run_query.return_value = [
            [1, 'testName',1]
        ]
        return_value = test_database.insert_business('testName', 1)
        assert isinstance(return_value, Business)
        assert return_value.id == mock_business.id
        assert return_value.name == mock_business.name
        assert return_value.business_type_id == mock_business.business_type_id

        names_business = {
            'testName': 1,
            'testName2': 4
        }
        mock_run_query.return_value = []
        return_value = test_database.insert_businesses(names_business)
        assert return_value == None

        mock_run_query.return_value = [
            [1, 'testName',1],
            [12345, 'testName2',4],
        ]
        return_value = test_database.insert_businesses(names_business)
        assert isinstance(return_value, List)
        assert isinstance(return_value[0], Business)
        assert return_value[0].id == mock_business.id
        assert return_value[0].name == mock_business.name
        assert return_value[0].business_type_id == mock_business.business_type_id

        assert return_value[1].id == mock_business2.id
        assert return_value[1].name == mock_business2.name
        assert return_value[1].business_type_id == mock_business2.business_type_id
    
    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_insert_transactions(self, mock_run_query):

        mock_run_query.return_value = []
        return_value = test_database.insert_transaction(500, 2, True)
        assert return_value == False

        mock_run_query.return_value = [1]
        return_value = test_database.insert_transaction(500, 2, True)
        assert return_value == True

        mock_run_query.return_value = []
        mock_transactions = [create_mock_transaction() for _ in range(6)]
        return_value = test_database.insert_transactions(mock_transactions)
        assert return_value == False

        mock_run_query.return_value = [1,2,3,4,5,6]
        mock_transactions = [create_mock_transaction() for _ in range(6)]
        return_value = test_database.insert_transactions(mock_transactions)
        assert return_value == True


    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_check_account_connection(self, mock_run_query):
        test_user_id = 12345
        account_ids = [i for i in range(5)]

        mock_run_query.return_value = []
        return_value = test_database.check_account_connection(
            test_user_id, account_ids
        )
        assert return_value == False

        mock_run_query.return_value = [1,2,3]
        return_value = test_database.check_account_connection(
            test_user_id, account_ids
        )
        assert return_value == False

        mock_run_query.return_value = [1,2,3,4,5]
        return_value = test_database.check_account_connection(
            test_user_id, account_ids
        )
        assert return_value == True


    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_budgets(self, mock_run_query):
        test_user_id = 12345

        mock_budget = create_mock_budget()

        mock_run_query.return_value = None
        return_value = test_database.get_budgets(test_user_id)
        assert return_value == None

        mock_run_query.return_value = []
        return_value = test_database.get_budgets(test_user_id)
        assert return_value == []

        mock_run_query.return_value = [
            [1,'TestBudget', 2000, 2, 3, datetime.now().date()]
        ]
        return_value = test_database.get_budgets(test_user_id)
        assert isinstance(return_value, List)
        assert isinstance(return_value[0], Budget)
        assert len(return_value) == 1
        assert return_value[0].id == mock_budget.id
        assert return_value[0].name == mock_budget.name
        assert return_value[0].amount == mock_budget.amount
        assert return_value[0].dashboard_user_id == mock_budget.dashboard_user_id
        assert return_value[0].business_type_id == mock_budget.business_type_id
        assert return_value[0].created_date == mock_budget.created_date


    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_create_budget(self, mock_run_query):
        test_user_id = 12345
        test_name = 'stupidName'
        test_amount = 2094
        test_business_type_id = 123

        mock_budget = create_mock_budget(
            1, test_name, test_amount, test_user_id, test_business_type_id
        )

        mock_run_query.return_value = []
        return_value = test_database.create_budget(
            test_user_id, test_name, test_amount, test_business_type_id
        )
        assert return_value == None

        
        mock_run_query.return_value = [
            [1, 'stupidName', 2094, 12345, 123, datetime.now().date()]
        ]
        return_value = test_database.create_budget(
            test_user_id, test_name, test_amount, test_business_type_id
        )
        assert isinstance(return_value, Budget)
        assert return_value.id == mock_budget.id
        assert return_value.name == mock_budget.name
        assert return_value.amount == mock_budget.amount
        assert return_value.business_type_id == mock_budget.business_type_id
        assert return_value.created_date == mock_budget.created_date


    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_update_budget(self, mock_run_query):
        test_budget_id = 12345
        test_name = 'stupidName'

        return_value = test_database.update_budget(test_budget_id)
        assert return_value == True
        mock_run_query.assert_not_called()

        
        mock_run_query.return_value = None
        return_value = test_database.update_budget(test_budget_id, test_name)
        assert return_value == False

        mock_run_query.return_value = [
            [test_budget_id]
        ]
        return_value = test_database.update_budget(test_budget_id, test_name)
        assert return_value == True

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_delete_budget(self, mock_run_query):
        test_id = 12345
        test_name = 'stupidName'

        mock_run_query.return_value = None
        return_value = test_database.delete_budget(test_id, test_name)
        assert return_value == False
        
        mock_run_query.return_value = [
            [test_id]
        ]
        return_value = test_database.delete_budget(test_id, test_name)
        assert return_value == True

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_get_user_by_email(self, mock_run_query):
        test_email = 'some@email.com'

        mock_run_query.return_value = []
        return_value = test_database.get_user_by_email(test_email)
        assert return_value == None

        mock_user = create_mock_user(email=test_email)
        
        mock_run_query.return_value = [
            [1, 'name', datetime.now().date()]
        ]
        return_value = test_database.get_user_by_email(test_email)
        assert isinstance(return_value, User)
        assert return_value.id == mock_user.id
        assert return_value.name == mock_user.name
        assert return_value.created_date == mock_user.created_date

    @patch('database.finance_database.FinanceDatabase._run_query')
    def test_check_user(self, mock_run_query):
        test_id = 12345
        test_pass = 'stupidPass'

        mock_run_query.return_value = []
        return_value = test_database.check_user(test_id, test_pass)
        assert return_value == False
        
        mock_run_query.return_value = [
            [test_id]
        ]
        return_value = test_database.check_user(test_id, test_pass)
        assert return_value == True