From c96b4b47e31178347cc3aeab6b4b11a700f6d34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Thu, 9 Jan 2025 15:15:52 +0100 Subject: [PATCH] refactor: use 'dump' command instead of 'get --all' --- CHANGES.rst | 2 +- canaille/backends/commands.py | 42 ++++++++++---------------- doc/references/commands.rst | 6 ++++ tests/app/commands/test_dump.py | 52 +++++++++++++++++++++++++++++++++ tests/app/commands/test_get.py | 48 ------------------------------ 5 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 tests/app/commands/test_dump.py diff --git a/CHANGES.rst b/CHANGES.rst index 3c8be58b..4494712d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Added ^^^^^ - ``--version`` option to the CLI. :pr:`209` - :attr:`~canaille.backends.sql.configuration.SQLSettings.PASSWORD_SCHEMES` :issue:`175` -- `canaille get --all` command option to perform full database dumps +- `canaille dump` command option to perform full database dumps Changed ^^^^^^^ diff --git a/canaille/backends/commands.py b/canaille/backends/commands.py index d376f3f3..c307a087 100644 --- a/canaille/backends/commands.py +++ b/canaille/backends/commands.py @@ -74,6 +74,20 @@ def register(cli): cli.add_command(create_command) cli.add_command(delete_command) cli.add_command(reset_otp) + cli.add_command(dump) + + +@click.command() +@with_appcontext +@with_backendcontext +def dump(): + """Dump all the available models.""" + objects = {} + for model_name, model in MODELS.items(): + objects[model_name] = list(Backend.instance.query(model)) + + output = json.dumps(objects, cls=Backend.instance.json_encoder) + click.echo(output) def get_factory(model): @@ -98,20 +112,8 @@ def get_factory(model): return command -@click.command( - cls=ModelCommand, factory=get_factory, name="get", invoke_without_command=True -) -@click.option( - "--all", - is_flag=True, - show_default=True, - default=False, - help="Dump all the model instances", -) -@click.pass_context -@with_appcontext -@with_backendcontext -def get_command(ctx, all: bool): +@click.command(cls=ModelCommand, factory=get_factory, name="get") +def get_command(): """Read information about models. Options can be used to filter models:: @@ -121,18 +123,6 @@ def get_command(ctx, all: bool): Displays the matching models in JSON format in the standard output. """ - if not all and not ctx.invoked_subcommand: - click.echo(ctx.get_help()) - ctx.exit(0) - - if all: - objects = {} - for model_name, model in MODELS.items(): - objects[model_name] = list(Backend.instance.query(model)) - - output = json.dumps(objects, cls=Backend.instance.json_encoder) - click.echo(output) - def set_factory(model): command_help = f"""Update a {model.__name__.lower()} and display the diff --git a/doc/references/commands.rst b/doc/references/commands.rst index 9c3dd163..d247f248 100644 --- a/doc/references/commands.rst +++ b/doc/references/commands.rst @@ -23,6 +23,12 @@ For the sake of readability, it is omitted in the following examples. :prog: canaille clean :nested: full +.. _cli_dump: + +.. click:: canaille.app.commands:dump + :prog: canaille dump + :nested: full + .. _cli_install: .. click:: canaille.app.commands:install diff --git a/tests/app/commands/test_dump.py b/tests/app/commands/test_dump.py new file mode 100644 index 00000000..0dcc33ec --- /dev/null +++ b/tests/app/commands/test_dump.py @@ -0,0 +1,52 @@ +import json +from unittest import mock + +from canaille.commands import cli + + +def test_dump_stdout(testclient, backend, user, foo_group): + """Test the full database dump command.""" + + runner = testclient.app.test_cli_runner() + res = runner.invoke(cli, ["dump"], catch_exceptions=False) + assert res.exit_code == 0, res.stdout + assert json.loads(res.stdout) == { + "authorizationcode": [], + "client": [], + "consent": [], + "group": [ + { + "created": mock.ANY, + "display_name": "foo", + "id": foo_group.id, + "last_modified": mock.ANY, + "members": [ + user.id, + ], + }, + ], + "token": [], + "user": [ + { + "created": mock.ANY, + "display_name": "Johnny", + "emails": [ + "john@doe.test", + ], + "family_name": "Doe", + "formatted_address": "1235, somewhere", + "formatted_name": "John (johnny) Doe", + "given_name": "John", + "groups": [foo_group.id], + "id": user.id, + "last_modified": mock.ANY, + "password": mock.ANY, + "phone_numbers": [ + "555-000-000", + ], + "preferred_language": "en", + "profile_url": "https://john.test", + "user_name": "user", + }, + ], + } diff --git a/tests/app/commands/test_get.py b/tests/app/commands/test_get.py index 85fb7037..bbd4fe18 100644 --- a/tests/app/commands/test_get.py +++ b/tests/app/commands/test_get.py @@ -122,51 +122,3 @@ def test_get_datetime_filter(testclient, backend, user): "user_name": "user", }, ] - - -def test_get_all(testclient, backend, user, foo_group): - """Test the full database dump command.""" - - runner = testclient.app.test_cli_runner() - res = runner.invoke(cli, ["get", "--all"], catch_exceptions=False) - assert res.exit_code == 0, res.stdout - assert json.loads(res.stdout) == { - "authorizationcode": [], - "client": [], - "consent": [], - "group": [ - { - "created": mock.ANY, - "display_name": "foo", - "id": foo_group.id, - "last_modified": mock.ANY, - "members": [ - user.id, - ], - }, - ], - "token": [], - "user": [ - { - "created": mock.ANY, - "display_name": "Johnny", - "emails": [ - "john@doe.test", - ], - "family_name": "Doe", - "formatted_address": "1235, somewhere", - "formatted_name": "John (johnny) Doe", - "given_name": "John", - "groups": [foo_group.id], - "id": user.id, - "last_modified": mock.ANY, - "password": mock.ANY, - "phone_numbers": [ - "555-000-000", - ], - "preferred_language": "en", - "profile_url": "https://john.test", - "user_name": "user", - }, - ], - }