diff --git a/tests/integration/test_status.py b/tests/integration/test_status.py
index 61f8e91..3daf65e 100644
--- a/tests/integration/test_status.py
+++ b/tests/integration/test_status.py
@@ -1,3 +1,4 @@
+import json
import time
import pytest
@@ -5,7 +6,7 @@ from toot import api
from toot.exceptions import NotFoundError
-def test_delete_status(app, user, run):
+def test_delete(app, user, run):
status = api.post_status(app, user, "foo").json()
out = run("delete", status["id"])
@@ -15,6 +16,17 @@ def test_delete_status(app, user, run):
api.fetch_status(app, user, status["id"])
+def test_delete_json(app, user, run):
+ status = api.post_status(app, user, "foo").json()
+
+ out = run("delete", status["id"], "--json")
+ result = json.loads(out)
+ assert result["id"] == status["id"]
+
+ with pytest.raises(NotFoundError):
+ api.fetch_status(app, user, status["id"])
+
+
def test_favourite(app, user, run):
status = api.post_status(app, user, "foo").json()
assert not status["favourited"]
@@ -35,6 +47,23 @@ def test_favourite(app, user, run):
assert not status["favourited"]
+def test_favourite_json(app, user, run):
+ status = api.post_status(app, user, "foo").json()
+ assert not status["favourited"]
+
+ out = run("favourite", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["id"] == status["id"]
+ assert result["favourited"] is True
+
+ out = run("unfavourite", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["id"] == status["id"]
+ assert result["favourited"] is False
+
+
def test_reblog(app, user, run):
status = api.post_status(app, user, "foo").json()
assert not status["reblogged"]
@@ -55,6 +84,27 @@ def test_reblog(app, user, run):
assert not status["reblogged"]
+def test_reblog_json(app, user, run):
+ status = api.post_status(app, user, "foo").json()
+ assert not status["reblogged"]
+
+ out = run("reblog", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["reblogged"] is True
+ assert result["reblog"]["id"] == status["id"]
+
+ out = run("reblogged_by", status["id"], "--json")
+ [reblog] = json.loads(out)
+ assert reblog["acct"] == user.username
+
+ out = run("unreblog", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["reblogged"] is False
+ assert result["reblog"] is None
+
+
def test_pin(app, user, run):
status = api.post_status(app, user, "foo").json()
assert not status["pinned"]
@@ -72,6 +122,23 @@ def test_pin(app, user, run):
assert not status["pinned"]
+def test_pin_json(app, user, run):
+ status = api.post_status(app, user, "foo").json()
+ assert not status["pinned"]
+
+ out = run("pin", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["pinned"] is True
+ assert result["id"] == status["id"]
+
+ out = run("unpin", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["pinned"] is False
+ assert result["id"] == status["id"]
+
+
def test_bookmark(app, user, run):
status = api.post_status(app, user, "foo").json()
assert not status["bookmarked"]
@@ -87,3 +154,20 @@ def test_bookmark(app, user, run):
status = api.fetch_status(app, user, status["id"]).json()
assert not status["bookmarked"]
+
+
+def test_bookmark_json(app, user, run):
+ status = api.post_status(app, user, "foo").json()
+ assert not status["bookmarked"]
+
+ out = run("bookmark", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["id"] == status["id"]
+ assert result["bookmarked"] is True
+
+ out = run("unbookmark", status["id"], "--json")
+ result = json.loads(out)
+
+ assert result["id"] == status["id"]
+ assert result["bookmarked"] is False
diff --git a/tests/test_console.py b/tests/test_console.py
index 72a114b..d9859df 100644
--- a/tests/test_console.py
+++ b/tests/test_console.py
@@ -196,36 +196,6 @@ def test_timeline_with_re(mock_get, monkeypatch, capsys):
assert err == ""
-@mock.patch('toot.http.get')
-def test_reblogged_by(mock_get, monkeypatch, capsys):
- mock_get.return_value = MockResponse([{
- 'display_name': 'Terry Bozzio',
- 'acct': 'bozzio@drummers.social',
- }, {
- 'display_name': 'Dweezil',
- 'acct': 'dweezil@zappafamily.social',
- }])
-
- console.run_command(app, user, 'reblogged_by', ['111111111111111111'])
-
- calls = [
- mock.call(app, user, '/api/v1/statuses/111111111111111111/reblogged_by'),
- ]
- mock_get.assert_has_calls(calls, any_order=False)
-
- out, err = capsys.readouterr()
-
- # Display order
- expected = "\n".join([
- "Terry Bozzio",
- " @bozzio@drummers.social",
- "Dweezil",
- " @dweezil@zappafamily.social",
- "",
- ])
- assert out == expected
-
-
@mock.patch('toot.http.post')
def test_upload(mock_post, capsys):
mock_post.return_value = MockResponse({
diff --git a/toot/api.py b/toot/api.py
index 829e53d..2158b13 100644
--- a/toot/api.py
+++ b/toot/api.py
@@ -43,9 +43,9 @@ def _account_action(app, user, account, action):
return http.post(app, user, url).json()
-def _status_action(app, user, status_id, action, data=None):
+def _status_action(app, user, status_id, action, data=None) -> Response:
url = f"/api/v1/statuses/{status_id}/{action}"
- return http.post(app, user, url, data=data).json()
+ return http.post(app, user, url, data=data)
def _tag_action(app, user, tag_name, action):
@@ -301,9 +301,9 @@ def context(app, user, status_id) -> Response:
return http.get(app, user, url)
-def reblogged_by(app, user, status_id):
+def reblogged_by(app, user, status_id) -> Response:
url = f"/api/v1/statuses/{status_id}/reblogged_by"
- return http.get(app, user, url).json()
+ return http.get(app, user, url)
def _get_next_path(headers):
diff --git a/toot/commands.py b/toot/commands.py
index c2b3d43..285258b 100644
--- a/toot/commands.py
+++ b/toot/commands.py
@@ -10,7 +10,7 @@ from toot.auth import login_interactive, login_browser_interactive, create_app_i
from toot.entities import Account, Instance, Notification, Status, from_dict
from toot.exceptions import ApiError, ConsoleError
from toot.output import (print_lists, print_out, print_instance, print_account, print_acct_list,
- print_search_results, print_status, print_timeline, print_notifications, print_tag_list,
+ print_search_results, print_status, print_table, print_timeline, print_notifications, print_tag_list,
print_list_accounts, print_user_list)
from toot.utils import args_get_instance, delete_tmp_status_file, editor_input, multiline_input, EOF_KEY
from toot.utils.datetime import parse_datetime
@@ -212,48 +212,75 @@ def _wait_until_processed(app, user, media, start_time, timeout):
def delete(app, user, args):
- api.delete_status(app, user, args.status_id)
- print_out("✓ Status deleted")
+ response = api.delete_status(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status deleted")
def favourite(app, user, args):
- api.favourite(app, user, args.status_id)
- print_out("✓ Status favourited")
+ response = api.favourite(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status favourited")
def unfavourite(app, user, args):
- api.unfavourite(app, user, args.status_id)
- print_out("✓ Status unfavourited")
+ response = api.unfavourite(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status unfavourited")
def reblog(app, user, args):
- api.reblog(app, user, args.status_id, visibility=args.visibility)
- print_out("✓ Status reblogged")
+ response = api.reblog(app, user, args.status_id, visibility=args.visibility)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status reblogged")
def unreblog(app, user, args):
- api.unreblog(app, user, args.status_id)
- print_out("✓ Status unreblogged")
+ response = api.unreblog(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status unreblogged")
def pin(app, user, args):
- api.pin(app, user, args.status_id)
- print_out("✓ Status pinned")
+ response = api.pin(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status pinned")
def unpin(app, user, args):
- api.unpin(app, user, args.status_id)
- print_out("✓ Status unpinned")
+ response = api.unpin(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status unpinned")
def bookmark(app, user, args):
- api.bookmark(app, user, args.status_id)
- print_out("✓ Status bookmarked")
+ response = api.bookmark(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status bookmarked")
def unbookmark(app, user, args):
- api.unbookmark(app, user, args.status_id)
- print_out("✓ Status unbookmarked")
+ response = api.unbookmark(app, user, args.status_id)
+ if args.json:
+ print(response.text)
+ else:
+ print_out("✓ Status unbookmarked")
def bookmarks(app, user, args):
@@ -261,8 +288,14 @@ def bookmarks(app, user, args):
def reblogged_by(app, user, args):
- for account in api.reblogged_by(app, user, args.status_id):
- print_out("{}\n @{}".format(account['display_name'], account['acct']))
+ response = api.reblogged_by(app, user, args.status_id)
+
+ if args.json:
+ print(response.text)
+ else:
+ headers = ["Account", "Display name"]
+ rows = [[a["acct"], a["display_name"]] for a in response.json()]
+ print_table(headers, rows)
def auth(app, user, args):
diff --git a/toot/console.py b/toot/console.py
index 1916941..9f74557 100644
--- a/toot/console.py
+++ b/toot/console.py
@@ -608,61 +608,61 @@ STATUS_COMMANDS = [
Command(
name="delete",
description="Delete a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="favourite",
description="Favourite a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="unfavourite",
description="Unfavourite a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="reblog",
description="Reblog a status",
- arguments=[status_id_arg, visibility_arg],
+ arguments=[status_id_arg, visibility_arg, json_arg],
require_auth=True,
),
Command(
name="unreblog",
description="Unreblog a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="reblogged_by",
description="Show accounts that reblogged the status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=False,
),
Command(
name="pin",
description="Pin a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="unpin",
description="Unpin a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="bookmark",
description="Bookmark a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
Command(
name="unbookmark",
description="Unbookmark a status",
- arguments=[status_id_arg],
+ arguments=[status_id_arg, json_arg],
require_auth=True,
),
]