diff options
| -rw-r--r-- | TODO.md | 29 | ||||
| -rw-r--r-- | tests/unit/test_output.py | 38 |
2 files changed, 67 insertions, 0 deletions
@@ -0,0 +1,29 @@ +# TODO + +Next steps for firefly-cli. Each new command group follows the expandability +rule in CLAUDE.md (module + decorator, import line, unit test, SKILL.md, regen +bash completion). + +## Command groups (deferred, roughly by demand) +- [ ] `budget` — list/status; most-requested next group. +- [ ] `bill` — list and inspect bills. +- [ ] `piggy` — piggy banks. +- [ ] `rule` — rules and rule groups. +- [ ] `recurring` — recurring transactions. +- [ ] `attachment` — list/download transaction attachments. +- [ ] `report` — summary reports (income/expense by period). +- [ ] `currency` — list/manage currencies. + +## Verbs on existing groups +- [ ] `account delete` — currently needs a manual curl DELETE. +- [ ] `tx update` / `tx delete`. + +## Output / UX +- [ ] `--human` column whitelists live in `output.py` `_VIEWS`; extend as new + resource shapes are added (budget, bill, ...). +- [ ] Consider a `--no-color` flag (color is currently TTY-auto only). + +## Infrastructure +- [ ] `--raw` escape hatch for arbitrary API calls. +- [ ] OAuth as an alternative to personal access tokens. +- [ ] zsh / fish completion (bash done). diff --git a/tests/unit/test_output.py b/tests/unit/test_output.py index 5b154d9..2e3e5ea 100644 --- a/tests/unit/test_output.py +++ b/tests/unit/test_output.py @@ -75,3 +75,41 @@ class TestOutput(unittest.TestCase): tty = TTY() emit([tx], human=True, stream=tty) self.assertIn("\033[31m", tty.getvalue()) # tty: withdrawal is red + + def _emit(self, row): + buf = io.StringIO() + emit([row], human=True, stream=buf) + return buf.getvalue() + + def test_view_account_shows_balance_drops_plumbing(self): + # account_role signature -> the account view. + out = self._emit({"id": "6", "name": "BBVA", "type": "asset", + "account_role": "defaultAsset", + "current_balance": "1590.92", "currency_code": "EUR", + "active": True, "iban": "IT68...", "notes": "secret"}) + self.assertIn("BBVA", out) + self.assertIn("1590.92", out) + self.assertIn("currency_code", out) + self.assertNotIn("iban", out) # plumbing column dropped + self.assertNotIn("secret", out) + + def test_view_tag(self): + out = self._emit({"id": "9", "tag": "2026", "description": "yr", + "zoom_level": None, "latitude": None}) + self.assertIn("2026", out) + self.assertIn("description", out) + self.assertNotIn("zoom_level", out) + + def test_view_account_balance(self): + # The balance handler emits id+name+current_balance (no account_role). + out = self._emit({"id": "6", "name": "BBVA", + "current_balance": "1590.92"}) + self.assertIn("current_balance", out) + self.assertIn("1590.92", out) + + def test_view_category_name_only(self): + out = self._emit({"id": "2", "name": "Food", "spent": [], + "primary_currency_code": "EUR", "notes": "junk"}) + self.assertIn("Food", out) + self.assertNotIn("primary_currency_code", out) + self.assertNotIn("spent", out) |
