Merge pull request #5 from Crocmagnon/improve-coverage
Improve test coverage
This commit is contained in:
commit
05ccb7d15f
11 changed files with 546 additions and 45 deletions
|
@ -9,7 +9,10 @@ CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||||
@click.group(context_settings=CONTEXT_SETTINGS)
|
@click.group(context_settings=CONTEXT_SETTINGS)
|
||||||
@click.version_option()
|
@click.version_option()
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
"""
|
||||||
|
Import your data to YNAB with the processors listed below
|
||||||
|
or manage your config.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(ynab.config, name="config")
|
cli.add_command(ynab.config, name="config")
|
||||||
|
|
|
@ -43,13 +43,13 @@ class Line:
|
||||||
|
|
||||||
|
|
||||||
class Processor:
|
class Processor:
|
||||||
transaction_ids = defaultdict(int)
|
|
||||||
line_class = Line
|
line_class = Line
|
||||||
account_name = None
|
account_name = None
|
||||||
|
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.iterable = self.parse_file()
|
self.iterable = self.parse_file()
|
||||||
|
self.transaction_ids = defaultdict(int)
|
||||||
|
|
||||||
def parse_file(self):
|
def parse_file(self):
|
||||||
return [] # pragma: nocover
|
return [] # pragma: nocover
|
||||||
|
|
|
@ -29,18 +29,17 @@ def get_config_file_name():
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
def config():
|
def config():
|
||||||
pass
|
"""
|
||||||
|
Manage configuration with subcommands
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@config.command("edit")
|
||||||
def edit_config():
|
def edit_config():
|
||||||
config_file = get_config_file_name()
|
config_file = get_config_file_name()
|
||||||
click.edit(filename=config_file)
|
click.edit(filename=config_file)
|
||||||
|
|
||||||
|
|
||||||
config.add_command(edit_config, "edit")
|
|
||||||
|
|
||||||
|
|
||||||
def push_transactions(transactions, account):
|
def push_transactions(transactions, account):
|
||||||
if not transactions:
|
if not transactions:
|
||||||
click.secho("No transaction, nothing to do.", fg="yellow")
|
click.secho("No transaction, nothing to do.", fg="yellow")
|
||||||
|
@ -73,7 +72,7 @@ def push_transactions(transactions, account):
|
||||||
|
|
||||||
created = set()
|
created = set()
|
||||||
for transaction in data["transactions"]:
|
for transaction in data["transactions"]:
|
||||||
matched_id = transaction["matched_transaction_id"]
|
matched_id = transaction.get("matched_transaction_id")
|
||||||
if not matched_id or matched_id not in created:
|
if not matched_id or matched_id not in created:
|
||||||
created.add(transaction["id"])
|
created.add(transaction["id"])
|
||||||
|
|
||||||
|
|
|
@ -1 +1,121 @@
|
||||||
[{"date": "2020-02-26", "amount": -9660, "payee_name": "PRLV SEPA Company 3", "memo": "123456789 PAYPAL 542UHBON", "import_id": "YNAB:-9660:2020-02-26:1"}, {"date": "2020-02-25", "amount": -2400, "payee_name": "H.I.K 69VILLEURBANNE", "memo": "240220 CB****5555", "import_id": "YNAB:-2400:2020-02-25:1"}, {"date": "2020-02-25", "amount": -39200, "payee_name": "DELIVEROO FR WWW", "memo": "230220 CB****5555 39,20EUR 1 EURO = 1,000000", "import_id": "YNAB:-39200:2020-02-25:1"}, {"date": "2020-02-25", "amount": -9990, "payee_name": "PRLV SEPA Company 1", "memo": "Votre abonnement mobile: 06XXXXX 6498165189060897", "import_id": "YNAB:-9990:2020-02-25:1"}, {"date": "2020-02-24", "amount": -7500, "payee_name": "COMPANY FR LYON 6EME", "memo": "210220 CB****5555 7,50EUR 1 EURO = 1,000000", "import_id": "YNAB:-7500:2020-02-24:1"}, {"date": "2020-02-24", "amount": -34990, "payee_name": "PRLV SEPA Company 2", "memo": "24-02-2020 / 22-03-2020 56418710", "import_id": "YNAB:-34990:2020-02-24:1"}, {"date": "2020-02-24", "amount": -2390, "payee_name": "VIR Person 1", "memo": "481840871 Splitwise", "import_id": "YNAB:-2390:2020-02-24:1"}, {"date": "2020-02-20", "amount": 235000, "payee_name": "VIREMENT Person 2", "memo": "Cadeau", "import_id": "YNAB:235000:2020-02-20:1"}, {"date": "2020-02-20", "amount": 55000, "payee_name": "VIREMENT Company 3", "memo": "48716508719", "import_id": "YNAB:55000:2020-02-20:1"}, {"date": "2020-02-19", "amount": -55000, "payee_name": "BDE INSA LYON 69VILLEURBANNE", "memo": "170220 CB****5555", "import_id": "YNAB:-55000:2020-02-19:1"}, {"date": "2020-02-19", "amount": -900, "payee_name": "GUY AND SONS FR LYON", "memo": "180220 CB****5555 0,90EUR 1 EURO = 1,000000", "import_id": "YNAB:-900:2020-02-19:1"}, {"date": "2020-02-19", "amount": -1400, "payee_name": "GUY AND SONS FR LYON", "memo": "170220 CB****5555 1,40EUR 1 EURO = 1,000000", "import_id": "YNAB:-1400:2020-02-19:1"}, {"date": "2020-02-19", "amount": -473500, "payee_name": "VIR Person 1", "memo": "65187460 Acompte cuisine 2", "import_id": "YNAB:-473500:2020-02-19:1"}, {"date": "2020-02-18", "amount": -96960, "payee_name": "PRLV SEPA Company 4", "memo": "487105874 Amazon.fr 3X QC.(OJBIYN:ZOFEUBZF51871", "import_id": "YNAB:-96960:2020-02-18:1"}, {"date": "2020-02-17", "amount": -232000, "payee_name": "GRAND PARC PUY 85LES EPESSES", "memo": "150220 CB****5555", "import_id": "YNAB:-232000:2020-02-17:1"}, {"date": "2020-02-17", "amount": -1000, "payee_name": "UBER BV NL HELP.UBER.CO", "memo": "140220 CB****5555 1,00EUR 1 EURO = 1,000000", "import_id": "YNAB:-1000:2020-02-17:1"}, {"date": "2020-02-17", "amount": 8600, "payee_name": "VIREMENT Person 5", "memo": "VIREMENT DE PERSON 6", "import_id": "YNAB:8600:2020-02-17:1"}]
|
[
|
||||||
|
{
|
||||||
|
"date": "2020-02-26",
|
||||||
|
"amount": -9660,
|
||||||
|
"payee_name": "PRLV SEPA Company 3",
|
||||||
|
"memo": "123456789 PAYPAL 542UHBON",
|
||||||
|
"import_id": "YNAB:-9660:2020-02-26:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-25",
|
||||||
|
"amount": -2400,
|
||||||
|
"payee_name": "H.I.K 69VILLEURBANNE",
|
||||||
|
"memo": "240220 CB****5555",
|
||||||
|
"import_id": "YNAB:-2400:2020-02-25:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-25",
|
||||||
|
"amount": -39200,
|
||||||
|
"payee_name": "DELIVEROO FR WWW",
|
||||||
|
"memo": "230220 CB****5555 39,20EUR 1 EURO = 1,000000",
|
||||||
|
"import_id": "YNAB:-39200:2020-02-25:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-25",
|
||||||
|
"amount": -9990,
|
||||||
|
"payee_name": "PRLV SEPA Company 1",
|
||||||
|
"memo": "Votre abonnement mobile: 06XXXXX 6498165189060897",
|
||||||
|
"import_id": "YNAB:-9990:2020-02-25:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": -7500,
|
||||||
|
"payee_name": "COMPANY FR LYON 6EME",
|
||||||
|
"memo": "210220 CB****5555 7,50EUR 1 EURO = 1,000000",
|
||||||
|
"import_id": "YNAB:-7500:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": -34990,
|
||||||
|
"payee_name": "PRLV SEPA Company 2",
|
||||||
|
"memo": "24-02-2020 / 22-03-2020 56418710",
|
||||||
|
"import_id": "YNAB:-34990:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": -2390,
|
||||||
|
"payee_name": "VIR Person 1",
|
||||||
|
"memo": "481840871 Splitwise",
|
||||||
|
"import_id": "YNAB:-2390:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-20",
|
||||||
|
"amount": 235000,
|
||||||
|
"payee_name": "VIREMENT Person 2",
|
||||||
|
"memo": "Cadeau",
|
||||||
|
"import_id": "YNAB:235000:2020-02-20:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-20",
|
||||||
|
"amount": 55000,
|
||||||
|
"payee_name": "VIREMENT Company 3",
|
||||||
|
"memo": "48716508719",
|
||||||
|
"import_id": "YNAB:55000:2020-02-20:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-19",
|
||||||
|
"amount": -55000,
|
||||||
|
"payee_name": "BDE INSA LYON 69VILLEURBANNE",
|
||||||
|
"memo": "170220 CB****5555",
|
||||||
|
"import_id": "YNAB:-55000:2020-02-19:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-19",
|
||||||
|
"amount": -900,
|
||||||
|
"payee_name": "GUY AND SONS FR LYON",
|
||||||
|
"memo": "180220 CB****5555 0,90EUR 1 EURO = 1,000000",
|
||||||
|
"import_id": "YNAB:-900:2020-02-19:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-19",
|
||||||
|
"amount": -1400,
|
||||||
|
"payee_name": "GUY AND SONS FR LYON",
|
||||||
|
"memo": "170220 CB****5555 1,40EUR 1 EURO = 1,000000",
|
||||||
|
"import_id": "YNAB:-1400:2020-02-19:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-19",
|
||||||
|
"amount": -473500,
|
||||||
|
"payee_name": "VIR Person 1",
|
||||||
|
"memo": "65187460 Acompte cuisine 2",
|
||||||
|
"import_id": "YNAB:-473500:2020-02-19:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-18",
|
||||||
|
"amount": -96960,
|
||||||
|
"payee_name": "PRLV SEPA Company 4",
|
||||||
|
"memo": "487105874 Amazon.fr 3X QC.(OJBIYN:ZOFEUBZF51871",
|
||||||
|
"import_id": "YNAB:-96960:2020-02-18:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-17",
|
||||||
|
"amount": -232000,
|
||||||
|
"payee_name": "GRAND PARC PUY 85LES EPESSES",
|
||||||
|
"memo": "150220 CB****5555",
|
||||||
|
"import_id": "YNAB:-232000:2020-02-17:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-17",
|
||||||
|
"amount": -1000,
|
||||||
|
"payee_name": "UBER BV NL HELP.UBER.CO",
|
||||||
|
"memo": "140220 CB****5555 1,00EUR 1 EURO = 1,000000",
|
||||||
|
"import_id": "YNAB:-1000:2020-02-17:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-17",
|
||||||
|
"amount": 8600,
|
||||||
|
"payee_name": "VIREMENT Person 5",
|
||||||
|
"memo": "VIREMENT DE PERSON 6",
|
||||||
|
"import_id": "YNAB:8600:2020-02-17:1"
|
||||||
|
}
|
||||||
|
]
|
|
@ -1 +1,44 @@
|
||||||
[{"date": "2020-02-25", "amount": -21000, "payee_name": "CB DECATHLON", "memo": "FACT 240220", "import_id": "YNAB:-21000:2020-02-25:1"}, {"date": "2020-02-25", "amount": -7000, "payee_name": "PRLV COMPANY", "memo": "Company Ref Prlvt SEPA 99-1KIBHEF-01 45871984", "import_id": "YNAB:-7000:2020-02-25:1"}, {"date": "2020-02-24", "amount": -48130, "payee_name": "CB 3403 MONOP", "memo": "FACT 210220", "import_id": "YNAB:-48130:2020-02-24:1"}, {"date": "2020-02-24", "amount": -1200, "payee_name": "CB MALATIER", "memo": "FACT 210220", "import_id": "YNAB:-1200:2020-02-24:1"}, {"date": "2020-02-24", "amount": 2390, "payee_name": "VIR SEPA PERSON 1", "memo": "_", "import_id": "YNAB:2390:2020-02-24:1"}, {"date": "2020-02-24", "amount": 14490, "payee_name": "VIR SEPA PERSON 2", "memo": "_", "import_id": "YNAB:14490:2020-02-24:1"}]
|
[
|
||||||
|
{
|
||||||
|
"date": "2020-02-25",
|
||||||
|
"amount": -21000,
|
||||||
|
"payee_name": "CB DECATHLON",
|
||||||
|
"memo": "FACT 240220",
|
||||||
|
"import_id": "YNAB:-21000:2020-02-25:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-25",
|
||||||
|
"amount": -7000,
|
||||||
|
"payee_name": "PRLV COMPANY",
|
||||||
|
"memo": "Company Ref Prlvt SEPA 99-1KIBHEF-01 45871984",
|
||||||
|
"import_id": "YNAB:-7000:2020-02-25:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": -48130,
|
||||||
|
"payee_name": "CB 3403 MONOP",
|
||||||
|
"memo": "FACT 210220",
|
||||||
|
"import_id": "YNAB:-48130:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": -1200,
|
||||||
|
"payee_name": "CB MALATIER",
|
||||||
|
"memo": "FACT 210220",
|
||||||
|
"import_id": "YNAB:-1200:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": 2390,
|
||||||
|
"payee_name": "VIR SEPA PERSON 1",
|
||||||
|
"memo": "_",
|
||||||
|
"import_id": "YNAB:2390:2020-02-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-02-24",
|
||||||
|
"amount": 14490,
|
||||||
|
"payee_name": "VIR SEPA PERSON 2",
|
||||||
|
"memo": "_",
|
||||||
|
"import_id": "YNAB:14490:2020-02-24:1"
|
||||||
|
}
|
||||||
|
]
|
12
tests/samples/config.ini
Normal file
12
tests/samples/config.ini
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[DEFAULT]
|
||||||
|
token = <YOUR API TOKEN>
|
||||||
|
budget = <YOUR BUDGET ID>
|
||||||
|
|
||||||
|
[bpvf]
|
||||||
|
account = <YOUR BPVF ACCOUNT ID>
|
||||||
|
|
||||||
|
[revolut]
|
||||||
|
account = <YOUR REVOLUT ACCOUNT ID>
|
||||||
|
|
||||||
|
[ce]
|
||||||
|
account = <YOUR CE ACCOUNT ID>
|
|
@ -1 +1,65 @@
|
||||||
[{"date": "2020-01-29", "amount": -53630, "payee_name": "To Person 1", "memo": "Transfers", "import_id": "YNAB:-53630:2020-01-29:1"}, {"date": "2020-01-29", "amount": -900, "payee_name": "To Person 2", "memo": "Transfers", "import_id": "YNAB:-900:2020-01-29:1"}, {"date": "2020-01-29", "amount": 53630, "payee_name": "Refund from Company 2", "memo": "Shopping", "import_id": "YNAB:53630:2020-01-29:1"}, {"date": "2020-01-24", "amount": -8500, "payee_name": "To Person 3", "memo": "Transfers", "import_id": "YNAB:-8500:2020-01-24:1"}, {"date": "2020-01-16", "amount": -1400, "payee_name": "To Person 4", "memo": "Transfers", "import_id": "YNAB:-1400:2020-01-16:1"}, {"date": "2020-01-10", "amount": -2009, "payee_name": "To Person 5", "memo": "Transfers", "import_id": "YNAB:-2009:2020-01-10:1"}, {"date": "2020-01-10", "amount": -1210, "payee_name": "To Person 6", "memo": "Transfers", "import_id": "YNAB:-1210:2020-01-10:1"}, {"date": "2020-01-05", "amount": -123680, "payee_name": "Company 1", "memo": "Shopping - FX-rate \u20ac1\u2008=\u2008US$1,1158", "import_id": "YNAB:-123680:2020-01-05:1"}, {"date": "2020-01-04", "amount": 100000, "payee_name": "Top-up via Apple Pay", "memo": "General", "import_id": "YNAB:100000:2020-01-04:1"}]
|
[
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": -53630,
|
||||||
|
"payee_name": "To Person 1",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-53630:2020-01-29:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": -900,
|
||||||
|
"payee_name": "To Person 2",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-900:2020-01-29:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": 53630,
|
||||||
|
"payee_name": "Refund from Company 2",
|
||||||
|
"memo": "Shopping",
|
||||||
|
"import_id": "YNAB:53630:2020-01-29:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-24",
|
||||||
|
"amount": -8500,
|
||||||
|
"payee_name": "To Person 3",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-8500:2020-01-24:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-16",
|
||||||
|
"amount": -1400,
|
||||||
|
"payee_name": "To Person 4",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-1400:2020-01-16:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-10",
|
||||||
|
"amount": -2009,
|
||||||
|
"payee_name": "To Person 5",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-2009:2020-01-10:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-10",
|
||||||
|
"amount": -1210,
|
||||||
|
"payee_name": "To Person 6",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-1210:2020-01-10:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-05",
|
||||||
|
"amount": -123680,
|
||||||
|
"payee_name": "Company 1",
|
||||||
|
"memo": "Shopping - FX-rate \u20ac1\u2008=\u2008US$1,1158",
|
||||||
|
"import_id": "YNAB:-123680:2020-01-05:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-04",
|
||||||
|
"amount": 100000,
|
||||||
|
"payee_name": "Top-up via Apple Pay",
|
||||||
|
"memo": "General",
|
||||||
|
"import_id": "YNAB:100000:2020-01-04:1"
|
||||||
|
}
|
||||||
|
]
|
76
tests/samples/transactions.json
Normal file
76
tests/samples/transactions.json
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": -53630,
|
||||||
|
"payee_name": "To Person 1",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-53630:2020-01-29:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": -900,
|
||||||
|
"payee_name": "To Person 2",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-900:2020-01-29:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-29",
|
||||||
|
"amount": 53630,
|
||||||
|
"payee_name": "Refund from Company 2",
|
||||||
|
"memo": "Shopping",
|
||||||
|
"import_id": "YNAB:53630:2020-01-29:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-24",
|
||||||
|
"amount": -8500,
|
||||||
|
"payee_name": "To Person 3",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-8500:2020-01-24:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-16",
|
||||||
|
"amount": -1400,
|
||||||
|
"payee_name": "To Person 4",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-1400:2020-01-16:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-10",
|
||||||
|
"amount": -2009,
|
||||||
|
"payee_name": "To Person 5",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-2009:2020-01-10:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-10",
|
||||||
|
"amount": -1210,
|
||||||
|
"payee_name": "To Person 6",
|
||||||
|
"memo": "Transfers",
|
||||||
|
"import_id": "YNAB:-1210:2020-01-10:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-05",
|
||||||
|
"amount": -123680,
|
||||||
|
"payee_name": "Company 1",
|
||||||
|
"memo": "Shopping - FX-rate €1 = US$1,1158",
|
||||||
|
"import_id": "YNAB:-123680:2020-01-05:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2020-01-04",
|
||||||
|
"amount": 100000,
|
||||||
|
"payee_name": "Top-up via Apple Pay",
|
||||||
|
"memo": "General",
|
||||||
|
"import_id": "YNAB:100000:2020-01-04:1",
|
||||||
|
"account_id": "<YOUR REVOLUT ACCOUNT ID>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
184
tests/test_end_to_end.py
Normal file
184
tests/test_end_to_end.py
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
from unittest.mock import call
|
||||||
|
|
||||||
|
from click.testing import CliRunner
|
||||||
|
|
||||||
|
from ofx_processor.processors.bpvf import BpvfProcessor
|
||||||
|
from ofx_processor.processors.ce import CeProcessor
|
||||||
|
from ofx_processor.processors.revolut import RevolutProcessor
|
||||||
|
from ofx_processor.utils import utils
|
||||||
|
from ofx_processor.utils import ynab
|
||||||
|
from ofx_processor.utils.ynab import config
|
||||||
|
|
||||||
|
|
||||||
|
class UtilsTestCase(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
This class needs to run before any other that imports
|
||||||
|
ofx_processor.main.cli because it tests import time stuff.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def test_discover_processors():
|
||||||
|
ce_main = CeProcessor.main
|
||||||
|
bpvf_main = BpvfProcessor.main
|
||||||
|
revolut_main = RevolutProcessor.main
|
||||||
|
runner = CliRunner()
|
||||||
|
with mock.patch("click.core.Group.add_command") as add_command:
|
||||||
|
from ofx_processor.main import cli
|
||||||
|
|
||||||
|
runner.invoke(cli, ["--help"])
|
||||||
|
calls = [
|
||||||
|
call(ce_main),
|
||||||
|
call(bpvf_main),
|
||||||
|
call(revolut_main),
|
||||||
|
call(config, name="config"),
|
||||||
|
]
|
||||||
|
add_command.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigEditTestCase(unittest.TestCase):
|
||||||
|
@mock.patch("click.edit")
|
||||||
|
def test_config_edit(self, edit):
|
||||||
|
config_dir = "tests/samples"
|
||||||
|
ynab.DEFAULT_CONFIG_DIR = config_dir
|
||||||
|
expected_filename = f"{config_dir}/config.ini"
|
||||||
|
runner = CliRunner()
|
||||||
|
from ofx_processor.main import cli
|
||||||
|
|
||||||
|
# This is run at import time and the cli module is already imported before this test
|
||||||
|
# so we need to re-run the add_command to make it available.
|
||||||
|
cli.add_command(ynab.config, name="config")
|
||||||
|
|
||||||
|
runner.invoke(cli, ["config", "edit"])
|
||||||
|
edit.assert_called_once_with(filename=expected_filename)
|
||||||
|
|
||||||
|
|
||||||
|
class DataTestCase(unittest.TestCase):
|
||||||
|
@mock.patch("requests.post")
|
||||||
|
def test_revolut_sends_data_only_created(self, post):
|
||||||
|
ynab.DEFAULT_CONFIG_DIR = "tests/samples"
|
||||||
|
post.return_value.json.return_value = {
|
||||||
|
"data": {
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"id": "ynab_existing:1",
|
||||||
|
"matched_transaction_id": "imported_matched:2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "imported_matched:2",
|
||||||
|
"matched_transaction_id": "ynab_existing:1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "imported_matched:3",
|
||||||
|
"matched_transaction_id": "ynab_existing:4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ynab_existing:4",
|
||||||
|
"matched_transaction_id": "imported_matched:3",
|
||||||
|
},
|
||||||
|
{"id": "created:5", "matched_transaction_id": None},
|
||||||
|
{"id": "created:6", "matched_transaction_id": None},
|
||||||
|
{"id": "created:7", "matched_transaction_id": None},
|
||||||
|
{"id": "created:8", "matched_transaction_id": None},
|
||||||
|
{"id": "created:9", "matched_transaction_id": None},
|
||||||
|
{"id": "created:10", "matched_transaction_id": None},
|
||||||
|
{"id": "created:11", "matched_transaction_id": None},
|
||||||
|
],
|
||||||
|
"duplicate_import_ids": [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
from ofx_processor.main import cli
|
||||||
|
|
||||||
|
# This is run at import time and the cli module is already imported before this test
|
||||||
|
# so we need to re-run the add_command to make it available.
|
||||||
|
utils.discover_processors(cli)
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(cli, ["revolut", "tests/samples/revolut.csv"])
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
self.assertIn("Processed 9 transactions total.", result.output)
|
||||||
|
self.assertIn("9 transactions created in YNAB.", result.output)
|
||||||
|
self.assertNotIn("transactions ignored (duplicates).", result.output)
|
||||||
|
|
||||||
|
@mock.patch("requests.post")
|
||||||
|
def test_revolut_sends_data_some_created_some_duplicates(self, post):
|
||||||
|
ynab.DEFAULT_CONFIG_DIR = "tests/samples"
|
||||||
|
post.return_value.json.return_value = {
|
||||||
|
"data": {
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"id": "ynab_existing:1",
|
||||||
|
"matched_transaction_id": "imported_matched:2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "imported_matched:2",
|
||||||
|
"matched_transaction_id": "ynab_existing:1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "imported_matched:3",
|
||||||
|
"matched_transaction_id": "ynab_existing:4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ynab_existing:4",
|
||||||
|
"matched_transaction_id": "imported_matched:3",
|
||||||
|
},
|
||||||
|
{"id": "created:5", "matched_transaction_id": None},
|
||||||
|
],
|
||||||
|
"duplicate_import_ids": [
|
||||||
|
"duplicate:6",
|
||||||
|
"duplicate:7",
|
||||||
|
"duplicate:8",
|
||||||
|
"duplicate:9",
|
||||||
|
"duplicate:10",
|
||||||
|
"duplicate:11",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
from ofx_processor.main import cli
|
||||||
|
|
||||||
|
# This is run at import time and the cli module is already imported before this test
|
||||||
|
# so we need to re-run the add_command to make it available.
|
||||||
|
utils.discover_processors(cli)
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(cli, ["revolut", "tests/samples/revolut.csv"])
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
self.assertIn("Processed 9 transactions total.", result.output)
|
||||||
|
self.assertIn("3 transactions created in YNAB.", result.output)
|
||||||
|
self.assertIn("6 transactions ignored (duplicates).", result.output)
|
||||||
|
|
||||||
|
@mock.patch("requests.post")
|
||||||
|
def test_revolut_sends_data_only_duplicates(self, post):
|
||||||
|
ynab.DEFAULT_CONFIG_DIR = "tests/samples"
|
||||||
|
post.return_value.json.return_value = {
|
||||||
|
"data": {
|
||||||
|
"transactions": [],
|
||||||
|
"duplicate_import_ids": [
|
||||||
|
"duplicate:1",
|
||||||
|
"duplicate:2",
|
||||||
|
"duplicate:3",
|
||||||
|
"duplicate:4",
|
||||||
|
"duplicate:5",
|
||||||
|
"duplicate:6",
|
||||||
|
"duplicate:7",
|
||||||
|
"duplicate:8",
|
||||||
|
"duplicate:9",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
from ofx_processor.main import cli
|
||||||
|
|
||||||
|
# This is run at import time and the cli module is already imported before this test
|
||||||
|
# so we need to re-run the add_command to make it available.
|
||||||
|
utils.discover_processors(cli)
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(cli, ["revolut", "tests/samples/revolut.csv"])
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
self.assertIn("Processed 9 transactions total.", result.output)
|
||||||
|
self.assertNotIn("transactions created in YNAB.", result.output)
|
||||||
|
self.assertIn("9 transactions ignored (duplicates).", result.output)
|
|
@ -1,34 +0,0 @@
|
||||||
import unittest
|
|
||||||
from unittest import mock
|
|
||||||
from unittest.mock import call
|
|
||||||
|
|
||||||
from click.testing import CliRunner
|
|
||||||
|
|
||||||
from ofx_processor.processors.bpvf import BpvfProcessor
|
|
||||||
from ofx_processor.processors.ce import CeProcessor
|
|
||||||
from ofx_processor.processors.revolut import RevolutProcessor
|
|
||||||
from ofx_processor.utils.ynab import config
|
|
||||||
|
|
||||||
|
|
||||||
class UtilsTestCase(unittest.TestCase):
|
|
||||||
@staticmethod
|
|
||||||
def test_discover_processors():
|
|
||||||
ce_main = CeProcessor.main
|
|
||||||
bpvf_main = BpvfProcessor.main
|
|
||||||
revolut_main = RevolutProcessor.main
|
|
||||||
runner = CliRunner()
|
|
||||||
with mock.patch("click.core.Group.add_command") as add_command:
|
|
||||||
from ofx_processor.main import cli
|
|
||||||
|
|
||||||
runner.invoke(cli, ["--help"])
|
|
||||||
calls = [
|
|
||||||
call(ce_main),
|
|
||||||
call(bpvf_main),
|
|
||||||
call(revolut_main),
|
|
||||||
call(config, name="config"),
|
|
||||||
]
|
|
||||||
add_command.assert_has_calls(calls, any_order=True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main() # pragma: nocover
|
|
34
tests/test_ynab_integration.py
Normal file
34
tests/test_ynab_integration.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import json
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from ofx_processor.utils import ynab
|
||||||
|
|
||||||
|
|
||||||
|
class YNABIntegrationTestCase(unittest.TestCase):
|
||||||
|
@mock.patch("requests.post")
|
||||||
|
def test_data_sent_to_ynab(self, post):
|
||||||
|
ynab.DEFAULT_CONFIG_DIR = "tests/samples"
|
||||||
|
|
||||||
|
with open("tests/samples/revolut_expected.json", encoding="utf-8") as f:
|
||||||
|
transactions = json.load(f)
|
||||||
|
with open("tests/samples/transactions.json", encoding="utf-8") as f:
|
||||||
|
expected_data = json.load(f)
|
||||||
|
|
||||||
|
expected_headers = {"Authorization": f"Bearer <YOUR API TOKEN>"}
|
||||||
|
expected_url = f"{ynab.BASE_URL}/budgets/<YOUR BUDGET ID>/transactions"
|
||||||
|
|
||||||
|
ynab.push_transactions(transactions, "revolut")
|
||||||
|
|
||||||
|
post.assert_called_once_with(
|
||||||
|
expected_url, json=expected_data, headers=expected_headers
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch("requests.post")
|
||||||
|
def test_no_data_to_send(self, post):
|
||||||
|
ynab.push_transactions([], "")
|
||||||
|
post.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main() # pragma: nocover
|
Loading…
Reference in a new issue