Files @ 22d5b7e90a1e
Branch filter:

Location: NPO-Accounting/conservancy_beancount/tests/test_data_posting.py

Brett Smith
setup: Disallow untyped calls.
"""Test Posting class"""
# Copyright © 2020  Brett Smith
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

import pytest

from . import testutil

from decimal import Decimal

import beancount.core.amount as bc_amount

from conservancy_beancount import data

PAYMENT_ACCOUNTS = {
    'Assets:Cash',
    'Assets:Checking',
}

NON_PAYMENT_ACCOUNTS = {
    'Accrued:AccountsReceivable',
    'Assets:PrepaidExpenses',
    'Assets:PrepaidVacation',
    'Expenses:Other',
    'Income:Other',
    'Liabilities:CreditCard',
    'UnearnedIncome:MatchPledges',
}

def Posting(account, number,
            currency='USD', cost=None, price=None, flag=None,
            **meta):
    if not meta:
        meta = None
    return data.Posting(
        data.Account(account),
        bc_amount.Amount(Decimal(number), currency),
        cost,
        price,
        flag,
        meta,
    )

def check_all_thresholds(post, threshold, expected):
    assert post.is_payment(threshold) is expected
    assert post.is_payment(-threshold) is expected
    assert post.is_payment(Decimal(threshold)) is expected
    assert post.is_payment(Decimal(-threshold)) is expected

@pytest.mark.parametrize('acct', PAYMENT_ACCOUNTS)
def test_is_payment(acct):
    assert Posting(acct, -500).is_payment()

@pytest.mark.parametrize('acct,amount,threshold', testutil.combine_values(
    NON_PAYMENT_ACCOUNTS,
    range(5, 20, 5),
    range(0, 30, 10),
))
def test_is_not_payment_account(acct, amount, threshold):
    post = Posting(acct, -amount)
    assert not post.is_payment()
    check_all_thresholds(post, threshold, False)

@pytest.mark.parametrize('acct', PAYMENT_ACCOUNTS)
def test_is_payment_with_threshold(acct):
    threshold = len(acct) * 10
    post = Posting(acct, -500)
    check_all_thresholds(post, threshold, True)

@pytest.mark.parametrize('acct', PAYMENT_ACCOUNTS)
def test_is_not_payment_by_threshold(acct):
    threshold = len(acct) * 10
    post = Posting(acct, -9)
    check_all_thresholds(post, threshold, False)

@pytest.mark.parametrize('acct', PAYMENT_ACCOUNTS)
def test_is_not_payment_but_credit(acct):
    post = Posting(acct, 9)
    assert not post.is_payment()
    check_all_thresholds(post, 0, False)
    check_all_thresholds(post, 5, False)
    check_all_thresholds(post, 10, False)