Add fields support, tests

This commit is contained in:
Lorenz Diener 2018-06-05 01:54:12 +02:00
pare 465981ea9a
commit 85ca599935
S'han modificat 6 arxius amb 1985 adicions i 1928 eliminacions

Veure arxiu

@ -228,6 +228,7 @@ User dicts
'moved_to_account': # If set, an account dict of the account this user has 'moved_to_account': # If set, an account dict of the account this user has
# set up as their moved-to address. # set up as their moved-to address.
'bot': # Boolean indicating whether this account is automated. 'bot': # Boolean indicating whether this account is automated.
'fields': # List of up to four dicts with free-form 'name' and 'value' profile info.
} }
mastodon.account_verify_credentials()["source"] mastodon.account_verify_credentials()["source"]

Veure arxiu

@ -7,6 +7,7 @@ import time
import random import random
import string import string
import datetime import datetime
import collections
from contextlib import closing from contextlib import closing
import pytz import pytz
import requests import requests
@ -104,13 +105,13 @@ class Mastodon:
__DEFAULT_TIMEOUT = 300 __DEFAULT_TIMEOUT = 300
__DEFAULT_STREAM_TIMEOUT = 300 __DEFAULT_STREAM_TIMEOUT = 300
__DEFAULT_STREAM_RECONNECT_WAIT_SEC = 5 __DEFAULT_STREAM_RECONNECT_WAIT_SEC = 5
__SUPPORTED_MASTODON_VERSION = "2.3.0" __SUPPORTED_MASTODON_VERSION = "2.4.0"
# Dict versions # Dict versions
__DICT_VERSION_APPLICATION = "1.0.0" __DICT_VERSION_APPLICATION = "1.0.0"
__DICT_VERSION_MENTION = "1.0.0" __DICT_VERSION_MENTION = "1.0.0"
__DICT_VERSION_MEDIA = "2.3.0" __DICT_VERSION_MEDIA = "2.3.0"
__DICT_VERSION_ACCOUNT = "2.3.0" __DICT_VERSION_ACCOUNT = "2.4.0"
__DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version("2.1.0", __DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version("2.1.0",
__DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION) __DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION)
__DICT_VERSION_INSTANCE = bigger_version("2.3.0", __DICT_VERSION_ACCOUNT) __DICT_VERSION_INSTANCE = bigger_version("2.3.0", __DICT_VERSION_ACCOUNT)
@ -1239,10 +1240,11 @@ class Mastodon:
url = '/api/v1/accounts/{0}/unmute'.format(str(id)) url = '/api/v1/accounts/{0}/unmute'.format(str(id))
return self.__api_request('POST', url) return self.__api_request('POST', url)
@api_version("1.1.1", "2.3.0", __DICT_VERSION_ACCOUNT) @api_version("1.1.1", "2.4.0", __DICT_VERSION_ACCOUNT)
def account_update_credentials(self, display_name=None, note=None, def account_update_credentials(self, display_name=None, note=None,
avatar=None, avatar_mime_type=None, avatar=None, avatar_mime_type=None,
header=None, header_mime_type=None, locked=None): header=None, header_mime_type=None,
locked=None, fields=None):
""" """
Update the profile for the currently logged-in user. Update the profile for the currently logged-in user.
@ -1253,9 +1255,12 @@ class Mastodon:
'locked' specifies whether the user needs to manually approve follow requests. 'locked' specifies whether the user needs to manually approve follow requests.
'fields' can be a list of up to four name-value pairs (specified as tuples) to
appear as semi-structured information in the users profile.
Returns the updated `user dict` of the logged-in user. Returns the updated `user dict` of the logged-in user.
""" """
params_initial = locals() params_initial = collections.OrderedDict(locals())
# Load avatar, if specified # Load avatar, if specified
if not avatar is None: if not avatar is None:
@ -1275,8 +1280,18 @@ class Mastodon:
if header_mime_type is None: if header_mime_type is None:
raise MastodonIllegalArgumentError('Could not determine mime type or data passed directly without mime type.') raise MastodonIllegalArgumentError('Could not determine mime type or data passed directly without mime type.')
# Convert fields
if fields != None:
if len(fields) > 4:
raise MastodonIllegalArgumentError('A maximum of four fields are allowed.')
fields_attributes = []
for idx, (field_name, field_value) in enumerate(fields):
params_initial['fields_attributes[' + str(idx) + '][name]'] = field_name
params_initial['fields_attributes[' + str(idx) + '][value]'] = field_value
# Clean up params # Clean up params
for param in ["avatar", "avatar_mime_type", "header", "header_mime_type"]: for param in ["avatar", "avatar_mime_type", "header", "header_mime_type", "fields"]:
if param in params_initial: if param in params_initial:
del params_initial[param] del params_initial[param]

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

Veure arxiu

@ -1,11 +1,11 @@
interactions: interactions:
- request: - request:
body: !!binary | body: !!binary |
LS00MzhiODc4NzMyNmI0YTJmYjc1YzZmNjE1ZmJhOWY2Yw0KQ29udGVudC1EaXNwb3NpdGlvbjog LS0wMzE1MDYzZmI0OWE0Yzg1YWVmZmRlN2RmZTExNmFlMA0KQ29udGVudC1EaXNwb3NpdGlvbjog
Zm9ybS1kYXRhOyBuYW1lPSJub3RlIg0KDQpJIHdhbGsgZnVubnkNCi0tNDM4Yjg3ODczMjZiNGEy Zm9ybS1kYXRhOyBuYW1lPSJkaXNwbGF5X25hbWUiDQoNCkpvaG4gTGVubm9uDQotLTAzMTUwNjNm
ZmI3NWM2ZjYxNWZiYTlmNmMNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0i YjQ5YTRjODVhZWZmZGU3ZGZlMTE2YWUwDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7
ZGlzcGxheV9uYW1lIg0KDQpKb2huIExlbm5vbg0KLS00MzhiODc4NzMyNmI0YTJmYjc1YzZmNjE1 IG5hbWU9Im5vdGUiDQoNCkkgd2FsayBmdW5ueQ0KLS0wMzE1MDYzZmI0OWE0Yzg1YWVmZmRlN2Rm
ZmJhOWY2Yw0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJoZWFkZXIiOyBm ZTExNmFlMA0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJoZWFkZXIiOyBm
aWxlbmFtZT0ibWFzdG9kb25weXVwbG9hZF8uanBlIg0KQ29udGVudC1UeXBlOiBpbWFnZS9qcGVn aWxlbmFtZT0ibWFzdG9kb25weXVwbG9hZF8uanBlIg0KQ29udGVudC1UeXBlOiBpbWFnZS9qcGVn
DQoNCv/Y/+AAEEpGSUYAAQEBAEgASAAA/+ICHElDQ19QUk9GSUxFAAEBAAACDGxjbXMCEAAAbW50 DQoNCv/Y/+AAEEpGSUYAAQEBAEgASAAA/+ICHElDQ19QUk9GSUxFAAEBAAACDGxjbXMCEAAAbW50
clJHQiBYWVogB9wAAQAZAAMAKQA5YWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbW clJHQiBYWVogB9wAAQAZAAMAKQA5YWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbW
@ -942,7 +942,7 @@ interactions:
elShfkRBtkgMCmGlSoojqYg3CP1hg5XagwuSZZej1N96VKgeHKRZSii9BM7fep2iK8u6Y69PxSpU elShfkRBtkgMCmGlSoojqYg3CP1hg5XagwuSZZej1N96VKgeHKRZSii9BM7fep2iK8u6Y69PxSpU
VZtsdoSiQO3N/mozLhcIxMSN89s+KVKgU4XMHLHOFF7LVZRJrFV22pUqBoKKIKucrmmTAxMZfilS VZtsdoSiQO3N/mozLhcIxMSN89s+KVKgU4XMHLHOFF7LVZRJrFV22pUqBoKKIKucrmmTAxMZfilS
oFO2xicuMnjFStYMZkHV3XP4pUqC5Zbdy3MwJvu7U0AjASTLfOy9aVKgjPC5Yj9imCTIjyrGTjBn oFO2xicuMnjFStYMZkHV3XP4pUqC5Zbdy3MwJvu7U0AjASTLfOy9aVKgjPC5Yj9imCTIjyrGTjBn
9aVKgY09xujjo55uzvSpUqD/2Q0KLS00MzhiODc4NzMyNmI0YTJmYjc1YzZmNjE1ZmJhOWY2Yy0t 9aVKgY09xujjo55uzvSpUqD/2Q0KLS0wMzE1MDYzZmI0OWE0Yzg1YWVmZmRlN2RmZTExNmFlMC0t
DQo= DQo=
headers: headers:
Accept: ['*/*'] Accept: ['*/*']
@ -950,26 +950,29 @@ interactions:
Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
Connection: [keep-alive] Connection: [keep-alive]
Content-Length: ['53696'] Content-Length: ['53696']
Content-Type: [multipart/form-data; boundary=438b8787326b4a2fb75c6f615fba9f6c] Content-Type: [multipart/form-data; boundary=0315063fb49a4c85aeffde7dfe116ae0]
User-Agent: [python-requests/2.9.1] User-Agent: [python-requests/2.9.1]
method: PATCH method: PATCH
uri: http://localhost:3000/api/v1/accounts/update_credentials uri: http://localhost:3000/api/v1/accounts/update_credentials
response: response:
body: {string: '{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John body: {string: '{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John
Lennon","locked":true,"created_at":"2018-05-07T00:38:05.405Z","note":"\u003cp\u003eI Lennon","locked":true,"bot":false,"created_at":"2018-05-07T00:38:05.405Z","note":"\u003cp\u003eI
walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","avatar_static":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","header":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","header_static":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","followers_count":0,"following_count":0,"statuses_count":4,"source":{"privacy":"public","sensitive":false,"note":"I walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","avatar_static":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","header":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","header_static":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","followers_count":0,"following_count":0,"statuses_count":4,"source":{"privacy":"public","sensitive":false,"note":"I
walk funny"}}'} walk funny","fields":[{"name":"bread","value":"toasty."},{"name":"lasagna","value":"no!!!"}]},"emojis":[],"fields":[{"name":"bread","value":"toasty."},{"name":"lasagna","value":"no!!!"}]}'}
headers: headers:
Cache-Control: ['max-age=0, private, must-revalidate'] Cache-Control: ['max-age=0, private, must-revalidate']
Content-Type: [application/json; charset=utf-8] Content-Type: [application/json; charset=utf-8]
ETag: [W/"b91f99fdd4767acf9e1ecc62828207ef"] ETag: [W/"e4a5fa3ea7d32b002975509cbf12d30e"]
Referrer-Policy: [strict-origin-when-cross-origin]
Transfer-Encoding: [chunked] Transfer-Encoding: [chunked]
Vary: ['Accept-Encoding, Origin'] Vary: ['Accept-Encoding, Origin']
X-Content-Type-Options: [nosniff] X-Content-Type-Options: [nosniff]
X-Download-Options: [noopen]
X-Frame-Options: [SAMEORIGIN] X-Frame-Options: [SAMEORIGIN]
X-Request-Id: [4da4d35e-15ea-4a32-8b3c-015be1a73c24] X-Permitted-Cross-Domain-Policies: [none]
X-Runtime: ['0.148153'] X-Request-Id: [e74cf7c0-def0-4007-931e-bf08d48a92d5]
X-Runtime: ['0.209705']
X-XSS-Protection: [1; mode=block] X-XSS-Protection: [1; mode=block]
content-length: ['833'] content-length: ['1019']
status: {code: 200, message: OK} status: {code: 200, message: OK}
version: 1 version: 1

Veure arxiu

@ -1,11 +1,11 @@
interactions: interactions:
- request: - request:
body: !!binary | body: !!binary |
LS03N2FmNjQyODkxODU0NTU4YmI4NjdiN2I5MmVmYjVkZg0KQ29udGVudC1EaXNwb3NpdGlvbjog LS00NTk4Yjg5MzQ1Njg0ZWEyYmNlZjFlNDg0YmU5MzBlMw0KQ29udGVudC1EaXNwb3NpdGlvbjog
Zm9ybS1kYXRhOyBuYW1lPSJub3RlIg0KDQpJIHdhbGsgZnVubnkNCi0tNzdhZjY0Mjg5MTg1NDU1 Zm9ybS1kYXRhOyBuYW1lPSJkaXNwbGF5X25hbWUiDQoNCkpvaG4gTGVubm9uDQotLTQ1OThiODkz
OGJiODY3YjdiOTJlZmI1ZGYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0i NDU2ODRlYTJiY2VmMWU0ODRiZTkzMGUzDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7
ZGlzcGxheV9uYW1lIg0KDQpKb2huIExlbm5vbg0KLS03N2FmNjQyODkxODU0NTU4YmI4NjdiN2I5 IG5hbWU9Im5vdGUiDQoNCkkgd2FsayBmdW5ueQ0KLS00NTk4Yjg5MzQ1Njg0ZWEyYmNlZjFlNDg0
MmVmYjVkZg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJhdmF0YXIiOyBm YmU5MzBlMw0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJhdmF0YXIiOyBm
aWxlbmFtZT0ibWFzdG9kb25weXVwbG9hZF8uanBlIg0KQ29udGVudC1UeXBlOiBpbWFnZS9qcGVn aWxlbmFtZT0ibWFzdG9kb25weXVwbG9hZF8uanBlIg0KQ29udGVudC1UeXBlOiBpbWFnZS9qcGVn
DQoNCv/Y/+AAEEpGSUYAAQEBAEgASAAA/+ICHElDQ19QUk9GSUxFAAEBAAACDGxjbXMCEAAAbW50 DQoNCv/Y/+AAEEpGSUYAAQEBAEgASAAA/+ICHElDQ19QUk9GSUxFAAEBAAACDGxjbXMCEAAAbW50
clJHQiBYWVogB9wAAQAZAAMAKQA5YWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbW clJHQiBYWVogB9wAAQAZAAMAKQA5YWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbW
@ -942,7 +942,7 @@ interactions:
elShfkRBtkgMCmGlSoojqYg3CP1hg5XagwuSZZej1N96VKgeHKRZSii9BM7fep2iK8u6Y69PxSpU elShfkRBtkgMCmGlSoojqYg3CP1hg5XagwuSZZej1N96VKgeHKRZSii9BM7fep2iK8u6Y69PxSpU
VZtsdoSiQO3N/mozLhcIxMSN89s+KVKgU4XMHLHOFF7LVZRJrFV22pUqBoKKIKucrmmTAxMZfilS VZtsdoSiQO3N/mozLhcIxMSN89s+KVKgU4XMHLHOFF7LVZRJrFV22pUqBoKKIKucrmmTAxMZfilS
oFO2xicuMnjFStYMZkHV3XP4pUqC5Zbdy3MwJvu7U0AjASTLfOy9aVKgjPC5Yj9imCTIjyrGTjBn oFO2xicuMnjFStYMZkHV3XP4pUqC5Zbdy3MwJvu7U0AjASTLfOy9aVKgjPC5Yj9imCTIjyrGTjBn
9aVKgY09xujjo55uzvSpUqD/2Q0KLS03N2FmNjQyODkxODU0NTU4YmI4NjdiN2I5MmVmYjVkZi0t 9aVKgY09xujjo55uzvSpUqD/2Q0KLS00NTk4Yjg5MzQ1Njg0ZWEyYmNlZjFlNDg0YmU5MzBlMy0t
DQo= DQo=
headers: headers:
Accept: ['*/*'] Accept: ['*/*']
@ -950,26 +950,29 @@ interactions:
Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
Connection: [keep-alive] Connection: [keep-alive]
Content-Length: ['53696'] Content-Length: ['53696']
Content-Type: [multipart/form-data; boundary=77af642891854558bb867b7b92efb5df] Content-Type: [multipart/form-data; boundary=4598b89345684ea2bcef1e484be930e3]
User-Agent: [python-requests/2.9.1] User-Agent: [python-requests/2.9.1]
method: PATCH method: PATCH
uri: http://localhost:3000/api/v1/accounts/update_credentials uri: http://localhost:3000/api/v1/accounts/update_credentials
response: response:
body: {string: '{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John body: {string: '{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John
Lennon","locked":true,"created_at":"2018-05-07T00:38:05.405Z","note":"\u003cp\u003eI Lennon","locked":true,"bot":false,"created_at":"2018-05-07T00:38:05.405Z","note":"\u003cp\u003eI
walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","avatar_static":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","header":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpeg","header_static":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpeg","followers_count":0,"following_count":0,"statuses_count":4,"source":{"privacy":"public","sensitive":false,"note":"I walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","avatar_static":"http://localhost:3000/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpe","header":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","header_static":"http://localhost:3000/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpe","followers_count":0,"following_count":0,"statuses_count":4,"source":{"privacy":"public","sensitive":false,"note":"I
walk funny"}}'} walk funny","fields":[{"name":"bread","value":"toasty."},{"name":"lasagna","value":"no!!!"}]},"emojis":[],"fields":[{"name":"bread","value":"toasty."},{"name":"lasagna","value":"no!!!"}]}'}
headers: headers:
Cache-Control: ['max-age=0, private, must-revalidate'] Cache-Control: ['max-age=0, private, must-revalidate']
Content-Type: [application/json; charset=utf-8] Content-Type: [application/json; charset=utf-8]
ETag: [W/"aba70f93d265f72d820cc0d3bd01c834"] ETag: [W/"88fa68354142994962076b3df86272b7"]
Referrer-Policy: [strict-origin-when-cross-origin]
Transfer-Encoding: [chunked] Transfer-Encoding: [chunked]
Vary: ['Accept-Encoding, Origin'] Vary: ['Accept-Encoding, Origin']
X-Content-Type-Options: [nosniff] X-Content-Type-Options: [nosniff]
X-Download-Options: [noopen]
X-Frame-Options: [SAMEORIGIN] X-Frame-Options: [SAMEORIGIN]
X-Request-Id: [a7b608c7-ddfe-4447-b571-4310985822e3] X-Permitted-Cross-Domain-Policies: [none]
X-Runtime: ['0.583569'] X-Request-Id: [97881214-41a9-4e53-ac2d-0bd3dff79e7b]
X-Runtime: ['0.209024']
X-XSS-Protection: [1; mode=block] X-XSS-Protection: [1; mode=block]
content-length: ['835'] content-length: ['1019']
status: {code: 200, message: OK} status: {code: 200, message: OK}
version: 1 version: 1

Veure arxiu

@ -1,5 +1,6 @@
import pytest import pytest
from mastodon.Mastodon import MastodonAPIError from mastodon.Mastodon import MastodonAPIError, MastodonIllegalArgumentError
import re
@pytest.mark.vcr() @pytest.mark.vcr()
def test_account(api): def test_account(api):
@ -86,12 +87,35 @@ def test_account_update_credentials(api):
image = f.read() image = f.read()
account = api.account_update_credentials( account = api.account_update_credentials(
display_name='John Lennon', display_name='John Lennon',
note='I walk funny', note='I walk funny',
avatar = "tests/image.jpg", avatar = "tests/image.jpg",
header = image, header = image,
header_mime_type = "image/jpeg") header_mime_type = "image/jpeg",
fields = [
("bread", "toasty."),
("lasagna", "no!!!"),
]
)
assert account assert account
assert account["display_name"] == 'John Lennon'
assert re.sub("<.*?>", " ", account["note"]).strip() == 'I walk funny'
assert account["fields"][0].name == "bread"
assert account["fields"][0].value == "toasty."
assert account["fields"][1].name == "lasagna"
assert account["fields"][1].value == "no!!!"
@pytest.mark.vcr()
def test_account_update_credentials_too_many_fields(api):
with pytest.raises(MastodonIllegalArgumentError):
api.account_update_credentials(fields = [
('a', 'b'),
('c', 'd'),
('e', 'f'),
('g', 'h'),
('i', 'j'),
])
@pytest.mark.vcr(match_on=['path']) @pytest.mark.vcr(match_on=['path'])
def test_account_update_credentials_no_header(api): def test_account_update_credentials_no_header(api):