forked from gaugendre/ofx-processor
Improve and test bad config file handling
This commit is contained in:
parent
a32e568dde
commit
b1e80994b4
6 changed files with 78 additions and 16 deletions
|
@ -59,20 +59,21 @@ def push_transactions(transactions, account):
|
||||||
try:
|
try:
|
||||||
config.read(config_file)
|
config.read(config_file)
|
||||||
except configparser.Error as e:
|
except configparser.Error as e:
|
||||||
click.secho(f"Error while parsing config file: {str(e)}", fg="red", bold=True)
|
return handle_config_file_error(config_file, e)
|
||||||
click.secho("Opening the file...")
|
|
||||||
click.pause()
|
try:
|
||||||
click.edit(filename=config_file)
|
section = config[account]
|
||||||
click.secho("Exiting...", fg="red", bold=True)
|
budget_id = section["budget"]
|
||||||
sys.exit(1)
|
token = section["token"]
|
||||||
section = config[account]
|
account = section["account"]
|
||||||
budget_id = section["budget"]
|
except KeyError as e:
|
||||||
|
return handle_config_file_error(config_file, e)
|
||||||
|
|
||||||
url = f"{BASE_URL}/budgets/{budget_id}/transactions"
|
url = f"{BASE_URL}/budgets/{budget_id}/transactions"
|
||||||
for transaction in transactions:
|
for transaction in transactions:
|
||||||
transaction["account_id"] = section["account"]
|
transaction["account_id"] = account
|
||||||
|
|
||||||
data = {"transactions": transactions}
|
data = {"transactions": transactions}
|
||||||
token = section["token"]
|
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
res = requests.post(url, json=data, headers=headers)
|
res = requests.post(url, json=data, headers=headers)
|
||||||
|
@ -95,3 +96,12 @@ def push_transactions(transactions, account):
|
||||||
click.secho(
|
click.secho(
|
||||||
f"{len(duplicates)} transactions ignored (duplicates).", fg="yellow"
|
f"{len(duplicates)} transactions ignored (duplicates).", fg="yellow"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_config_file_error(config_file, e):
|
||||||
|
click.secho(f"Error while parsing config file: {str(e)}", fg="red", bold=True)
|
||||||
|
click.secho("Opening the file...")
|
||||||
|
click.pause()
|
||||||
|
click.edit(filename=config_file)
|
||||||
|
click.secho("Exiting...", fg="red", bold=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
9
tests/samples/config_broken_missing_account.ini
Normal file
9
tests/samples/config_broken_missing_account.ini
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[DEFAULT]
|
||||||
|
token = <YOUR API TOKEN>
|
||||||
|
budget = <YOUR BUDGET ID>
|
||||||
|
|
||||||
|
[bpvf]
|
||||||
|
account = <YOUR BPVF ACCOUNT ID>
|
||||||
|
|
||||||
|
[ce]
|
||||||
|
account = <YOUR CE ACCOUNT ID>
|
11
tests/samples/config_broken_missing_account_key.ini
Normal file
11
tests/samples/config_broken_missing_account_key.ini
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[DEFAULT]
|
||||||
|
token = <YOUR API TOKEN>
|
||||||
|
budget = <YOUR BUDGET ID>
|
||||||
|
|
||||||
|
[bpvf]
|
||||||
|
account = <YOUR BPVF ACCOUNT ID>
|
||||||
|
|
||||||
|
[revolut]
|
||||||
|
|
||||||
|
[ce]
|
||||||
|
account = <YOUR CE ACCOUNT ID>
|
11
tests/samples/config_broken_missing_budget.ini
Normal file
11
tests/samples/config_broken_missing_budget.ini
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[DEFAULT]
|
||||||
|
token = <YOUR API TOKEN>
|
||||||
|
|
||||||
|
[bpvf]
|
||||||
|
account = <YOUR BPVF ACCOUNT ID>
|
||||||
|
|
||||||
|
[revolut]
|
||||||
|
account = <YOUR REVOLUT ACCOUNT ID>
|
||||||
|
|
||||||
|
[ce]
|
||||||
|
account = <YOUR CE ACCOUNT ID>
|
11
tests/samples/config_broken_missing_token.ini
Normal file
11
tests/samples/config_broken_missing_token.ini
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[DEFAULT]
|
||||||
|
budget = <YOUR BUDGET ID>
|
||||||
|
|
||||||
|
[bpvf]
|
||||||
|
account = <YOUR BPVF ACCOUNT ID>
|
||||||
|
|
||||||
|
[revolut]
|
||||||
|
account = <YOUR REVOLUT ACCOUNT ID>
|
||||||
|
|
||||||
|
[ce]
|
||||||
|
account = <YOUR CE ACCOUNT ID>
|
|
@ -64,12 +64,22 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_DIR", "tests/samples")
|
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_DIR", "tests/samples")
|
||||||
def test_broken_config_file(self, edit):
|
def test_broken_config_file(self, edit):
|
||||||
runner = CliRunner()
|
broken_files = [
|
||||||
result = runner.invoke(self.cli, ["revolut", "tests/samples/revolut.csv"])
|
"config_broken_duplicate_key.ini",
|
||||||
|
"config_broken_missing_account.ini",
|
||||||
expected_filename = "tests/samples/config_broken_duplicate_key.ini"
|
"config_broken_missing_account_key.ini",
|
||||||
self.assertIn("Error while parsing config file", result.output)
|
"config_broken_missing_budget.ini",
|
||||||
edit.assert_called_once_with(filename=expected_filename)
|
"config_broken_missing_token.ini",
|
||||||
|
]
|
||||||
|
for name in broken_files:
|
||||||
|
with mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_FILENAME", name):
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(
|
||||||
|
self.cli, ["revolut", "tests/samples/revolut.csv"]
|
||||||
|
)
|
||||||
|
expected_filename = ynab.get_config_file_name()
|
||||||
|
self.assertIn("Error while parsing config file", result.output)
|
||||||
|
edit.assert_called_with(filename=expected_filename)
|
||||||
|
|
||||||
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_FILENAME", "file.ini")
|
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_FILENAME", "file.ini")
|
||||||
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_DIR", "some/config/folder")
|
@mock.patch("ofx_processor.utils.ynab.DEFAULT_CONFIG_DIR", "some/config/folder")
|
||||||
|
|
Loading…
Reference in a new issue