diff options
author | Lorenz Diener <[email protected]> | 2019-04-28 23:12:27 +0200 |
---|---|---|
committer | Lorenz Diener <[email protected]> | 2019-04-28 23:12:27 +0200 |
commit | 09c03296db1671e80f5e7814045e826f1975fb0b (patch) | |
tree | 87e709b3b2b5aa86909bee4db89a04c0340d3d0d | |
parent | 3eba3f8835f25800f37b9da18a09429b084effa0 (diff) | |
download | mastodon.py-09c03296db1671e80f5e7814045e826f1975fb0b.tar.gz |
Polls
-rw-r--r-- | docs/index.rst | 41 | ||||
-rw-r--r-- | mastodon/Mastodon.py | 97 | ||||
-rw-r--r-- | tests/cassettes/test_poll_illegal_vote.yaml | 96 | ||||
-rw-r--r-- | tests/cassettes/test_polls.yaml | 184 |
4 files changed, 401 insertions, 17 deletions
diff --git a/docs/index.rst b/docs/index.rst index a98eb23..6e798d7 100644 --- a/docs/index.rst +++ b/docs/index.rst | |||
@@ -314,6 +314,7 @@ Toot dicts | |||
314 | 'replies_count': # The number of replies to this status. | 314 | 'replies_count': # The number of replies to this status. |
315 | 'card': # A preview card for links from the status, if present at time of delivery, | 315 | 'card': # A preview card for links from the status, if present at time of delivery, |
316 | # as card dict. | 316 | # as card dict. |
317 | 'poll': # A poll dict if a poll is attached to this status. | ||
317 | } | 318 | } |
318 | 319 | ||
319 | Mention dicts | 320 | Mention dicts |
@@ -355,7 +356,29 @@ Scheduled toot dicts | |||
355 | }, | 356 | }, |
356 | 'media_attachments': # Array of media dicts for the attachments to the scheduled toot | 357 | 'media_attachments': # Array of media dicts for the attachments to the scheduled toot |
357 | } | 358 | } |
358 | 359 | ||
360 | Poll dicts | ||
361 | ~~~~~~~~~~ | ||
362 | .. _poll dict: | ||
363 | |||
364 | .. code-block:: python | ||
365 | |||
366 | # Returns the following dictionary: | ||
367 | mastodon.poll(id) | ||
368 | { | ||
369 | 'id': # The polls ID | ||
370 | 'expires_at': # The time at which the poll is set to expire | ||
371 | 'expired': # Boolean denoting whether you can still vote in this poll | ||
372 | 'multiple': # Boolean indicating whether it is allowed to vote for more than one option | ||
373 | 'votes_count': # Total number of votes cast in this poll | ||
374 | 'voted': # Boolean indicating whether the logged-in user has already voted in this poll | ||
375 | 'options': # The poll options as a list of dicts, each option with a `title` and a | ||
376 | # `votes_count` field. `votes_count` can be None if the poll creator has | ||
377 | # chosen to hide vote totals until the poll expires and it hasn't yet. | ||
378 | 'emojis': # List of emoji dicts for all emoji used in answer strings | ||
379 | } | ||
380 | |||
381 | |||
359 | Conversation dicts | 382 | Conversation dicts |
360 | ~~~~~~~~~~~~~~~~~~ | 383 | ~~~~~~~~~~~~~~~~~~ |
361 | .. _conversation dict: | 384 | .. _conversation dict: |
@@ -797,13 +820,19 @@ These functions allow you to get information about single statuses. | |||
797 | .. automethod:: Mastodon.status_favourited_by | 820 | .. automethod:: Mastodon.status_favourited_by |
798 | .. automethod:: Mastodon.status_card | 821 | .. automethod:: Mastodon.status_card |
799 | 822 | ||
800 | Writing data: Scheduled statuses | 823 | Reading data: Scheduled statuses |
801 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 824 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
802 | These functions allow you to get information about scheduled statuses. | 825 | These functions allow you to get information about scheduled statuses. |
803 | 826 | ||
804 | .. automethod:: Mastodon.scheduled_statuses | 827 | .. automethod:: Mastodon.scheduled_statuses |
805 | .. automethod:: Mastodon.scheduled_status | 828 | .. automethod:: Mastodon.scheduled_status |
806 | 829 | ||
830 | Reading data: Polls | ||
831 | ~~~~~~~~~~~~~~~~~~~ | ||
832 | This function allows you to get and refresh information about polls. | ||
833 | |||
834 | .. automethod:: Mastodon.poll | ||
835 | |||
807 | Reading data: Notifications | 836 | Reading data: Notifications |
808 | --------------------------- | 837 | --------------------------- |
809 | This function allows you to get information about a users notifications. | 838 | This function allows you to get information about a users notifications. |
@@ -913,6 +942,8 @@ interact with already posted statuses. | |||
913 | .. automethod:: Mastodon.status_post | 942 | .. automethod:: Mastodon.status_post |
914 | .. automethod:: Mastodon.status_reply | 943 | .. automethod:: Mastodon.status_reply |
915 | .. automethod:: Mastodon.toot | 944 | .. automethod:: Mastodon.toot |
945 | .. _make_poll(): | ||
946 | .. automethod:: Mastodon.make_poll | ||
916 | .. automethod:: Mastodon.status_reblog | 947 | .. automethod:: Mastodon.status_reblog |
917 | .. automethod:: Mastodon.status_unreblog | 948 | .. automethod:: Mastodon.status_unreblog |
918 | .. automethod:: Mastodon.status_favourite | 949 | .. automethod:: Mastodon.status_favourite |
@@ -932,6 +963,12 @@ scheduled statuses. | |||
932 | .. automethod:: Mastodon.scheduled_status_update | 963 | .. automethod:: Mastodon.scheduled_status_update |
933 | .. automethod:: Mastodon.scheduled_status_delete | 964 | .. automethod:: Mastodon.scheduled_status_delete |
934 | 965 | ||
966 | Writing data: Polls | ||
967 | ~~~~~~~~~~~~~~~~~~~ | ||
968 | This function allows you to vote in polls. | ||
969 | |||
970 | .. automethod:: Mastodon.poll_vote | ||
971 | |||
935 | Writing data: Notifications | 972 | Writing data: Notifications |
936 | --------------------------- | 973 | --------------------------- |
937 | These functions allow you to clear all or some notifications. | 974 | These functions allow you to clear all or some notifications. |
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index 6b3de9a..27acbaa 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py | |||
@@ -161,8 +161,9 @@ class Mastodon: | |||
161 | __DICT_VERSION_MENTION = "1.0.0" | 161 | __DICT_VERSION_MENTION = "1.0.0" |
162 | __DICT_VERSION_MEDIA = "2.3.0" | 162 | __DICT_VERSION_MEDIA = "2.3.0" |
163 | __DICT_VERSION_ACCOUNT = "2.4.0" | 163 | __DICT_VERSION_ACCOUNT = "2.4.0" |
164 | __DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version("2.5.0", | 164 | __DICT_VERSION_POLL = "2.8.0" |
165 | __DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION) | 165 | __DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version(bigger_version("2.8.0", |
166 | __DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION), __DICT_VERSION_POLL) | ||
166 | __DICT_VERSION_INSTANCE = bigger_version("2.7.2", __DICT_VERSION_ACCOUNT) | 167 | __DICT_VERSION_INSTANCE = bigger_version("2.7.2", __DICT_VERSION_ACCOUNT) |
167 | __DICT_VERSION_HASHTAG = "2.3.4" | 168 | __DICT_VERSION_HASHTAG = "2.3.4" |
168 | __DICT_VERSION_EMOJI = "2.1.0" | 169 | __DICT_VERSION_EMOJI = "2.1.0" |
@@ -827,6 +828,20 @@ class Mastodon: | |||
827 | return self.__api_request('GET', url) | 828 | return self.__api_request('GET', url) |
828 | 829 | ||
829 | ### | 830 | ### |
831 | # Reading data: Polls | ||
832 | ### | ||
833 | @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL) | ||
834 | def poll(self, id): | ||
835 | """ | ||
836 | Fetch information about the poll with the given id | ||
837 | |||
838 | Returns a `poll dict`_. | ||
839 | """ | ||
840 | id = self.__unpack_id(id) | ||
841 | url = '/api/v1/polls/{0}'.format(str(id)) | ||
842 | return self.__api_request('GET', url) | ||
843 | |||
844 | ### | ||
830 | # Reading data: Notifications | 845 | # Reading data: Notifications |
831 | ### | 846 | ### |
832 | @api_version("1.0.0", "2.6.0", __DICT_VERSION_NOTIFICATION) | 847 | @api_version("1.0.0", "2.6.0", __DICT_VERSION_NOTIFICATION) |
@@ -1367,11 +1382,11 @@ class Mastodon: | |||
1367 | ### | 1382 | ### |
1368 | # Writing data: Statuses | 1383 | # Writing data: Statuses |
1369 | ### | 1384 | ### |
1370 | @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) | 1385 | @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS) |
1371 | def status_post(self, status, in_reply_to_id=None, media_ids=None, | 1386 | def status_post(self, status, in_reply_to_id=None, media_ids=None, |
1372 | sensitive=False, visibility=None, spoiler_text=None, | 1387 | sensitive=False, visibility=None, spoiler_text=None, |
1373 | language=None, idempotency_key=None, content_type=None, | 1388 | language=None, idempotency_key=None, content_type=None, |
1374 | scheduled_at=None): | 1389 | scheduled_at=None, poll=None): |
1375 | """ | 1390 | """ |
1376 | Post a status. Can optionally be in reply to another status and contain | 1391 | Post a status. Can optionally be in reply to another status and contain |
1377 | media. | 1392 | media. |
@@ -1412,6 +1427,9 @@ class Mastodon: | |||
1412 | (the time must be at least 5 minutes into the future). If this is passed, | 1427 | (the time must be at least 5 minutes into the future). If this is passed, |
1413 | status_post returns a `scheduled toot dict`_ instead. | 1428 | status_post returns a `scheduled toot dict`_ instead. |
1414 | 1429 | ||
1430 | Pass `poll` to attach a poll to the status. An appropriate object can be | ||
1431 | constructed using `make_poll()`_ | ||
1432 | |||
1415 | Specify `content_type` to set the content type of your post on Pleroma. | 1433 | Specify `content_type` to set the content type of your post on Pleroma. |
1416 | It accepts 'text/plain' (default), 'text/markdown', and 'text/html'. | 1434 | It accepts 'text/plain' (default), 'text/markdown', and 'text/html'. |
1417 | This parameter is not supported on Mastodon servers, but will be | 1435 | This parameter is not supported on Mastodon servers, but will be |
@@ -1466,10 +1484,14 @@ class Mastodon: | |||
1466 | if params_initial['content_type'] == None: | 1484 | if params_initial['content_type'] == None: |
1467 | del params_initial['content_type'] | 1485 | del params_initial['content_type'] |
1468 | 1486 | ||
1487 | use_json = False | ||
1488 | if not poll is None: | ||
1489 | use_json = True | ||
1490 | |||
1469 | params = self.__generate_params(params_initial, ['idempotency_key']) | 1491 | params = self.__generate_params(params_initial, ['idempotency_key']) |
1470 | return self.__api_request('POST', '/api/v1/statuses', params, headers = headers) | 1492 | return self.__api_request('POST', '/api/v1/statuses', params, headers = headers, use_json = use_json) |
1471 | 1493 | ||
1472 | @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) | 1494 | @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS) |
1473 | def toot(self, status): | 1495 | def toot(self, status): |
1474 | """ | 1496 | """ |
1475 | Synonym for `status_post()`_ that only takes the status text as input. | 1497 | Synonym for `status_post()`_ that only takes the status text as input. |
@@ -1480,10 +1502,10 @@ class Mastodon: | |||
1480 | """ | 1502 | """ |
1481 | return self.status_post(status) | 1503 | return self.status_post(status) |
1482 | 1504 | ||
1483 | @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) | 1505 | @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS) |
1484 | def status_reply(self, to_status, status, media_ids=None, sensitive=False, visibility=None, | 1506 | def status_reply(self, to_status, status, media_ids=None, sensitive=False, visibility=None, |
1485 | spoiler_text=None, language=None, idempotency_key=None, content_type=None, | 1507 | spoiler_text=None, language=None, idempotency_key=None, content_type=None, |
1486 | scheduled_at=None, untag=False): | 1508 | scheduled_at=None, poll=None, untag=False): |
1487 | """ | 1509 | """ |
1488 | Helper function - acts like status_post, but prepends the name of all | 1510 | Helper function - acts like status_post, but prepends the name of all |
1489 | the users that are being replied to to the status text and retains | 1511 | the users that are being replied to to the status text and retains |
@@ -1516,8 +1538,22 @@ class Mastodon: | |||
1516 | return self.status_post(status, in_reply_to_id = to_status.id, media_ids = media_ids, sensitive = sensitive, | 1538 | return self.status_post(status, in_reply_to_id = to_status.id, media_ids = media_ids, sensitive = sensitive, |
1517 | visibility = visibility, spoiler_text = spoiler_text, language = language, | 1539 | visibility = visibility, spoiler_text = spoiler_text, language = language, |
1518 | idempotency_key = idempotency_key, content_type = content_type, | 1540 | idempotency_key = idempotency_key, content_type = content_type, |
1519 | scheduled_at = scheduled_at) | 1541 | scheduled_at = scheduled_at, poll = poll) |
1520 | 1542 | ||
1543 | @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL) | ||
1544 | def make_poll(self, options, expires_in, multiple=False, hide_totals=False): | ||
1545 | """ | ||
1546 | Generate a poll object that can be passed as the `poll` option when posting a status. | ||
1547 | |||
1548 | options is an array of strings with the poll options (Maximum, by default: 4), | ||
1549 | expires_in is the time in seconds for which the poll should be open. | ||
1550 | Set multiple to True to allow people to choose more than one answer. Set | ||
1551 | hide_totals to True to hide the results of the poll until it has expired. | ||
1552 | """ | ||
1553 | poll_params = locals() | ||
1554 | del poll_params["self"] | ||
1555 | return poll_params | ||
1556 | |||
1521 | @api_version("1.0.0", "1.0.0", "1.0.0") | 1557 | @api_version("1.0.0", "1.0.0", "1.0.0") |
1522 | def status_delete(self, id): | 1558 | def status_delete(self, id): |
1523 | """ | 1559 | """ |
@@ -1654,6 +1690,34 @@ class Mastodon: | |||
1654 | self.__api_request('DELETE', url) | 1690 | self.__api_request('DELETE', url) |
1655 | 1691 | ||
1656 | ### | 1692 | ### |
1693 | # Writing data: Polls | ||
1694 | ### | ||
1695 | @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL) | ||
1696 | def poll_vote(self, id, choices): | ||
1697 | """ | ||
1698 | Vote in the given poll. | ||
1699 | |||
1700 | `choices` is the index of the choice you wish to register a vote for | ||
1701 | (i.e. its index in the corresponding polls `options` field. In case | ||
1702 | of a poll that allows selection of more than one option, a list of | ||
1703 | indices can be passed. | ||
1704 | |||
1705 | You can only submit choices for any given poll once in case of | ||
1706 | single-option polls, or only once per option in case of multi-option | ||
1707 | polls. | ||
1708 | |||
1709 | Returns the updated `poll dict`_ | ||
1710 | """ | ||
1711 | id = self.__unpack_id(id) | ||
1712 | if not isinstance(choices, list): | ||
1713 | choices = [choices] | ||
1714 | params = self.__generate_params(locals(), ['id']) | ||
1715 | |||
1716 | url = '/api/v1/polls/{0}/votes'.format(id) | ||
1717 | self.__api_request('POST', url, params) | ||
1718 | |||
1719 | |||
1720 | ### | ||
1657 | # Writing data: Notifications | 1721 | # Writing data: Notifications |
1658 | ### | 1722 | ### |
1659 | @api_version("1.0.0", "1.0.0", "1.0.0") | 1723 | @api_version("1.0.0", "1.0.0", "1.0.0") |
@@ -2480,7 +2544,7 @@ class Mastodon: | |||
2480 | isotime = isotime[:-2] + ":" + isotime[-2:] | 2544 | isotime = isotime[:-2] + ":" + isotime[-2:] |
2481 | return isotime | 2545 | return isotime |
2482 | 2546 | ||
2483 | def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, do_ratelimiting=True): | 2547 | def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, do_ratelimiting=True, use_json = False): |
2484 | """ | 2548 | """ |
2485 | Internal API request helper. | 2549 | Internal API request helper. |
2486 | """ | 2550 | """ |
@@ -2527,11 +2591,14 @@ class Mastodon: | |||
2527 | try: | 2591 | try: |
2528 | kwargs = dict(headers=headers, files=files, | 2592 | kwargs = dict(headers=headers, files=files, |
2529 | timeout=self.request_timeout) | 2593 | timeout=self.request_timeout) |
2530 | if method == 'GET': | 2594 | if use_json == False: |
2531 | kwargs['params'] = params | 2595 | if method == 'GET': |
2596 | kwargs['params'] = params | ||
2597 | else: | ||
2598 | kwargs['data'] = params | ||
2532 | else: | 2599 | else: |
2533 | kwargs['data'] = params | 2600 | kwargs['json'] = params |
2534 | 2601 | ||
2535 | response_object = self.session.request( | 2602 | response_object = self.session.request( |
2536 | method, self.api_base_url + endpoint, **kwargs) | 2603 | method, self.api_base_url + endpoint, **kwargs) |
2537 | except Exception as e: | 2604 | except Exception as e: |
diff --git a/tests/cassettes/test_poll_illegal_vote.yaml b/tests/cassettes/test_poll_illegal_vote.yaml new file mode 100644 index 0000000..72482b9 --- /dev/null +++ b/tests/cassettes/test_poll_illegal_vote.yaml | |||
@@ -0,0 +1,96 @@ | |||
1 | interactions: | ||
2 | - request: | ||
3 | body: '{"poll": {"hide_totals": false, "multiple": false, "expires_in": 300, "options": | ||
4 | ["four twenty", "sixty-nine"]}, "status": "nice"}' | ||
5 | headers: | ||
6 | Accept: ['*/*'] | ||
7 | Accept-Encoding: ['gzip, deflate'] | ||
8 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2] | ||
9 | Connection: [keep-alive] | ||
10 | Content-Length: ['130'] | ||
11 | Content-Type: [application/json] | ||
12 | User-Agent: [python-requests/2.18.4] | ||
13 | method: POST | ||
14 | uri: http://localhost:3000/api/v1/statuses | ||
15 | response: | ||
16 | body: {string: '{"id":"102005835304968136","created_at":"2019-04-28T21:05:24.088Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"en","uri":"http://localhost/users/admin/statuses/102005835304968136","content":"\u003cp\u003enice\u003c/p\u003e","url":"http://localhost/@admin/102005835304968136","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py | ||
17 | test suite","website":null},"account":{"id":"1","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2019-04-27T18:52:42.626Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@admin","avatar":"http://localhost/avatars/original/missing.png","avatar_static":"http://localhost/avatars/original/missing.png","header":"http://localhost/headers/original/missing.png","header_static":"http://localhost/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":25,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":{"id":"16","expires_at":"2019-04-28T21:10:24.070Z","expired":false,"multiple":false,"votes_count":0,"voted":true,"options":[{"title":"four | ||
18 | twenty","votes_count":0},{"title":"sixty-nine","votes_count":0}],"emojis":[]}}'} | ||
19 | headers: | ||
20 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
21 | Content-Type: [application/json; charset=utf-8] | ||
22 | ETag: [W/"cb8935a9ac8d3dea6609462bbce81c7d"] | ||
23 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
24 | Transfer-Encoding: [chunked] | ||
25 | Vary: ['Accept-Encoding, Origin'] | ||
26 | X-Content-Type-Options: [nosniff] | ||
27 | X-Download-Options: [noopen] | ||
28 | X-Frame-Options: [SAMEORIGIN] | ||
29 | X-Permitted-Cross-Domain-Policies: [none] | ||
30 | X-Request-Id: [13adc429-bd63-4a6c-8afa-e52db1b58762] | ||
31 | X-Runtime: ['0.342656'] | ||
32 | X-XSS-Protection: [1; mode=block] | ||
33 | content-length: ['1383'] | ||
34 | status: {code: 200, message: OK} | ||
35 | - request: | ||
36 | body: choices%5B%5D=1 | ||
37 | headers: | ||
38 | Accept: ['*/*'] | ||
39 | Accept-Encoding: ['gzip, deflate'] | ||
40 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
41 | Connection: [keep-alive] | ||
42 | Content-Length: ['15'] | ||
43 | Content-Type: [application/x-www-form-urlencoded] | ||
44 | User-Agent: [python-requests/2.18.4] | ||
45 | method: POST | ||
46 | uri: http://localhost:3000/api/v1/polls/16/votes | ||
47 | response: | ||
48 | body: {string: '{"id":"16","expires_at":"2019-04-28T21:10:24.070Z","expired":false,"multiple":false,"votes_count":1,"voted":true,"options":[{"title":"four | ||
49 | twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'} | ||
50 | headers: | ||
51 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
52 | Content-Type: [application/json; charset=utf-8] | ||
53 | ETag: [W/"96d62a6ad640c2c992e83b4bffc10c7b"] | ||
54 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
55 | Transfer-Encoding: [chunked] | ||
56 | Vary: ['Accept-Encoding, Origin'] | ||
57 | X-Content-Type-Options: [nosniff] | ||
58 | X-Download-Options: [noopen] | ||
59 | X-Frame-Options: [SAMEORIGIN] | ||
60 | X-Permitted-Cross-Domain-Policies: [none] | ||
61 | X-Request-Id: [d7715baa-8b11-47b3-bc72-401b22f6296c] | ||
62 | X-Runtime: ['0.167098'] | ||
63 | X-XSS-Protection: [1; mode=block] | ||
64 | content-length: ['216'] | ||
65 | status: {code: 200, message: OK} | ||
66 | - request: | ||
67 | body: choices%5B%5D=0 | ||
68 | headers: | ||
69 | Accept: ['*/*'] | ||
70 | Accept-Encoding: ['gzip, deflate'] | ||
71 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
72 | Connection: [keep-alive] | ||
73 | Content-Length: ['15'] | ||
74 | Content-Type: [application/x-www-form-urlencoded] | ||
75 | User-Agent: [python-requests/2.18.4] | ||
76 | method: POST | ||
77 | uri: http://localhost:3000/api/v1/polls/16/votes | ||
78 | response: | ||
79 | body: {string: "{\"error\":\"\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u306B\u5931\u6557\u3057\u307E\u3057\u305F: | ||
80 | \u3053\u306E\u30A2\u30F3\u30B1\u30FC\u30C8\u306B\u306F\u6295\u7968\u6E08\u307F\u3067\u3059\"}"} | ||
81 | headers: | ||
82 | Cache-Control: [no-cache] | ||
83 | Content-Type: [application/json; charset=utf-8] | ||
84 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
85 | Transfer-Encoding: [chunked] | ||
86 | Vary: ['Accept-Encoding, Origin'] | ||
87 | X-Content-Type-Options: [nosniff] | ||
88 | X-Download-Options: [noopen] | ||
89 | X-Frame-Options: [SAMEORIGIN] | ||
90 | X-Permitted-Cross-Domain-Policies: [none] | ||
91 | X-Request-Id: [846275ac-e205-4fb2-8132-edeef42a2ff2] | ||
92 | X-Runtime: ['0.101521'] | ||
93 | X-XSS-Protection: [1; mode=block] | ||
94 | content-length: ['101'] | ||
95 | status: {code: 422, message: Unprocessable Entity} | ||
96 | version: 1 | ||
diff --git a/tests/cassettes/test_polls.yaml b/tests/cassettes/test_polls.yaml new file mode 100644 index 0000000..6132074 --- /dev/null +++ b/tests/cassettes/test_polls.yaml | |||
@@ -0,0 +1,184 @@ | |||
1 | interactions: | ||
2 | - request: | ||
3 | body: '{"poll": {"hide_totals": false, "multiple": true, "expires_in": 300, "options": | ||
4 | ["four twenty", "sixty-nine"]}, "status": "nice"}' | ||
5 | headers: | ||
6 | Accept: ['*/*'] | ||
7 | Accept-Encoding: ['gzip, deflate'] | ||
8 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2] | ||
9 | Connection: [keep-alive] | ||
10 | Content-Length: ['129'] | ||
11 | Content-Type: [application/json] | ||
12 | User-Agent: [python-requests/2.18.4] | ||
13 | method: POST | ||
14 | uri: http://localhost:3000/api/v1/statuses | ||
15 | response: | ||
16 | body: {string: '{"id":"102005835265128615","created_at":"2019-04-28T21:05:23.464Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"en","uri":"http://localhost/users/admin/statuses/102005835265128615","content":"\u003cp\u003enice\u003c/p\u003e","url":"http://localhost/@admin/102005835265128615","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py | ||
17 | test suite","website":null},"account":{"id":"1","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2019-04-27T18:52:42.626Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@admin","avatar":"http://localhost/avatars/original/missing.png","avatar_static":"http://localhost/avatars/original/missing.png","header":"http://localhost/headers/original/missing.png","header_static":"http://localhost/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":25,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":0,"voted":true,"options":[{"title":"four | ||
18 | twenty","votes_count":0},{"title":"sixty-nine","votes_count":0}],"emojis":[]}}'} | ||
19 | headers: | ||
20 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
21 | Content-Type: [application/json; charset=utf-8] | ||
22 | ETag: [W/"9b51d6b8d66f9e0eb1c833ed6f67df71"] | ||
23 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
24 | Transfer-Encoding: [chunked] | ||
25 | Vary: ['Accept-Encoding, Origin'] | ||
26 | X-Content-Type-Options: [nosniff] | ||
27 | X-Download-Options: [noopen] | ||
28 | X-Frame-Options: [SAMEORIGIN] | ||
29 | X-Permitted-Cross-Domain-Policies: [none] | ||
30 | X-Request-Id: [f11d8fa0-461a-446e-a0f5-20b81af7f6cc] | ||
31 | X-Runtime: ['0.157309'] | ||
32 | X-XSS-Protection: [1; mode=block] | ||
33 | content-length: ['1382'] | ||
34 | status: {code: 200, message: OK} | ||
35 | - request: | ||
36 | body: choices%5B%5D=1 | ||
37 | headers: | ||
38 | Accept: ['*/*'] | ||
39 | Accept-Encoding: ['gzip, deflate'] | ||
40 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
41 | Connection: [keep-alive] | ||
42 | Content-Length: ['15'] | ||
43 | Content-Type: [application/x-www-form-urlencoded] | ||
44 | User-Agent: [python-requests/2.18.4] | ||
45 | method: POST | ||
46 | uri: http://localhost:3000/api/v1/polls/15/votes | ||
47 | response: | ||
48 | body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":1,"voted":true,"options":[{"title":"four | ||
49 | twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'} | ||
50 | headers: | ||
51 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
52 | Content-Type: [application/json; charset=utf-8] | ||
53 | ETag: [W/"5b2a849b672ccadf70a2620d4dc1cacb"] | ||
54 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
55 | Transfer-Encoding: [chunked] | ||
56 | Vary: ['Accept-Encoding, Origin'] | ||
57 | X-Content-Type-Options: [nosniff] | ||
58 | X-Download-Options: [noopen] | ||
59 | X-Frame-Options: [SAMEORIGIN] | ||
60 | X-Permitted-Cross-Domain-Policies: [none] | ||
61 | X-Request-Id: [9bfef151-c9a3-44cc-94d4-6ed33e9e7c24] | ||
62 | X-Runtime: ['0.079564'] | ||
63 | X-XSS-Protection: [1; mode=block] | ||
64 | content-length: ['215'] | ||
65 | status: {code: 200, message: OK} | ||
66 | - request: | ||
67 | body: null | ||
68 | headers: | ||
69 | Accept: ['*/*'] | ||
70 | Accept-Encoding: ['gzip, deflate'] | ||
71 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
72 | Connection: [keep-alive] | ||
73 | User-Agent: [python-requests/2.18.4] | ||
74 | method: GET | ||
75 | uri: http://localhost:3000/api/v1/polls/15 | ||
76 | response: | ||
77 | body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":1,"voted":true,"options":[{"title":"four | ||
78 | twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'} | ||
79 | headers: | ||
80 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
81 | Content-Type: [application/json; charset=utf-8] | ||
82 | ETag: [W/"5b2a849b672ccadf70a2620d4dc1cacb"] | ||
83 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
84 | Transfer-Encoding: [chunked] | ||
85 | Vary: ['Accept-Encoding, Origin'] | ||
86 | X-Content-Type-Options: [nosniff] | ||
87 | X-Download-Options: [noopen] | ||
88 | X-Frame-Options: [SAMEORIGIN] | ||
89 | X-Permitted-Cross-Domain-Policies: [none] | ||
90 | X-Request-Id: [f6a54825-bd65-49b0-a83f-39ef5124a362] | ||
91 | X-Runtime: ['0.043202'] | ||
92 | X-XSS-Protection: [1; mode=block] | ||
93 | content-length: ['215'] | ||
94 | status: {code: 200, message: OK} | ||
95 | - request: | ||
96 | body: choices%5B%5D=0 | ||
97 | headers: | ||
98 | Accept: ['*/*'] | ||
99 | Accept-Encoding: ['gzip, deflate'] | ||
100 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
101 | Connection: [keep-alive] | ||
102 | Content-Length: ['15'] | ||
103 | Content-Type: [application/x-www-form-urlencoded] | ||
104 | User-Agent: [python-requests/2.18.4] | ||
105 | method: POST | ||
106 | uri: http://localhost:3000/api/v1/polls/15/votes | ||
107 | response: | ||
108 | body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":2,"voted":true,"options":[{"title":"four | ||
109 | twenty","votes_count":1},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'} | ||
110 | headers: | ||
111 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
112 | Content-Type: [application/json; charset=utf-8] | ||
113 | ETag: [W/"567f9562c02e1a5533bf95d1d4bbdede"] | ||
114 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
115 | Transfer-Encoding: [chunked] | ||
116 | Vary: ['Accept-Encoding, Origin'] | ||
117 | X-Content-Type-Options: [nosniff] | ||
118 | X-Download-Options: [noopen] | ||
119 | X-Frame-Options: [SAMEORIGIN] | ||
120 | X-Permitted-Cross-Domain-Policies: [none] | ||
121 | X-Request-Id: [209f0950-c9c0-4ab8-978f-de3239546a97] | ||
122 | X-Runtime: ['0.062952'] | ||
123 | X-XSS-Protection: [1; mode=block] | ||
124 | content-length: ['215'] | ||
125 | status: {code: 200, message: OK} | ||
126 | - request: | ||
127 | body: null | ||
128 | headers: | ||
129 | Accept: ['*/*'] | ||
130 | Accept-Encoding: ['gzip, deflate'] | ||
131 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] | ||
132 | Connection: [keep-alive] | ||
133 | User-Agent: [python-requests/2.18.4] | ||
134 | method: GET | ||
135 | uri: http://localhost:3000/api/v1/polls/15 | ||
136 | response: | ||
137 | body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":2,"voted":true,"options":[{"title":"four | ||
138 | twenty","votes_count":1},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'} | ||
139 | headers: | ||
140 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
141 | Content-Type: [application/json; charset=utf-8] | ||
142 | ETag: [W/"567f9562c02e1a5533bf95d1d4bbdede"] | ||
143 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
144 | Transfer-Encoding: [chunked] | ||
145 | Vary: ['Accept-Encoding, Origin'] | ||
146 | X-Content-Type-Options: [nosniff] | ||
147 | X-Download-Options: [noopen] | ||
148 | X-Frame-Options: [SAMEORIGIN] | ||
149 | X-Permitted-Cross-Domain-Policies: [none] | ||
150 | X-Request-Id: [7caa443c-5605-436f-bae1-f7088dc7db1d] | ||
151 | X-Runtime: ['0.037629'] | ||
152 | X-XSS-Protection: [1; mode=block] | ||
153 | content-length: ['215'] | ||
154 | status: {code: 200, message: OK} | ||
155 | - request: | ||
156 | body: null | ||
157 | headers: | ||
158 | Accept: ['*/*'] | ||
159 | Accept-Encoding: ['gzip, deflate'] | ||
160 | Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2] | ||
161 | Connection: [keep-alive] | ||
162 | Content-Length: ['0'] | ||
163 | User-Agent: [python-requests/2.18.4] | ||
164 | method: DELETE | ||
165 | uri: http://localhost:3000/api/v1/statuses/102005835265128615 | ||
166 | response: | ||
167 | body: {string: '{}'} | ||
168 | headers: | ||
169 | Cache-Control: ['max-age=0, private, must-revalidate'] | ||
170 | Content-Type: [application/json; charset=utf-8] | ||
171 | ETag: [W/"6e856267241253766a52970611e7487c"] | ||
172 | Referrer-Policy: [strict-origin-when-cross-origin] | ||
173 | Transfer-Encoding: [chunked] | ||
174 | Vary: ['Accept-Encoding, Origin'] | ||
175 | X-Content-Type-Options: [nosniff] | ||
176 | X-Download-Options: [noopen] | ||
177 | X-Frame-Options: [SAMEORIGIN] | ||
178 | X-Permitted-Cross-Domain-Policies: [none] | ||
179 | X-Request-Id: [9a5591f2-fbaa-4f0e-832f-86f5d1b8e6b1] | ||
180 | X-Runtime: ['0.044707'] | ||
181 | X-XSS-Protection: [1; mode=block] | ||
182 | content-length: ['2'] | ||
183 | status: {code: 200, message: OK} | ||
184 | version: 1 | ||