Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/dualentry_cli/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ def make_resource_app(
resource: str,
path: str,
*,
has_get: bool = True,
has_create: bool = True,
has_update: bool = True,
has_delete: bool = False,
Expand Down Expand Up @@ -254,7 +255,7 @@ def list_cmd(
sig = inspect.signature(list_cmd)
list_cmd.__signature__ = sig.replace(parameters=[p for p in sig.parameters.values() if p.name not in remove])

if has_number:
if has_get and has_number:

@app.command("get")
def get_cmd_auto(
Expand Down Expand Up @@ -308,7 +309,8 @@ def get_cmd_by_id(
format_output(data, resource=resource, fmt=output)

get_cmd_by_id.__doc__ = f"Get a {resource} by ID."
else:

elif has_get and not has_number:

@app.command("get")
def get_cmd(
Expand Down
10 changes: 5 additions & 5 deletions src/dualentry_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@
make_resource_app("fixed assets", "fixed-asset", "fixed-assets", has_number=True, filters={"search", "status", "company", "customer", "vendor"}),
name="fixed-assets",
)
app.add_typer(make_resource_app("depreciation books", "depreciation-book", "depreciation-books", filters=set()), name="depreciation-books")
app.add_typer(make_resource_app("depreciation books", "depreciation-book", "depreciation-books", has_create=False, has_update=False, filters=set()), name="depreciation-books")

# Entities
app.add_typer(make_resource_app("customers", "customer", "customers", filters={"search", "status", "company"}), name="customers")
app.add_typer(make_resource_app("vendors", "vendor", "vendors", filters=TXN), name="vendors")
app.add_typer(make_resource_app("items", "item", "items", filters={"search", "status"}), name="items")
app.add_typer(make_resource_app("companies", "company", "companies", filters={"search"}), name="companies")
app.add_typer(make_resource_app("companies", "company", "companies", has_create=False, has_update=False, filters={"search"}), name="companies")
app.add_typer(make_resource_app("classifications", "classification", "classifications", filters={"search"}), name="classifications")

# Recurring
Expand All @@ -84,7 +84,7 @@
# Other
# Contracts name their status filter `status`, not `record_status`.
app.add_typer(make_resource_app("contracts", "contract", "contracts", filters=TXN_CUSTOMER, status_param="status"), name="contracts")
app.add_typer(make_resource_app("budgets", "budget", "budgets", filters={"search", "status", "company"}), name="budgets")
app.add_typer(make_resource_app("budgets", "budget", "budgets", has_create=False, has_update=False, filters={"search", "status", "company"}), name="budgets")
app.add_typer(
make_resource_app("workflows", "workflow", "workflows", has_create=False, has_update=False, filters={"search", "company"}),
name="workflows",
Expand All @@ -103,8 +103,8 @@
),
name="intercompany-journal-entries",
)
app.add_typer(make_resource_app("paper checks", "paper-check", "paper-checks", has_number=True, filters=TXN_ALL_PARTIES), name="paper-checks")
app.add_typer(make_resource_app("inbox items", "inbox-item", "inbox", has_create=False, has_update=False, filters={"search"}), name="inbox")
app.add_typer(make_resource_app("paper checks", "paper-check", "paper-checks", has_create=False, has_update=False, filters=TXN_ALL_PARTIES), name="paper-checks")
app.add_typer(make_resource_app("inbox items", "inbox-item", "inbox", has_get=False, has_create=False, has_update=False, filters={"search"}), name="inbox")


def version_callback(value: bool):
Expand Down
44 changes: 44 additions & 0 deletions tests/test_stale_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from __future__ import annotations

import pytest

from dualentry_cli.main import app

STALE_COMMANDS = [
("companies", "create"),
("companies", "update"),
("budgets", "create"),
("budgets", "update"),
("depreciation-books", "create"),
("depreciation-books", "update"),
("paper-checks", "create"),
("paper-checks", "update"),
("inbox", "get"),
]


def _commands(resource: str) -> set[str]:
group = next(g for g in app.registered_groups if g.name == resource)
return {c.name for c in group.typer_instance.registered_commands}


@pytest.mark.parametrize(("resource", "command"), STALE_COMMANDS)
def test_stale_command_is_not_registered(resource: str, command: str):
assert command not in _commands(resource), f"'dualentry {resource} {command}' has no v2 route and must not be registered"


@pytest.mark.parametrize("resource", ["companies", "budgets", "depreciation-books", "paper-checks"])
def test_read_only_resource_keeps_its_read_commands(resource: str):
assert _commands(resource) == {"list", "get"}


def test_inbox_keeps_only_list():
assert _commands("inbox") == {"list"}


def test_paper_checks_has_no_number_lookups():
assert not _commands("paper-checks") & {"get-number", "get-id"}


def test_writable_resource_is_untouched():
assert {"create", "update"} <= _commands("invoices")
Loading