aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md4
-rw-r--r--mastodon/Mastodon.py76
-rw-r--r--tests/cassettes/test_admin_trends.yaml234
-rw-r--r--tests/cassettes/test_revoke.yaml109
-rw-r--r--tests/test_admin.py9
-rw-r--r--tests/test_auth.py6
6 files changed, 392 insertions, 46 deletions
diff --git a/TODO.md b/TODO.md
index e0b504a..d5e16bd 100644
--- a/TODO.md
+++ b/TODO.md
@@ -43,11 +43,11 @@ Refer to mastodon changelog and API docs for details when implementing, add or m
43----- 43-----
44* [x] Add support for incoming edited posts 44* [x] Add support for incoming edited posts
45* [x] Add notifications for posts deleted by moderators <- by email. not actually API relevant. 45* [x] Add notifications for posts deleted by moderators <- by email. not actually API relevant.
46* [ ] Add explore page with trending posts and links 46* [x] Add explore page with trending posts and links
47* [ ] Add graphs and retention metrics to admin dashboard 47* [ ] Add graphs and retention metrics to admin dashboard
48* [ ] Add GET /api/v1/accounts/familiar_followers to REST API 48* [ ] Add GET /api/v1/accounts/familiar_followers to REST API
49* [ ] Add POST /api/v1/accounts/:id/remove_from_followers to REST API 49* [ ] Add POST /api/v1/accounts/:id/remove_from_followers to REST API
50* [ ] Add category and rule_ids params to POST /api/v1/reports IN REST API 50* [x] Add category and rule_ids params to POST /api/v1/reports IN REST API
51* [ ] Add global lang param to REST API 51* [ ] Add global lang param to REST API
52* [x] Add types param to GET /api/v1/notifications in REST API 52* [x] Add types param to GET /api/v1/notifications in REST API
53* [x] Add notifications for moderators about new sign-ups 53* [x] Add notifications for moderators about new sign-ups
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index a4fe768..d0b3606 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -373,10 +373,9 @@ class Mastodon:
373 373
374 If no other `User-Agent` is specified, "mastodonpy" will be used. 374 If no other `User-Agent` is specified, "mastodonpy" will be used.
375 """ 375 """
376 if api_base_url is None: 376 self.api_base_url = api_base_url
377 raise MastodonIllegalArgumentError("API base URL is required.") 377 if self.api_base_url is not None:
378 self.api_base_url = Mastodon.__protocolize(api_base_url) 378 self.api_base_url = self.__protocolize(self.api_base_url)
379
380 self.client_id = client_id 379 self.client_id = client_id
381 self.client_secret = client_secret 380 self.client_secret = client_secret
382 self.access_token = access_token 381 self.access_token = access_token
@@ -417,9 +416,9 @@ class Mastodon:
417 try_base_url = secret_file.readline().rstrip() 416 try_base_url = secret_file.readline().rstrip()
418 if try_base_url is not None and len(try_base_url) != 0: 417 if try_base_url is not None and len(try_base_url) != 0:
419 try_base_url = Mastodon.__protocolize(try_base_url) 418 try_base_url = Mastodon.__protocolize(try_base_url)
419 print(self.api_base_url, try_base_url)
420 if not (self.api_base_url is None or try_base_url == self.api_base_url): 420 if not (self.api_base_url is None or try_base_url == self.api_base_url):
421 raise MastodonIllegalArgumentError( 421 raise MastodonIllegalArgumentError('Mismatch in base URLs between files and/or specified')
422 'Mismatch in base URLs between files and/or specified')
423 self.api_base_url = try_base_url 422 self.api_base_url = try_base_url
424 423
425 # With new registrations we support the 4th line to store a client_name and use it as user-agent 424 # With new registrations we support the 4th line to store a client_name and use it as user-agent
@@ -428,8 +427,7 @@ class Mastodon:
428 self.user_agent = client_name.rstrip() 427 self.user_agent = client_name.rstrip()
429 else: 428 else:
430 if self.client_secret is None: 429 if self.client_secret is None:
431 raise MastodonIllegalArgumentError( 430 raise MastodonIllegalArgumentError('Specified client id directly, but did not supply secret')
432 'Specified client id directly, but did not supply secret')
433 431
434 if self.access_token is not None and os.path.isfile(self.access_token): 432 if self.access_token is not None and os.path.isfile(self.access_token):
435 with open(self.access_token, 'r') as token_file: 433 with open(self.access_token, 'r') as token_file:
@@ -439,10 +437,14 @@ class Mastodon:
439 if try_base_url is not None and len(try_base_url) != 0: 437 if try_base_url is not None and len(try_base_url) != 0:
440 try_base_url = Mastodon.__protocolize(try_base_url) 438 try_base_url = Mastodon.__protocolize(try_base_url)
441 if not (self.api_base_url is None or try_base_url == self.api_base_url): 439 if not (self.api_base_url is None or try_base_url == self.api_base_url):
442 raise MastodonIllegalArgumentError( 440 raise MastodonIllegalArgumentError('Mismatch in base URLs between files and/or specified')
443 'Mismatch in base URLs between files and/or specified')
444 self.api_base_url = try_base_url 441 self.api_base_url = try_base_url
445 442
443 # Verify we have a base URL, protocolize
444 if self.api_base_url is None:
445 raise MastodonIllegalArgumentError("API base URL is required.")
446 self.api_base_url = Mastodon.__protocolize(self.api_base_url)
447
446 if not version_check_mode in ["created", "changed", "none"]: 448 if not version_check_mode in ["created", "changed", "none"]:
447 raise MastodonIllegalArgumentError("Invalid version check method.") 449 raise MastodonIllegalArgumentError("Invalid version check method.")
448 self.version_check_mode = version_check_mode 450 self.version_check_mode = version_check_mode
@@ -994,7 +996,7 @@ class Mastodon:
994 Does not require authentication for publicly visible statuses. 996 Does not require authentication for publicly visible statuses.
995 997
996 This function is deprecated as of 3.0.0 and the endpoint does not 998 This function is deprecated as of 3.0.0 and the endpoint does not
997 exist anymore - you should just use the "card" field of the status dicts 999 exist anymore - you should just use the "card" field of the toot dicts
998 instead. Mastodon.py will try to mimic the old behaviour, but this 1000 instead. Mastodon.py will try to mimic the old behaviour, but this
999 is somewhat inefficient and not guaranteed to be the case forever. 1001 is somewhat inefficient and not guaranteed to be the case forever.
1000 1002
@@ -1573,7 +1575,7 @@ class Mastodon:
1573 Specify `limit` to limit how many results are returned (the maximum number 1575 Specify `limit` to limit how many results are returned (the maximum number
1574 of results is 10, the endpoint is not paginated). 1576 of results is 10, the endpoint is not paginated).
1575 1577
1576 Returns a list of `status dicts`_, sorted by the instances's trending algorithm, 1578 Returns a list of `toot dicts`_, sorted by the instances's trending algorithm,
1577 descending. 1579 descending.
1578 """ 1580 """
1579 params = self.__generate_params(locals()) 1581 params = self.__generate_params(locals())
@@ -1690,6 +1692,8 @@ class Mastodon:
1690 Warning: This method has now finally been removed, and will not 1692 Warning: This method has now finally been removed, and will not
1691 work on Mastodon versions 2.5.0 and above. 1693 work on Mastodon versions 2.5.0 and above.
1692 """ 1694 """
1695 if self.verify_minimum_version("2.5.0", cached=True):
1696 raise MastodonVersionError("API removed in Mastodon 2.5.0")
1693 return self.__api_request('GET', '/api/v1/reports') 1697 return self.__api_request('GET', '/api/v1/reports')
1694 1698
1695 ### 1699 ###
@@ -2530,7 +2534,7 @@ class Mastodon:
2530 """ 2534 """
2531 Set a note (visible to the logged in user only) for the given account. 2535 Set a note (visible to the logged in user only) for the given account.
2532 2536
2533 Returns a `status dict`_ with the `note` updated. 2537 Returns a `toot dict`_ with the `note` updated.
2534 """ 2538 """
2535 id = self.__unpack_id(id) 2539 id = self.__unpack_id(id)
2536 params = self.__generate_params(locals(), ["id"]) 2540 params = self.__generate_params(locals(), ["id"])
@@ -2696,18 +2700,25 @@ class Mastodon:
2696 ### 2700 ###
2697 # Writing data: Reports 2701 # Writing data: Reports
2698 ### 2702 ###
2699 @api_version("1.1.0", "2.5.0", __DICT_VERSION_REPORT) 2703 @api_version("1.1.0", "3.5.0", __DICT_VERSION_REPORT)
2700 def report(self, account_id, status_ids=None, comment=None, forward=False): 2704 def report(self, account_id, status_ids=None, comment=None, forward=False, category=None, rule_ids=None):
2701 """ 2705 """
2702 Report statuses to the instances administrators. 2706 Report statuses to the instances administrators.
2703 2707
2704 Accepts a list of toot IDs associated with the report, and a comment. 2708 Accepts a list of toot IDs associated with the report, and a comment.
2705 2709
2706 Set forward to True to forward a report of a remote user to that users 2710 Starting with Mastodon 3.5.0, you can also pass a `category` (one out of
2711 "spam", "violation" or "other") and `rule_ids` (a list of rule IDs corresponding
2712 to the rules returned by the `instance()`_ API).
2713
2714 Set `forward` to True to forward a report of a remote user to that users
2707 instance as well as sending it to the instance local administrators. 2715 instance as well as sending it to the instance local administrators.
2708 2716
2709 Returns a `report dict`_. 2717 Returns a `report dict`_.
2710 """ 2718 """
2719 if category is not None and not category in ["spam", "violation", "other"]:
2720 raise MastodonIllegalArgumentError("Invalid report category (must be spam, violation or other)")
2721
2711 account_id = self.__unpack_id(account_id) 2722 account_id = self.__unpack_id(account_id)
2712 2723
2713 if status_ids is not None: 2724 if status_ids is not None:
@@ -3297,6 +3308,39 @@ class Mastodon:
3297 id = self.__unpack_id(id) 3308 id = self.__unpack_id(id)
3298 return self.__api_request('POST', '/api/v1/admin/reports/{0}/resolve'.format(id)) 3309 return self.__api_request('POST', '/api/v1/admin/reports/{0}/resolve'.format(id))
3299 3310
3311 @api_version("3.5.0", "3.5.0", __DICT_VERSION_HASHTAG)
3312 def admin_trending_tags(self, limit=None):
3313 """
3314 Admin version of `trending_tags()`_. Includes unapproved tags.
3315
3316 Returns a list of `hashtag dicts`_, sorted by the instance's trending algorithm,
3317 descending.
3318 """
3319 params = self.__generate_params(locals())
3320 return self.__api_request('GET', '/api/v1/admin/trends/tags', params)
3321
3322 @api_version("3.5.0", "3.5.0", __DICT_VERSION_STATUS)
3323 def admin_trending_statuses(self):
3324 """
3325 Admin version of `trending_statuses()`_. Includes unapproved tags.
3326
3327 Returns a list of `toot dicts`_, sorted by the instance's trending algorithm,
3328 descending.
3329 """
3330 params = self.__generate_params(locals())
3331 return self.__api_request('GET', '/api/v1/admin/trends/statuses', params)
3332
3333 @api_version("3.5.0", "3.5.0", __DICT_VERSION_CARD)
3334 def admin_trending_links(self):
3335 """
3336 Admin version of `trending_links()`_. Includes unapproved tags.
3337
3338 Returns a list of `card dicts`_, sorted by the instance's trending algorithm,
3339 descending.
3340 """
3341 params = self.__generate_params(locals())
3342 return self.__api_request('GET', '/api/v1/admin/trends/links', params)
3343
3300 ### 3344 ###
3301 # Push subscription crypto utilities 3345 # Push subscription crypto utilities
3302 ### 3346 ###
diff --git a/tests/cassettes/test_admin_trends.yaml b/tests/cassettes/test_admin_trends.yaml
new file mode 100644
index 0000000..a471f98
--- /dev/null
+++ b/tests/cassettes/test_admin_trends.yaml
@@ -0,0 +1,234 @@
1interactions:
2- request:
3 body: null
4 headers:
5 Accept:
6 - '*/*'
7 Accept-Encoding:
8 - gzip, deflate
9 Authorization:
10 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
11 Connection:
12 - keep-alive
13 User-Agent:
14 - tests/v311
15 method: GET
16 uri: http://localhost:3000/api/v1/admin/trends/tags
17 response:
18 body:
19 string: '[]'
20 headers:
21 Cache-Control:
22 - no-store
23 Content-Security-Policy:
24 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
25 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
26 style-src ''self'' http://localhost:3000 ''nonce-riTO9qzezJtfpKUBo5FfRw=='';
27 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
28 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
29 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
30 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
31 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
32 worker-src ''self'' blob: http://localhost:3000'
33 Content-Type:
34 - application/json; charset=utf-8
35 ETag:
36 - W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
37 Referrer-Policy:
38 - strict-origin-when-cross-origin
39 Transfer-Encoding:
40 - chunked
41 Vary:
42 - Accept, Origin
43 X-Content-Type-Options:
44 - nosniff
45 X-Download-Options:
46 - noopen
47 X-Frame-Options:
48 - SAMEORIGIN
49 X-Permitted-Cross-Domain-Policies:
50 - none
51 X-Request-Id:
52 - 7f790ab8-9fba-4fd4-b1d1-32f98f057ced
53 X-Runtime:
54 - '0.019713'
55 X-XSS-Protection:
56 - 1; mode=block
57 status:
58 code: 200
59 message: OK
60- request:
61 body: null
62 headers:
63 Accept:
64 - '*/*'
65 Accept-Encoding:
66 - gzip, deflate
67 Authorization:
68 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
69 Connection:
70 - keep-alive
71 User-Agent:
72 - tests/v311
73 method: GET
74 uri: http://localhost:3000/api/v1/admin/trends/statuses
75 response:
76 body:
77 string: '[]'
78 headers:
79 Cache-Control:
80 - no-store
81 Content-Security-Policy:
82 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
83 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
84 style-src ''self'' http://localhost:3000 ''nonce-LJrdU51JLzwv175738dEzQ=='';
85 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
86 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
87 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
88 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
89 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
90 worker-src ''self'' blob: http://localhost:3000'
91 Content-Type:
92 - application/json; charset=utf-8
93 ETag:
94 - W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
95 Referrer-Policy:
96 - strict-origin-when-cross-origin
97 Transfer-Encoding:
98 - chunked
99 Vary:
100 - Accept, Origin
101 X-Content-Type-Options:
102 - nosniff
103 X-Download-Options:
104 - noopen
105 X-Frame-Options:
106 - SAMEORIGIN
107 X-Permitted-Cross-Domain-Policies:
108 - none
109 X-Request-Id:
110 - 247300e7-df10-49fa-81b7-5ee6fd5d82a4
111 X-Runtime:
112 - '0.027509'
113 X-XSS-Protection:
114 - 1; mode=block
115 status:
116 code: 200
117 message: OK
118- request:
119 body: null
120 headers:
121 Accept:
122 - '*/*'
123 Accept-Encoding:
124 - gzip, deflate
125 Authorization:
126 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
127 Connection:
128 - keep-alive
129 User-Agent:
130 - tests/v311
131 method: GET
132 uri: http://localhost:3000/api/v1/admin/trends/links
133 response:
134 body:
135 string: '[]'
136 headers:
137 Cache-Control:
138 - no-store
139 Content-Security-Policy:
140 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
141 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
142 style-src ''self'' http://localhost:3000 ''nonce-UsGPkqqgkgw3xXRrC/rS6Q=='';
143 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
144 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
145 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
146 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
147 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
148 worker-src ''self'' blob: http://localhost:3000'
149 Content-Type:
150 - application/json; charset=utf-8
151 ETag:
152 - W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
153 Referrer-Policy:
154 - strict-origin-when-cross-origin
155 Transfer-Encoding:
156 - chunked
157 Vary:
158 - Accept, Origin
159 X-Content-Type-Options:
160 - nosniff
161 X-Download-Options:
162 - noopen
163 X-Frame-Options:
164 - SAMEORIGIN
165 X-Permitted-Cross-Domain-Policies:
166 - none
167 X-Request-Id:
168 - f9838813-fc1a-455b-8ee4-6c4e38f62be0
169 X-Runtime:
170 - '0.018125'
171 X-XSS-Protection:
172 - 1; mode=block
173 status:
174 code: 200
175 message: OK
176- request:
177 body: null
178 headers:
179 Accept:
180 - '*/*'
181 Accept-Encoding:
182 - gzip, deflate
183 Authorization:
184 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
185 Connection:
186 - keep-alive
187 User-Agent:
188 - tests/v311
189 method: GET
190 uri: http://localhost:3000/api/v1/admin/trends/tags?limit=5
191 response:
192 body:
193 string: '[]'
194 headers:
195 Cache-Control:
196 - no-store
197 Content-Security-Policy:
198 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
199 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
200 style-src ''self'' http://localhost:3000 ''nonce-yIFkCE0nhCUfZnXpKkcTiQ=='';
201 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
202 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
203 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
204 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
205 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
206 worker-src ''self'' blob: http://localhost:3000'
207 Content-Type:
208 - application/json; charset=utf-8
209 ETag:
210 - W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
211 Referrer-Policy:
212 - strict-origin-when-cross-origin
213 Transfer-Encoding:
214 - chunked
215 Vary:
216 - Accept, Origin
217 X-Content-Type-Options:
218 - nosniff
219 X-Download-Options:
220 - noopen
221 X-Frame-Options:
222 - SAMEORIGIN
223 X-Permitted-Cross-Domain-Policies:
224 - none
225 X-Request-Id:
226 - 51da904e-4de6-49d8-8680-b02a8dce3feb
227 X-Runtime:
228 - '0.008825'
229 X-XSS-Protection:
230 - 1; mode=block
231 status:
232 code: 200
233 message: OK
234version: 1
diff --git a/tests/cassettes/test_revoke.yaml b/tests/cassettes/test_revoke.yaml
index b56655e..bc75494 100644
--- a/tests/cassettes/test_revoke.yaml
+++ b/tests/cassettes/test_revoke.yaml
@@ -19,14 +19,14 @@ interactions:
19 response: 19 response:
20 body: 20 body:
21 string: '{"access_token":"__MASTODON_PY_TEST_ACCESS_TOKEN_3","token_type":"Bearer","scope":"read 21 string: '{"access_token":"__MASTODON_PY_TEST_ACCESS_TOKEN_3","token_type":"Bearer","scope":"read
22 write follow push","created_at":1669069472}' 22 write follow push","created_at":1669078552}'
23 headers: 23 headers:
24 Cache-Control: 24 Cache-Control:
25 - no-store 25 - no-store
26 Content-Security-Policy: 26 Content-Security-Policy:
27 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src 27 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
28 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; 28 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
29 style-src ''self'' http://localhost:3000 ''nonce-2hAAmzxVIF2o8Dybbe/Nlw==''; 29 style-src ''self'' http://localhost:3000 ''nonce-qgSt4nG9WHHoLhv8/BTiNA=='';
30 media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' 30 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
31 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' 31 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
32 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 32 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
@@ -36,7 +36,7 @@ interactions:
36 Content-Type: 36 Content-Type:
37 - application/json; charset=utf-8 37 - application/json; charset=utf-8
38 ETag: 38 ETag:
39 - W/"2f20b949ed12ddfc15861ec448b5551f" 39 - W/"64a8679bd2f3d37be418066de7284ddd"
40 Pragma: 40 Pragma:
41 - no-cache 41 - no-cache
42 Referrer-Policy: 42 Referrer-Policy:
@@ -54,9 +54,9 @@ interactions:
54 X-Permitted-Cross-Domain-Policies: 54 X-Permitted-Cross-Domain-Policies:
55 - none 55 - none
56 X-Request-Id: 56 X-Request-Id:
57 - 8e26834c-db67-484e-bf41-80e3a1e48c83 57 - f7be8646-6edb-4018-89b2-525917883907
58 X-Runtime: 58 X-Runtime:
59 - '0.056343' 59 - '0.072228'
60 X-XSS-Protection: 60 X-XSS-Protection:
61 - 1; mode=block 61 - 1; mode=block
62 status: 62 status:
@@ -79,14 +79,14 @@ interactions:
79 uri: http://localhost:3000/api/v1/instance/ 79 uri: http://localhost:3000/api/v1/instance/
80 response: 80 response:
81 body: 81 body:
82 string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":1,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}' 82 string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":8,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}'
83 headers: 83 headers:
84 Cache-Control: 84 Cache-Control:
85 - max-age=180, public 85 - max-age=180, public
86 Content-Security-Policy: 86 Content-Security-Policy:
87 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src 87 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
88 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; 88 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
89 style-src ''self'' http://localhost:3000 ''nonce-p/U3iDcksaJMkQ5IvZDsGQ==''; 89 style-src ''self'' http://localhost:3000 ''nonce-Xujah3tRsHYiM+FbWsiFuA=='';
90 media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' 90 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
91 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' 91 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
92 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 92 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
@@ -96,9 +96,9 @@ interactions:
96 Content-Type: 96 Content-Type:
97 - application/json; charset=utf-8 97 - application/json; charset=utf-8
98 Date: 98 Date:
99 - Mon, 21 Nov 2022 20:24:59 GMT 99 - Thu, 24 Nov 2022 21:56:42 GMT
100 ETag: 100 ETag:
101 - W/"bf317ffab393d8d1da7195269f28968a" 101 - W/"b3134b9b6dd4c58f0150831d75c86c06"
102 Referrer-Policy: 102 Referrer-Policy:
103 - strict-origin-when-cross-origin 103 - strict-origin-when-cross-origin
104 Transfer-Encoding: 104 Transfer-Encoding:
@@ -114,9 +114,9 @@ interactions:
114 X-Permitted-Cross-Domain-Policies: 114 X-Permitted-Cross-Domain-Policies:
115 - none 115 - none
116 X-Request-Id: 116 X-Request-Id:
117 - 1d68749b-1782-4ee2-b0b4-f3b08b1253eb 117 - 902f84f2-1256-449b-8c98-e593b8b72998
118 X-Runtime: 118 X-Runtime:
119 - '0.029627' 119 - '0.042336'
120 X-XSS-Protection: 120 X-XSS-Protection:
121 - 1; mode=block 121 - 1; mode=block
122 status: 122 status:
@@ -150,7 +150,7 @@ interactions:
150 Content-Security-Policy: 150 Content-Security-Policy:
151 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src 151 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
152 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; 152 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
153 style-src ''self'' http://localhost:3000 ''nonce-DWtDMY1MqGERclXgCGbr0Q==''; 153 style-src ''self'' http://localhost:3000 ''nonce-WT+/lb3ulLnfgMU4/kyt6A=='';
154 media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' 154 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
155 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' 155 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
156 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 156 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
@@ -176,9 +176,9 @@ interactions:
176 X-Permitted-Cross-Domain-Policies: 176 X-Permitted-Cross-Domain-Policies:
177 - none 177 - none
178 X-Request-Id: 178 X-Request-Id:
179 - a63c3472-347e-48f5-8a11-4e5b6ebf4836 179 - 8c35a1e3-0ad8-4035-bb05-0795e74bace4
180 X-Runtime: 180 X-Runtime:
181 - '0.025417' 181 - '0.015637'
182 X-XSS-Protection: 182 X-XSS-Protection:
183 - 1; mode=block 183 - 1; mode=block
184 status: 184 status:
@@ -210,7 +210,7 @@ interactions:
210 Content-Security-Policy: 210 Content-Security-Policy:
211 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src 211 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
212 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; 212 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
213 style-src ''self'' http://localhost:3000 ''nonce-8Wq3rXCQa6b3gM8cbtEXVQ==''; 213 style-src ''self'' http://localhost:3000 ''nonce-YJJZ0jnA7xjMKXR0QxnZpg=='';
214 media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' 214 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
215 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' 215 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
216 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 216 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
@@ -239,21 +239,83 @@ interactions:
239 X-Permitted-Cross-Domain-Policies: 239 X-Permitted-Cross-Domain-Policies:
240 - none 240 - none
241 X-Request-Id: 241 X-Request-Id:
242 - 220822bd-2303-424b-96d7-babf8edfc5b9 242 - 0a52d3a9-ad38-4fe9-8fd4-91e90d3180c5
243 X-Runtime: 243 X-Runtime:
244 - '0.543121' 244 - '0.648647'
245 X-XSS-Protection: 245 X-XSS-Protection:
246 - 1; mode=block 246 - 1; mode=block
247 status: 247 status:
248 code: 401 248 code: 401
249 message: Unauthorized 249 message: Unauthorized
250- request: 250- request:
251 body: null
252 headers:
253 Accept:
254 - '*/*'
255 Accept-Encoding:
256 - gzip, deflate
257 Authorization:
258 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_3
259 Connection:
260 - keep-alive
261 User-Agent:
262 - mastodonpy
263 method: GET
264 uri: http://localhost:3000/api/v1/instance/
265 response:
266 body:
267 string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":8,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}'
268 headers:
269 Cache-Control:
270 - max-age=180, public
271 Content-Security-Policy:
272 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
273 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
274 style-src ''self'' http://localhost:3000 ''nonce-F1GvF0zbODWtYZVC3JI4wA=='';
275 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
276 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
277 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
278 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
279 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
280 worker-src ''self'' blob: http://localhost:3000'
281 Content-Type:
282 - application/json; charset=utf-8
283 Date:
284 - Thu, 24 Nov 2022 21:56:43 GMT
285 ETag:
286 - W/"b3134b9b6dd4c58f0150831d75c86c06"
287 Referrer-Policy:
288 - strict-origin-when-cross-origin
289 Transfer-Encoding:
290 - chunked
291 Vary:
292 - Accept, Origin
293 X-Content-Type-Options:
294 - nosniff
295 X-Download-Options:
296 - noopen
297 X-Frame-Options:
298 - SAMEORIGIN
299 X-Permitted-Cross-Domain-Policies:
300 - none
301 X-Request-Id:
302 - 2bf6c22d-2f68-45a4-bd92-389a130454b4
303 X-Runtime:
304 - '0.015512'
305 X-XSS-Protection:
306 - 1; mode=block
307 status:
308 code: 200
309 message: OK
310- request:
251 body: status=illegal+access+detected 311 body: status=illegal+access+detected
252 headers: 312 headers:
253 Accept: 313 Accept:
254 - '*/*' 314 - '*/*'
255 Accept-Encoding: 315 Accept-Encoding:
256 - gzip, deflate 316 - gzip, deflate
317 Authorization:
318 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_3
257 Connection: 319 Connection:
258 - keep-alive 320 - keep-alive
259 Content-Length: 321 Content-Length:
@@ -261,19 +323,19 @@ interactions:
261 Content-Type: 323 Content-Type:
262 - application/x-www-form-urlencoded 324 - application/x-www-form-urlencoded
263 User-Agent: 325 User-Agent:
264 - tests/v311 326 - mastodonpy
265 method: POST 327 method: POST
266 uri: http://localhost:3000/api/v1/statuses 328 uri: http://localhost:3000/api/v1/statuses
267 response: 329 response:
268 body: 330 body:
269 string: '{"error":"The access token is invalid"}' 331 string: "{\"error\":\"\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u306F\u53D6\u308A\u6D88\u3055\u308C\u3066\u3044\u307E\u3059\"}"
270 headers: 332 headers:
271 Cache-Control: 333 Cache-Control:
272 - no-store 334 - no-store
273 Content-Security-Policy: 335 Content-Security-Policy:
274 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src 336 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
275 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; 337 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
276 style-src ''self'' http://localhost:3000 ''nonce-fMWth9zD7qWcG79MyycwRQ==''; 338 style-src ''self'' http://localhost:3000 ''nonce-VHNNI4iV+hIATnI9wOKj0w=='';
277 media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' 339 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
278 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' 340 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
279 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 341 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
@@ -291,8 +353,7 @@ interactions:
291 Vary: 353 Vary:
292 - Accept, Origin 354 - Accept, Origin
293 WWW-Authenticate: 355 WWW-Authenticate:
294 - Bearer realm="Doorkeeper", error="invalid_token", error_description="The access 356 - "Bearer realm=\"Doorkeeper\", error=\"invalid_token\", error_description=\"\xE3\x82\xA2\xE3\x82\xAF\xE3\x82\xBB\xE3\x82\xB9\xE3\x83\x88\xE3\x83\xBC\xE3\x82\xAF\xE3\x83\xB3\xE3\x81\xAF\xE5\x8F\x96\xE3\x82\x8A\xE6\xB6\x88\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xA6\xE3\x81\x84\xE3\x81\xBE\xE3\x81\x99\""
295 token is invalid"
296 X-Content-Type-Options: 357 X-Content-Type-Options:
297 - nosniff 358 - nosniff
298 X-Download-Options: 359 X-Download-Options:
@@ -302,9 +363,9 @@ interactions:
302 X-Permitted-Cross-Domain-Policies: 363 X-Permitted-Cross-Domain-Policies:
303 - none 364 - none
304 X-Request-Id: 365 X-Request-Id:
305 - 17a0fa0b-62a6-44ef-90a4-91a90dcd68c8 366 - ddb03e7b-25bf-4711-93a4-74e63bf8dbc5
306 X-Runtime: 367 X-Runtime:
307 - '0.005676' 368 - '0.008214'
308 X-XSS-Protection: 369 X-XSS-Protection:
309 - 1; mode=block 370 - 1; mode=block
310 status: 371 status:
diff --git a/tests/test_admin.py b/tests/test_admin.py
index f62b96b..6a72ed7 100644
--- a/tests/test_admin.py
+++ b/tests/test_admin.py
@@ -108,7 +108,14 @@ def test_admin_reports(api, api2, status):
108 report2 = api2.admin_report(report) 108 report2 = api2.admin_report(report)
109 assert(report2) 109 assert(report2)
110 assert(report2.id == report.id) 110 assert(report2.id == report.id)
111 111
112@pytest.mark.vcr()
113def test_admin_trends(api2):
114 assert isinstance(api2.admin_trending_tags(), list)
115 assert isinstance(api2.admin_trending_statuses(), list)
116 assert isinstance(api2.admin_trending_links(), list)
117 assert isinstance(api2.admin_trending_tags(limit=5), list)
118
112@pytest.mark.skip(reason="reject / accept of account requests isn't really testable without modifying instance settings. anyone want to fumble those into the DB setup and write this test, please do.") 119@pytest.mark.skip(reason="reject / accept of account requests isn't really testable without modifying instance settings. anyone want to fumble those into the DB setup and write this test, please do.")
113def test_admin_accountrequests(api2): 120def test_admin_accountrequests(api2):
114 pass 121 pass
diff --git a/tests/test_auth.py b/tests/test_auth.py
index a14b4e7..8a2337b 100644
--- a/tests/test_auth.py
+++ b/tests/test_auth.py
@@ -34,7 +34,7 @@ def test_log_in_password(api_anonymous):
34def test_revoke(api_anonymous): 34def test_revoke(api_anonymous):
35 token = api_anonymous.log_in( 35 token = api_anonymous.log_in(
36 username='mastodonpy_test_2@localhost:3000', 36 username='mastodonpy_test_2@localhost:3000',
37 password='5fc638e0e53eafd9c4145b6bb852667d' 37 password='5fc638e0e53eafd9c4145b6bb852667d',
38 ) 38 )
39 api_anonymous.revoke_access_token() 39 api_anonymous.revoke_access_token()
40 40
@@ -45,9 +45,9 @@ def test_revoke(api_anonymous):
45 print(e) 45 print(e)
46 pass 46 pass
47 47
48 api_revoked_token = Mastodon(access_token = token) 48 api_revoked_token = Mastodon(access_token = token, api_base_url='http://localhost:3000')
49 try: 49 try:
50 api_anonymous.toot("illegal access detected") 50 api_revoked_token.toot("illegal access detected")
51 assert False 51 assert False
52 except Exception as e: 52 except Exception as e:
53 print(e) 53 print(e)
Powered by cgit v1.2.3 (git 2.41.0)