From 3dc5d35751c552b61ca7667e5dd9dca0aeed3ddd Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Tue, 28 Nov 2023 14:05:44 +0100 Subject: [PATCH] Migrate account commands --- tests/integration/conftest.py | 8 +- tests/integration/test_accounts.py | 180 +++++++++++++++++++---------- toot/cli/__init__.py | 1 + toot/cli/accounts.py | 159 +++++++++++++++++++++++++ 4 files changed, 281 insertions(+), 67 deletions(-) create mode 100644 toot/cli/accounts.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index dc387ea..2ccdf28 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -126,10 +126,12 @@ def run(app, user, runner): @pytest.fixture -def run_json(run): +def run_json(app, user, runner): def _run_json(command, *params): - out = run(command, *params) - return json.loads(out) + ctx = Context(app, user) + result = runner.invoke(command, params, obj=ctx) + assert result.exit_code == 0 + return json.loads(result.stdout) return _run_json diff --git a/tests/integration/test_accounts.py b/tests/integration/test_accounts.py index 96f8fc3..f13f855 100644 --- a/tests/integration/test_accounts.py +++ b/tests/integration/test_accounts.py @@ -1,22 +1,23 @@ import json -import pytest -from toot import App, User, api +from toot import App, User, api, cli from toot.entities import Account, Relationship, from_dict -pytest.skip("TODO", allow_module_level=True) - - def test_whoami(user: User, run): - out = run("whoami") + result = run(cli.whoami) + assert result.exit_code == 0 + # TODO: test other fields once updating account is supported + out = result.stdout.strip() assert f"@{user.username}" in out def test_whoami_json(user: User, run): - out = run("whoami", "--json") - account = from_dict(Account, json.loads(out)) + result = run(cli.whoami, "--json") + assert result.exit_code == 0 + + account = from_dict(Account, json.loads(result.stdout)) assert account.username == user.username @@ -29,83 +30,95 @@ def test_whois(app: App, friend: User, run): ] for username in variants: - out = run("whois", username) - assert f"@{friend.username}" in out + result = run(cli.whois, username) + assert result.exit_code == 0 + assert f"@{friend.username}" in result.stdout def test_following(app: App, user: User, friend: User, friend_id, run): # Make sure we're not initally following friend api.unfollow(app, user, friend_id) - out = run("following", user.username) - assert out == "" + result = run(cli.following, user.username) + assert result.exit_code == 0 + assert result.stdout.strip() == "" - out = run("follow", friend.username) - assert out == f"✓ You are now following {friend.username}" + result = run(cli.follow, friend.username) + assert result.exit_code == 0 + assert result.stdout.strip() == f"✓ You are now following {friend.username}" - out = run("following", user.username) - assert friend.username in out + result = run(cli.following, user.username) + assert result.exit_code == 0 + assert friend.username in result.stdout.strip() # If no account is given defaults to logged in user - out = run("following") - assert friend.username in out + result = run(cli.following) + assert result.exit_code == 0 + assert friend.username in result.stdout.strip() - out = run("unfollow", friend.username) - assert out == f"✓ You are no longer following {friend.username}" + result = run(cli.unfollow, friend.username) + assert result.exit_code == 0 + assert result.stdout.strip() == f"✓ You are no longer following {friend.username}" - out = run("following", user.username) - assert out == "" + result = run(cli.following, user.username) + assert result.exit_code == 0 + assert result.stdout.strip() == "" def test_following_case_insensitive(user: User, friend: User, run): assert friend.username != friend.username.upper() - out = run("follow", friend.username.upper()) + result = run(cli.follow, friend.username.upper()) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ You are now following {friend.username.upper()}" def test_following_not_found(run): - out = run("follow", "bananaman") - assert out == "Account not found" + result = run(cli.follow, "bananaman") + assert result.exit_code == 1 + assert result.stderr.strip() == "Error: Account not found" - out = run("unfollow", "bananaman") - assert out == "Account not found" + result = run(cli.unfollow, "bananaman") + assert result.exit_code == 1 + assert result.stderr.strip() == "Error: Account not found" def test_following_json(app: App, user: User, friend: User, user_id, friend_id, run_json): # Make sure we're not initally following friend api.unfollow(app, user, friend_id) - result = run_json("following", user.username, "--json") + result = run_json(cli.following, user.username, "--json") assert result == [] - result = run_json("followers", friend.username, "--json") + result = run_json(cli.followers, friend.username, "--json") assert result == [] - result = run_json("follow", friend.username, "--json") + result = run_json(cli.follow, friend.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id assert relationship.following is True - [result] = run_json("following", user.username, "--json") + [result] = run_json(cli.following, user.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id # If no account is given defaults to logged in user - [result] = run_json("following", user.username, "--json") + [result] = run_json(cli.following, user.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id - [result] = run_json("followers", friend.username, "--json") + [result] = run_json(cli.followers, friend.username, "--json") assert result["id"] == user_id - result = run_json("unfollow", friend.username, "--json") + result = run_json(cli.unfollow, friend.username, "--json") assert result["id"] == friend_id assert result["following"] is False - result = run_json("following", user.username, "--json") + result = run_json(cli.following, user.username, "--json") assert result == [] - result = run_json("followers", friend.username, "--json") + result = run_json(cli.followers, friend.username, "--json") assert result == [] @@ -113,57 +126,77 @@ def test_mute(app, user, friend, friend_id, run): # Make sure we're not initially muting friend api.unmute(app, user, friend_id) - out = run("muted") + result = run(cli.muted) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == "No accounts muted" - out = run("mute", friend.username) + result = run(cli.mute, friend.username) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ You have muted {friend.username}" - out = run("muted") + result = run(cli.muted) + assert result.exit_code == 0 + + out = result.stdout.strip() assert friend.username in out - out = run("unmute", friend.username) + result = run(cli.unmute, friend.username) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ {friend.username} is no longer muted" - out = run("muted") + result = run(cli.muted) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == "No accounts muted" def test_mute_case_insensitive(friend: User, run): - out = run("mute", friend.username.upper()) + result = run(cli.mute, friend.username.upper()) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ You have muted {friend.username.upper()}" def test_mute_not_found(run): - out = run("mute", "doesnotexistperson") - assert out == f"Account not found" + result = run(cli.mute, "doesnotexistperson") + assert result.exit_code == 1 + assert result.stderr.strip() == "Error: Account not found" - out = run("unmute", "doesnotexistperson") - assert out == f"Account not found" + result = run(cli.unmute, "doesnotexistperson") + assert result.exit_code == 1 + assert result.stderr.strip() == "Error: Account not found" def test_mute_json(app: App, user: User, friend: User, run_json, friend_id): # Make sure we're not initially muting friend api.unmute(app, user, friend_id) - result = run_json("muted", "--json") + result = run_json(cli.muted, "--json") assert result == [] - result = run_json("mute", friend.username, "--json") + result = run_json(cli.mute, friend.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id assert relationship.muting is True - [result] = run_json("muted", "--json") + [result] = run_json(cli.muted, "--json") account = from_dict(Account, result) assert account.id == friend_id - result = run_json("unmute", friend.username, "--json") + result = run_json(cli.unmute, friend.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id assert relationship.muting is False - result = run_json("muted", "--json") + result = run_json(cli.muted, "--json") assert result == [] @@ -171,52 +204,71 @@ def test_block(app, user, friend, friend_id, run): # Make sure we're not initially blocking friend api.unblock(app, user, friend_id) - out = run("blocked") + result = run(cli.blocked) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == "No accounts blocked" - out = run("block", friend.username) + result = run(cli.block, friend.username) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ You are now blocking {friend.username}" - out = run("blocked") + result = run(cli.blocked) + assert result.exit_code == 0 + + out = result.stdout.strip() assert friend.username in out - out = run("unblock", friend.username) + result = run(cli.unblock, friend.username) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ {friend.username} is no longer blocked" - out = run("blocked") + result = run(cli.blocked) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == "No accounts blocked" def test_block_case_insensitive(friend: User, run): - out = run("block", friend.username.upper()) + result = run(cli.block, friend.username.upper()) + assert result.exit_code == 0 + + out = result.stdout.strip() assert out == f"✓ You are now blocking {friend.username.upper()}" def test_block_not_found(run): - out = run("block", "doesnotexistperson") - assert out == f"Account not found" + result = run(cli.block, "doesnotexistperson") + assert result.exit_code == 1 + assert result.stderr.strip() == "Error: Account not found" def test_block_json(app: App, user: User, friend: User, run_json, friend_id): # Make sure we're not initially blocking friend api.unblock(app, user, friend_id) - result = run_json("blocked", "--json") + result = run_json(cli.blocked, "--json") assert result == [] - result = run_json("block", friend.username, "--json") + result = run_json(cli.block, friend.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id assert relationship.blocking is True - [result] = run_json("blocked", "--json") + [result] = run_json(cli.blocked, "--json") account = from_dict(Account, result) assert account.id == friend_id - result = run_json("unblock", friend.username, "--json") + result = run_json(cli.unblock, friend.username, "--json") relationship = from_dict(Relationship, result) assert relationship.id == friend_id assert relationship.blocking is False - result = run_json("blocked", "--json") + result = run_json(cli.blocked, "--json") assert result == [] diff --git a/toot/cli/__init__.py b/toot/cli/__init__.py index d45892e..2e9efcf 100644 --- a/toot/cli/__init__.py +++ b/toot/cli/__init__.py @@ -1,5 +1,6 @@ from toot.cli.base import cli, Context # noqa +from toot.cli.accounts import * from toot.cli.post import * from toot.cli.read import * from toot.cli.statuses import * diff --git a/toot/cli/accounts.py b/toot/cli/accounts.py new file mode 100644 index 0000000..5bed310 --- /dev/null +++ b/toot/cli/accounts.py @@ -0,0 +1,159 @@ +import click +import json as pyjson + +from typing import Optional + +from toot import api +from toot.cli.base import cli, json_option, Context, pass_context +from toot.output import print_acct_list + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def follow(ctx: Context, account: str, json: bool): + """Follow an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.follow(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ You are now following {account}", fg="green") + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def unfollow(ctx: Context, account: str, json: bool): + """Unfollow an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.unfollow(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ You are no longer following {account}", fg="green") + + +@cli.command() +@click.argument("account", required=False) +@json_option +@pass_context +def following(ctx: Context, account: Optional[str], json: bool): + """List accounts followed by an account. + + If no account is given list accounts followed by you. + """ + account = account or ctx.user.username + found_account = api.find_account(ctx.app, ctx.user, account) + accounts = api.following(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(pyjson.dumps(accounts)) + else: + print_acct_list(accounts) + + +@cli.command() +@click.argument("account", required=False) +@json_option +@pass_context +def followers(ctx: Context, account: Optional[str], json: bool): + """List accounts following an account. + + If no account given list accounts following you.""" + account = account or ctx.user.username + found_account = api.find_account(ctx.app, ctx.user, account) + accounts = api.followers(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(pyjson.dumps(accounts)) + else: + print_acct_list(accounts) + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def mute(ctx: Context, account: str, json: bool): + """Mute an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.mute(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ You have muted {account}", fg="green") + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def unmute(ctx: Context, account: str, json: bool): + """Unmute an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.unmute(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ {account} is no longer muted", fg="green") + + +@cli.command() +@json_option +@pass_context +def muted(ctx: Context, json: bool): + """List muted accounts""" + response = api.muted(ctx.app, ctx.user) + if json: + click.echo(pyjson.dumps(response)) + else: + if len(response) > 0: + click.echo("Muted accounts:") + print_acct_list(response) + else: + click.echo("No accounts muted") + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def block(ctx: Context, account: str, json: bool): + """Block an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.block(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ You are now blocking {account}", fg="green") + + +@cli.command() +@click.argument("account") +@json_option +@pass_context +def unblock(ctx: Context, account: str, json: bool): + """Unblock an account""" + found_account = api.find_account(ctx.app, ctx.user, account) + response = api.unblock(ctx.app, ctx.user, found_account["id"]) + if json: + click.echo(response.text) + else: + click.secho(f"✓ {account} is no longer blocked", fg="green") + + +@cli.command() +@json_option +@pass_context +def blocked(ctx: Context, json: bool): + """List blocked accounts""" + response = api.blocked(ctx.app, ctx.user) + if json: + click.echo(pyjson.dumps(response)) + else: + if len(response) > 0: + click.echo("Blocked accounts:") + print_acct_list(response) + else: + click.echo("No accounts blocked")