Changeset - 0413fed8b957
[Not reviewed]
0 4 0
Brett Smith - 4 years ago 2020-04-06 20:03:56
brettcsmith@brettcsmith.org
meta_entity: Use payee as entity when metadata not available. RT#10529.
4 files changed with 65 insertions and 2 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/data.py
Show inline comments
...
 
@@ -187,2 +187,11 @@ class PostingMeta(Metadata):
 

	
 
    def __getitem__(self, key: MetaKey) -> MetaValue:
 
        try:
 
            return super().__getitem__(key)
 
        except KeyError:
 
            if key == 'entity' and self.txn.payee is not None:
 
                return self.txn.payee
 
            else:
 
                raise
 

	
 
    def __setitem__(self, key: MetaKey, value: MetaValue) -> None:
conservancy_beancount/plugin/meta_entity.py
Show inline comments
...
 
@@ -51,3 +51,3 @@ class MetaEntity(core.TransactionHook):
 
    def run(self, txn: Transaction) -> errormod.Iter:
 
        txn_entity = txn.meta.get(self.METADATA_KEY)
 
        txn_entity = txn.meta.get(self.METADATA_KEY, txn.payee)
 
        if txn_entity is None:
tests/test_data_posting_meta.py
Show inline comments
...
 
@@ -23,3 +23,3 @@ from conservancy_beancount import data
 
@pytest.fixture
 
def simple_txn(index=None, key=None):
 
def simple_txn():
 
    return testutil.Transaction(note='txn note', postings=[
...
 
@@ -30,2 +30,10 @@ SIMPLE_TXN_METAKEYS = frozenset(['filename', 'lineno', 'note'])
 

	
 
@pytest.fixture
 
def payee_txn():
 
    return testutil.Transaction(payee='SampleCo', postings=[
 
        ('Assets:Receivable:Accounts', -100),
 
        ('Assets:Checking', 95),
 
        ('Expenses:BankingFees', 5, {'entity': 'MyBank'}),
 
    ])
 

	
 
def test_getitem_transaction(simple_txn):
...
 
@@ -90,2 +98,18 @@ def test_get_links_from_post_override(simple_txn):
 

	
 
def test_payee_used_as_entity(payee_txn):
 
    actual = [data.PostingMeta(payee_txn, n, p)['entity']
 
              for n, p in enumerate(payee_txn.postings)]
 
    assert actual == ['SampleCo', 'SampleCo', 'MyBank']
 

	
 
def test_entity_metadata_has_precedence_over_payee(payee_txn):
 
    payee_txn.meta['entity'] = 'ExampleCo'
 
    actual = [data.PostingMeta(payee_txn, n, p)['entity']
 
              for n, p in enumerate(payee_txn.postings)]
 
    assert actual == ['ExampleCo', 'ExampleCo', 'MyBank']
 

	
 
def test_keyerror_when_no_entity_or_payee(simple_txn):
 
    meta = data.PostingMeta(simple_txn, 1)
 
    with pytest.raises(KeyError):
 
        meta['entity']
 

	
 
# The .get() tests are arguably testing the stdlib, but they're short and
tests/test_meta_entity.py
Show inline comments
...
 
@@ -112,2 +112,32 @@ def test_invalid_values_on_transactions(hook, src_value):
 

	
 
@pytest.mark.parametrize('src_value', VALID_VALUES)
 
def test_valid_values_on_payee(hook, src_value):
 
    txn = testutil.Transaction(payee=src_value, postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:General', 25),
 
    ])
 
    assert not any(hook.run(txn))
 

	
 
@pytest.mark.parametrize('src_value', INVALID_VALUES)
 
def test_invalid_values_on_payee(hook, src_value):
 
    txn = testutil.Transaction(payee=src_value, postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:General', 25),
 
    ])
 
    errors = list(hook.run(txn))
 
    assert 1 <= len(errors) <= 2
 
    assert all(error.message == "transaction has invalid entity: {}".format(src_value)
 
               for error in hook.run(txn))
 

	
 
@pytest.mark.parametrize('payee,src_value', testutil.combine_values(
 
    INVALID_VALUES,
 
    VALID_VALUES,
 
))
 
def test_invalid_payee_but_valid_metadata(hook, payee, src_value):
 
    txn = testutil.Transaction(**{'payee': payee, TEST_KEY: src_value}, postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:Other', 25),
 
    ])
 
    assert not any(hook.run(txn))
 

	
 
@pytest.mark.parametrize('account,required', [
0 comments (0 inline, 0 general)