Use Idempotency-Key header when posting toots
This commit is contained in:
parent
8f93b255ad
commit
025d8dde09
4 changed files with 24 additions and 7 deletions
|
@ -4,6 +4,8 @@ Changelog
|
|||
**0.19.0 (TBA)**
|
||||
|
||||
* Add support for replying to a toot (#6)
|
||||
* Use Idempotency-Key header to prevent multiple toots being posted if request
|
||||
is retried
|
||||
|
||||
**0.18.0 (2018-06-12)**
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
import io
|
||||
import pytest
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from collections import namedtuple
|
||||
from unittest import mock
|
||||
|
||||
from toot import console, User, App, http
|
||||
|
@ -13,6 +15,8 @@ from tests.utils import MockResponse
|
|||
app = App('habunek.com', 'https://habunek.com', 'foo', 'bar')
|
||||
user = User('habunek.com', 'ivan@habunek.com', 'xxx')
|
||||
|
||||
MockUuid = namedtuple("MockUuid", ["hex"])
|
||||
|
||||
|
||||
def uncolorize(text):
|
||||
"""Remove ANSI color sequences from a string"""
|
||||
|
@ -25,8 +29,10 @@ def test_print_usage(capsys):
|
|||
assert "toot - a Mastodon CLI client" in out
|
||||
|
||||
|
||||
@mock.patch('uuid.uuid4')
|
||||
@mock.patch('toot.http.post')
|
||||
def test_post_defaults(mock_post, capsys):
|
||||
def test_post_defaults(mock_post, mock_uuid, capsys):
|
||||
mock_uuid.return_value = MockUuid("rock-on")
|
||||
mock_post.return_value = MockResponse({
|
||||
'url': 'https://habunek.com/@ihabunek/1234567890'
|
||||
})
|
||||
|
@ -40,7 +46,7 @@ def test_post_defaults(mock_post, capsys):
|
|||
'sensitive': False,
|
||||
'spoiler_text': None,
|
||||
'in_reply_to_id': None,
|
||||
})
|
||||
}, headers={"Idempotency-Key": "rock-on"})
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Toot posted' in out
|
||||
|
@ -48,8 +54,10 @@ def test_post_defaults(mock_post, capsys):
|
|||
assert not err
|
||||
|
||||
|
||||
@mock.patch('uuid.uuid4')
|
||||
@mock.patch('toot.http.post')
|
||||
def test_post_with_options(mock_post, capsys):
|
||||
def test_post_with_options(mock_post, mock_uuid, capsys):
|
||||
mock_uuid.return_value = MockUuid("up-the-irons")
|
||||
args = [
|
||||
'Hello world',
|
||||
'--visibility', 'unlisted',
|
||||
|
@ -71,7 +79,7 @@ def test_post_with_options(mock_post, capsys):
|
|||
'sensitive': True,
|
||||
'spoiler_text': "Spoiler!",
|
||||
'in_reply_to_id': 123,
|
||||
})
|
||||
}, headers={"Idempotency-Key": "up-the-irons"})
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Toot posted' in out
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from urllib.parse import urlparse, urlencode, quote
|
||||
|
||||
|
@ -90,6 +91,11 @@ def post_status(
|
|||
Posts a new status.
|
||||
https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#posting-a-new-status
|
||||
"""
|
||||
|
||||
# Idempotency key assures the same status is not posted multiple times
|
||||
# if the request is retried.
|
||||
headers = {"Idempotency-Key": uuid.uuid4().hex}
|
||||
|
||||
return http.post(app, user, '/api/v1/statuses', {
|
||||
'status': status,
|
||||
'media_ids[]': media_ids,
|
||||
|
@ -97,7 +103,7 @@ def post_status(
|
|||
'sensitive': sensitive,
|
||||
'spoiler_text': spoiler_text,
|
||||
'in_reply_to_id': in_reply_to_id,
|
||||
}).json()
|
||||
}, headers=headers).json()
|
||||
|
||||
|
||||
def timeline_home(app, user):
|
||||
|
|
|
@ -58,9 +58,10 @@ def anon_get(url, params=None):
|
|||
return process_response(response)
|
||||
|
||||
|
||||
def post(app, user, url, data=None, files=None, allow_redirects=True):
|
||||
def post(app, user, url, data=None, files=None, allow_redirects=True, headers={}):
|
||||
url = app.base_url + url
|
||||
headers = {"Authorization": "Bearer " + user.access_token}
|
||||
|
||||
headers["Authorization"] = "Bearer " + user.access_token
|
||||
|
||||
request = Request('POST', url, headers, files, data)
|
||||
response = send_request(request, allow_redirects)
|
||||
|
|
Loading…
Reference in a new issue