Changeset - 69d079190ce7
[Not reviewed]
0 1 0
Brett Smith - 4 years ago 2020-07-02 17:08:21
brettcsmith@brettcsmith.org
tests: Test non-string values for payment-method metadata.
1 file changed with 1 insertions and 0 deletions:
0 comments (0 inline, 0 general)
tests/test_reports_accrual.py
Show inline comments
...
 
@@ -498,192 +498,193 @@ def test_balance_report(accrual_postings, invoice, expected, caplog):
 

	
 
def test_outgoing_report(accrual_postings, caplog):
 
    rt_client = RTClient()
 
    output = run_outgoing('rt:510', accrual_postings, rt_client)
 
    rt_url = RTClient.DEFAULT_URL[:-9]
 
    rt_id_url = rf'\b{re.escape(f"{rt_url}Ticket/Display.html?id=510")}\b'
 
    contract_url = rf'\b{re.escape(f"{rt_url}Ticket/Attachment/4000/4000/contract.pdf")}\b'
 
    assert not caplog.records
 
    check_output(output, [
 
        r'^PAYMENT FOR APPROVAL:$',
 
        r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
 
        r'^PAYMENT TO: Hon\. Mx\. 510$',
 
        r'^TOTAL TO PAY: \$280\.00$',
 
        fr'^AGREEMENT: {contract_url}',
 
        r'^BEANCOUNT ENTRIES:$',
 
        # For each transaction, check for the date line, a metadata, and the
 
        # Expenses posting.
 
        r'^\s*2010-06-10\s',
 
        fr'^\s+rt-id: "{rt_id_url}"$',
 
        r'^\s+Expenses:Services:Legal\s+220\.00 USD$',
 
        r'^\s*2010-06-10\s',
 
        fr'^\s+contract: "{contract_url}"$',
 
        r'^\s+Expenses:FilingFees\s+60\.00 USD$',
 
    ])
 
    assert rt_client.edits == {'510': {
 
        'CF_payment-amount': 'USD 280.00',
 
        'CF_payment-method': 'USD ACH',
 
    }}
 
    assert 'payment-method:' not in output.getvalue()
 

	
 
def test_outgoing_report_custom_field_fallbacks(accrual_postings, caplog):
 
    rt_client = RTClient(want_cfs=False)
 
    output = run_outgoing('rt:510', accrual_postings, rt_client)
 
    assert not caplog.records
 
    check_output(output, [
 
        r'^PAYMENT FOR APPROVAL:$',
 
        r'^REQUESTOR: <mx510@example\.org>$',
 
        r'^PAYMENT TO:\s*$',
 
    ])
 

	
 
def test_outgoing_report_fx_amounts(accrual_postings, caplog):
 
    rt_client = RTClient()
 
    output = run_outgoing('rt:520 rt:525', accrual_postings, rt_client)
 
    assert not caplog.records
 
    check_output(output, [
 
        r'^PAYMENT FOR APPROVAL:$',
 
        r'^REQUESTOR: Mx\. 520 <mx520@example\.org>$',
 
        r'^TOTAL TO PAY: 1,000\.00 EUR \(\$1,100.00\)$',
 
    ])
 
    assert rt_client.edits == {'520': {
 
        'CF_payment-amount': 'EUR 1,000.00 ($1,100.00)',
 
        'CF_payment-method': 'EUR Wire',
 
    }}
 
    assert 'payment-method:' not in output.getvalue()
 

	
 
def test_outgoing_report_multi_invoice(accrual_postings, caplog):
 
    rt_client = RTClient()
 
    output = run_outgoing('rt:310', accrual_postings, rt_client)
 
    log, = caplog.records
 
    assert log.levelname == 'WARNING'
 
    assert log.message.startswith('cannot set payment-method for rt:310: ')
 
    check_output(output, [
 
        r'^PAYMENT FOR APPROVAL:$',
 
        r'^REQUESTOR: Mx\. 310 <mx310@example\.org>$',
 
        r'^TOTAL TO PAY: \$420.00$',
 
    ])
 
    assert rt_client.edits == {'310': {
 
        'CF_payment-amount': 'USD 420.00',
 
    }}
 
    assert 'payment-method:' not in output.getvalue()
 

	
 
@pytest.mark.parametrize('arg', [
 
    'usd ach',
 
    '  eur  wire',
 
    'cad   vendorportal  ',
 
    ' gbp check ',
 
])
 
def test_outgoing_report_good_payment_method(caplog, accrual_postings, arg):
 
    rt_id = 'rt:40'
 
    meta = {'rt-id': rt_id, 'invoice': 'rt:40/100', 'payment-method': arg}
 
    txn = testutil.Transaction(postings=[
 
        ('Liabilities:Payable:Accounts', -100, meta),
 
    ])
 
    rt_client = RTClient()
 
    run_outgoing(rt_id, data.Posting.from_txn(txn), rt_client)
 
    assert not caplog.records
 
    cf_values = rt_client.edits[rt_id[3:]]['CF_payment-method'].split()
 
    assert cf_values[0] == arg.split()[0].upper()
 
    assert len(cf_values) > 1
 

	
 
@pytest.mark.parametrize('arg', [
 
    '',
 
    'usd',
 
    'usd nonexistent',
 
    'check',
 
    'us check',
 
    *testutil.NON_STRING_METADATA_VALUES,
 
])
 
def test_outgoing_report_bad_payment_method(caplog, accrual_postings, arg):
 
    rt_id = 'rt:40'
 
    meta = {'rt-id': rt_id, 'invoice': 'rt:40/100', 'payment-method': arg}
 
    txn = testutil.Transaction(postings=[
 
        ('Liabilities:Payable:Accounts', -100, meta),
 
    ])
 
    rt_client = RTClient()
 
    run_outgoing(rt_id, data.Posting.from_txn(txn), rt_client)
 
    assert caplog.records
 
    for log in caplog.records:
 
        assert log.levelname == 'WARNING'
 
        assert log.message.startswith(f'cannot set payment-method for {rt_id}: ')
 
    assert 'CF_payment-method' not in rt_client.edits[rt_id[3:]]
 

	
 
def test_outgoing_report_without_rt_id(accrual_postings, caplog):
 
    invoice = 'rt://ticket/515/attachments/5150'
 
    related = accruals_by_meta(
 
        accrual_postings, invoice, wrap_type=accrual.AccrualPostings,
 
    )
 
    output = run_outgoing(None, related)
 
    assert caplog.records
 
    log = caplog.records[0]
 
    assert log.message.startswith(
 
        f"can't generate outgoings report for 2010-05-15 MatchingProgram {invoice}"
 
        " because no RT ticket available:",
 
    )
 
    assert not output.getvalue()
 

	
 
def run_aging_report(postings, today):
 
    postings = (
 
        post for post in postings
 
        if post.account.is_under('Assets:Receivable', 'Liabilities:Payable')
 
    )
 
    groups = dict(accrual.AccrualPostings.make_consistent(postings))
 
    output = io.BytesIO()
 
    rt_wrapper = rtutil.RT(RTClient())
 
    report = accrual.AgingReport(rt_wrapper, output, today)
 
    report.run(groups)
 
    return output
 

	
 
@pytest.mark.parametrize('date', [
 
    datetime.date(2010, 3, 1),
 
    # Both these dates are chosen for their off-by-one potential:
 
    # the first is exactly 30 days after the 2010-06-10 payable;
 
    # the second is exactly 60 days after the 2010-05-15 receivable.
 
    datetime.date(2010, 7, 10),
 
    datetime.date(2010, 7, 14),
 
    # The remainder just shuffle the age buckets some.
 
    datetime.date(2010, 12, 1),
 
    datetime.date(2011, 6, 1),
 
    datetime.date(2011, 12, 1),
 
    datetime.date(2012, 3, 1),
 
])
 
def test_aging_report_date_cutoffs(accrual_postings, date):
 
    output = run_aging_report(accrual_postings, date)
 
    check_aging_ods(output, date)
 

	
 
def test_aging_report_entity_consistency(accrual_postings):
 
    date = datetime.date.today()
 
    output = run_aging_report((
 
        post for post in accrual_postings
 
        if post.meta.get('rt-id') == 'rt:480'
 
        and post.units.number < 0
 
    ), date)
 
    check_aging_ods(output, date, [], [
 
        AgingRow.make_simple('2010-04-15', 'MultiPartyA', 125, 'rt:480/4800'),
 
        AgingRow.make_simple('2010-04-15', 'MultiPartyB', 125, 'rt:480/4800'),
 
    ])
 

	
 
def run_main(arglist, config=None, out_type=io.StringIO):
 
    if config is None:
 
        config = testutil.TestConfig(
 
            books_path=testutil.test_path('books/accruals.beancount'),
 
            rt_client=RTClient(),
 
        )
 
    if out_type is io.BytesIO:
 
        arglist.insert(0, '--output-file=-')
 
    output = out_type()
 
    errors = io.StringIO()
 
    retcode = accrual.main(arglist, output, errors, config)
 
    output.seek(0)
 
    errors.seek(0)
 
    return retcode, output, errors
 

	
 
def check_main_fails(arglist, config, error_flags):
 
    retcode, output, errors = run_main(arglist, config)
 
    assert retcode > 16
 
    assert (retcode - 16) & error_flags
 
    assert not output.getvalue()
 
    return errors
 

	
 
@pytest.mark.parametrize('arglist', [
 
    ['--report-type=balance', 'entity=EarlyBird'],
 
    ['--report-type=outgoing', 'entity=EarlyBird'],
 
])
0 comments (0 inline, 0 general)