Skip to content

Commit

Permalink
feat(cli): define the agency list command
Browse files Browse the repository at this point in the history
    benefits agency list -h
  • Loading branch information
thekaveman committed Oct 31, 2024
1 parent 78127a4 commit bf19d3d
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 3 deletions.
Empty file added benefits/cli/agency/__init__.py
Empty file.
73 changes: 73 additions & 0 deletions benefits/cli/agency/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from dataclasses import dataclass

from django.db.models import Q

from benefits.cli.commands import BaseOptions, BenefitsCommand
from benefits.core.models import TransitAgency


@dataclass
class Options(BaseOptions):
all: bool = False
name: str = None
slug: str = None


class List(BenefitsCommand):
"""List transit agencies."""

help = __doc__
name = "list"
options_cls = Options

def add_arguments(self, parser):
parser.add_argument(
"-a",
"--all",
action="store_true",
default=False,
help="Show both active and inactive agencies. By default show only active agencies.",
)
parser.add_argument(
"-n",
"--name",
type=str,
help="Filter for agencies with matching (partial) short_name or long_name.",
)
parser.add_argument(
"-s",
"--slug",
type=str,
help="Filter for agencies with matching (partial) slug.",
)

def handle(self, *args, **options):
opts = self.parse_opts(**options)
agencies = TransitAgency.objects.all()

if not opts.all:
agencies = agencies.filter(active=True)

if opts.name:
q = Q(short_name__contains=opts.name) | Q(long_name__contains=opts.name)
agencies = agencies.filter(q)

if opts.slug:
agencies = agencies.filter(slug__contains=opts.slug)

if len(agencies) > 0:
if len(agencies) > 1:
msg = f"{len(agencies)} agencies:"
else:
msg = "1 agency:"
self.stdout.write(self.style.SUCCESS(msg))

active = filter(lambda a: a.active, agencies)
inactive = filter(lambda a: not a.active, agencies)

for agency in active:
self.stdout.write(self.style.HTTP_NOT_MODIFIED(f"{agency}"))
for agency in inactive:
self.stdout.write(self.style.WARNING(f"[inactive] {agency}"))
else:
self.stdout.write(self.style.HTTP_NOT_FOUND("No matching agencies"))
6 changes: 4 additions & 2 deletions benefits/cli/management/commands/agency.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from benefits.cli.agency.list import List
from benefits.cli.commands import BenefitsCommand


Expand All @@ -6,7 +7,8 @@ class Command(BenefitsCommand):

help = __doc__
name = "agency"
subcommands = []
subcommands = [List]

def __init__(self, stdout=None, stderr=None, no_color=False, force_color=False):
super().__init__(stdout, stderr, no_color, force_color)
# make List the default_subcmd
super().__init__(stdout, stderr, no_color, force_color, List)
Empty file.
68 changes: 68 additions & 0 deletions tests/pytest/cli/agency/test_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import pytest

from benefits.cli.agency.list import List


@pytest.fixture
def cmd(cmd):
def call(*args, **kwargs):
return cmd(List, *args, **kwargs)

return call


@pytest.mark.django_db
def test_list(cmd):
out, err = cmd()

assert err == ""
assert "No matching agencies" in out


@pytest.mark.django_db
def test_list_agency(cmd, model_TransitAgency):
out, err = cmd()

assert err == ""
assert "1 agency" in out
assert str(model_TransitAgency) in out


@pytest.mark.django_db
def test_list_agencies(cmd, model_TransitAgency):
orig_agency = str(model_TransitAgency)

model_TransitAgency.pk = None
model_TransitAgency.long_name = "Another agency"
model_TransitAgency.save()

out, err = cmd()

assert err == ""
assert "2 agencies" in out
assert orig_agency in out
assert str(model_TransitAgency) in out


@pytest.mark.django_db
def test_list_agencies_active(cmd, model_TransitAgency):
orig_agency = str(model_TransitAgency)

model_TransitAgency.pk = None
model_TransitAgency.long_name = "Another agency"
model_TransitAgency.active = False
model_TransitAgency.save()

out, err = cmd()

assert err == ""
assert "1 agency" in out
assert orig_agency in out
assert str(model_TransitAgency) not in out

out, err = cmd("--all")

assert err == ""
assert "2 agencies" in out
assert orig_agency in out
assert f"[inactive] {model_TransitAgency}" in out
12 changes: 12 additions & 0 deletions tests/pytest/cli/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest

from django.core.management import call_command


@pytest.fixture
def cmd(capfd):
def call(cls, *args, **kwargs):
call_command(cls(), *args, **kwargs)
return capfd.readouterr()

return call
7 changes: 6 additions & 1 deletion tests/pytest/cli/management/commands/test_agency.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import pytest

from benefits.cli.agency.list import List
from benefits.cli.management.commands.agency import Command


@pytest.mark.django_db
def test_class():
assert Command.help == Command.__doc__
assert Command.name == "agency"
assert Command.subcommands == []
assert Command.subcommands == [List]


@pytest.mark.django_db
Expand All @@ -16,3 +17,7 @@ def test_init():

assert "agency" in cmd.subparsers
assert cmd.subparser == cmd.subparsers["agency"]

list_cmd = getattr(cmd, "list")
assert isinstance(list_cmd, List)
assert cmd.default_handler == list_cmd.handle

0 comments on commit bf19d3d

Please sign in to comment.