aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md1
-rw-r--r--docs/conf.py2
-rw-r--r--docs/index.rst2
-rw-r--r--mastodon/Mastodon.py2
-rw-r--r--setup.py2
-rw-r--r--tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pklbin0 -> 21 bytes
-rw-r--r--tests/cassettes_special/test_scheduled_status_long_part1.yaml133
-rw-r--r--tests/cassettes_special/test_scheduled_status_long_part2.yaml73
-rw-r--r--tests/cassettes_special/test_scheduled_status_long_text.pklbin0 -> 75 bytes
-rw-r--r--tests/test_status.py28
10 files changed, 239 insertions, 4 deletions
diff --git a/TODO.md b/TODO.md
index ce01ec1..7f27e51 100644
--- a/TODO.md
+++ b/TODO.md
@@ -65,3 +65,4 @@ General improvements that would be good to do before doing another release:
65* [ ] Split mastodon.py into parts in some way that makes sense, it's getting very unwieldy 65* [ ] Split mastodon.py into parts in some way that makes sense, it's getting very unwieldy
66* [x] Fix the CI 66* [x] Fix the CI
67* [ ] Get test coverage like, real high 67* [ ] Get test coverage like, real high
68* [ ] Add all those streaming events??
diff --git a/docs/conf.py b/docs/conf.py
index 0ab6777..c6fc0fb 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -68,7 +68,7 @@ author = u'Lorenz Diener'
68# The short X.Y version. 68# The short X.Y version.
69version = u'1.6' 69version = u'1.6'
70# The full version, including alpha/beta/rc tags. 70# The full version, including alpha/beta/rc tags.
71release = u'1.6.1' 71release = u'1.6.2'
72 72
73# The language for content autogenerated by Sphinx. Refer to documentation 73# The language for content autogenerated by Sphinx. Refer to documentation
74# for a list of supported languages. 74# for a list of supported languages.
diff --git a/docs/index.rst b/docs/index.rst
index 7fc59d2..7c4f200 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -135,7 +135,7 @@ since the IDs used are Snowflake IDs and dates can be approximately converted to
135This is guaranteed to work on mainline Mastodon servers and very likely to work on all 135This is guaranteed to work on mainline Mastodon servers and very likely to work on all
136forks, but will **not** work on other servers implementing the API, like Pleroma, Misskey 136forks, but will **not** work on other servers implementing the API, like Pleroma, Misskey
137or Gotosocial. You should not use this if you want your application to be universally 137or Gotosocial. You should not use this if you want your application to be universally
138compatible. 138compatible. It's also relatively coarse-grained.
139 139
140`limit` allows you to specify how many results you would like returned. Note that an 140`limit` allows you to specify how many results you would like returned. Note that an
141instance may choose to return less results than you requested - by default, Mastodon 141instance may choose to return less results than you requested - by default, Mastodon
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 493d485..f49df83 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -3934,6 +3934,8 @@ class Mastodon:
3934 Checks if id is a dict that contains id and 3934 Checks if id is a dict that contains id and
3935 returns the id inside, otherwise just returns 3935 returns the id inside, otherwise just returns
3936 the id straight. 3936 the id straight.
3937
3938 Also unpacks datetimes to snowflake IDs if requested.
3937 """ 3939 """
3938 if isinstance(id, dict) and "id" in id: 3940 if isinstance(id, dict) and "id" in id:
3939 id = id["id"] 3941 id = id["id"]
diff --git a/setup.py b/setup.py
index ff5fab7..98ed7de 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@ extras = {
26} 26}
27 27
28setup(name='Mastodon.py', 28setup(name='Mastodon.py',
29 version='1.6.1', 29 version='1.6.2',
30 description='Python wrapper for the Mastodon API', 30 description='Python wrapper for the Mastodon API',
31 packages=['mastodon'], 31 packages=['mastodon'],
32 install_requires=[ 32 install_requires=[
diff --git a/tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl b/tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl
new file mode 100644
index 0000000..0d2f0c1
--- /dev/null
+++ b/tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl
Binary files differ
diff --git a/tests/cassettes_special/test_scheduled_status_long_part1.yaml b/tests/cassettes_special/test_scheduled_status_long_part1.yaml
new file mode 100644
index 0000000..0d83523
--- /dev/null
+++ b/tests/cassettes_special/test_scheduled_status_long_part1.yaml
@@ -0,0 +1,133 @@
1interactions:
2- request:
3 body: status=please+ensure+maximum+headroom+at+2022-11-19+00%3A13%3A28.641336&scheduled_at=2022-11-18T22%3A13%3A28%2B00%3A00
4 headers:
5 Accept:
6 - '*/*'
7 Accept-Encoding:
8 - gzip, deflate
9 Authorization:
10 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
11 Connection:
12 - keep-alive
13 Content-Length:
14 - '118'
15 Content-Type:
16 - application/x-www-form-urlencoded
17 User-Agent:
18 - tests/v311
19 method: POST
20 uri: http://localhost:3000/api/v1/statuses
21 response:
22 body:
23 string: '{"id":"5","scheduled_at":"2022-11-18T22:13:28.000Z","params":{"text":"please
24 ensure maximum headroom at 2022-11-19 00:13:28.641336","media_ids":null,"sensitive":null,"spoiler_text":null,"visibility":null,"language":null,"scheduled_at":null,"poll":null,"idempotency":null,"with_rate_limit":false,"in_reply_to_id":null,"application_id":1234567890123456},"media_attachments":[]}'
25 headers:
26 Cache-Control:
27 - no-store
28 Content-Security-Policy:
29 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
30 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
31 style-src ''self'' http://localhost:3000 ''nonce-oDT7L0vwLx8ThpkVmR2WkQ=='';
32 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
33 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
34 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
35 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
36 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
37 worker-src ''self'' blob: http://localhost:3000'
38 Content-Type:
39 - application/json; charset=utf-8
40 ETag:
41 - W/"961ec598899e68bf0f28ef2d0339120d"
42 Referrer-Policy:
43 - strict-origin-when-cross-origin
44 Transfer-Encoding:
45 - chunked
46 Vary:
47 - Accept, Origin
48 X-Content-Type-Options:
49 - nosniff
50 X-Download-Options:
51 - noopen
52 X-Frame-Options:
53 - SAMEORIGIN
54 X-Permitted-Cross-Domain-Policies:
55 - none
56 X-RateLimit-Limit:
57 - '300'
58 X-RateLimit-Remaining:
59 - '300'
60 X-RateLimit-Reset:
61 - '2022-11-19T00:00:00.671086Z'
62 X-Request-Id:
63 - 3ccd3249-4aa7-4366-8722-caaa9c427e6f
64 X-Runtime:
65 - '0.025260'
66 X-XSS-Protection:
67 - 1; mode=block
68 status:
69 code: 200
70 message: OK
71- request:
72 body: null
73 headers:
74 Accept:
75 - '*/*'
76 Accept-Encoding:
77 - gzip, deflate
78 Authorization:
79 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
80 Connection:
81 - keep-alive
82 User-Agent:
83 - tests/v311
84 method: GET
85 uri: http://localhost:3000/api/v1/scheduled_statuses
86 response:
87 body:
88 string: '[{"id":"5","scheduled_at":"2022-11-18T22:13:28.000Z","params":{"poll":null,"text":"please
89 ensure maximum headroom at 2022-11-19 00:13:28.641336","language":null,"media_ids":null,"sensitive":null,"visibility":null,"idempotency":null,"scheduled_at":null,"spoiler_text":null,"application_id":1234567890123456,"in_reply_to_id":null,"with_rate_limit":false},"media_attachments":[]},{"id":"4","scheduled_at":"2022-11-18T22:12:21.000Z","params":{"poll":null,"text":"please
90 ensure maximum headroom at 2022-11-19 00:12:21.805020","language":null,"media_ids":null,"sensitive":null,"visibility":null,"idempotency":null,"scheduled_at":null,"spoiler_text":null,"application_id":1234567890123456,"in_reply_to_id":null,"with_rate_limit":false},"media_attachments":[]}]'
91 headers:
92 Cache-Control:
93 - no-store
94 Content-Security-Policy:
95 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
96 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
97 style-src ''self'' http://localhost:3000 ''nonce-vlVvEXWNgaJdWW23jKfZqA=='';
98 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
99 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
100 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
101 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
102 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
103 worker-src ''self'' blob: http://localhost:3000'
104 Content-Type:
105 - application/json; charset=utf-8
106 ETag:
107 - W/"41f6a2d732beea8c5ef0286133506b91"
108 Link:
109 - <http://localhost:3000/api/v1/scheduled_statuses?min_id=5>; rel="prev"
110 Referrer-Policy:
111 - strict-origin-when-cross-origin
112 Transfer-Encoding:
113 - chunked
114 Vary:
115 - Accept, Origin
116 X-Content-Type-Options:
117 - nosniff
118 X-Download-Options:
119 - noopen
120 X-Frame-Options:
121 - SAMEORIGIN
122 X-Permitted-Cross-Domain-Policies:
123 - none
124 X-Request-Id:
125 - 8194fc5d-2433-4359-8d25-3a0446703c61
126 X-Runtime:
127 - '0.011068'
128 X-XSS-Protection:
129 - 1; mode=block
130 status:
131 code: 200
132 message: OK
133version: 1
diff --git a/tests/cassettes_special/test_scheduled_status_long_part2.yaml b/tests/cassettes_special/test_scheduled_status_long_part2.yaml
new file mode 100644
index 0000000..e14812d
--- /dev/null
+++ b/tests/cassettes_special/test_scheduled_status_long_part2.yaml
@@ -0,0 +1,73 @@
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
11 Connection:
12 - keep-alive
13 User-Agent:
14 - tests/v311
15 method: GET
16 uri: http://localhost:3000/api/v1/timelines/home
17 response:
18 body:
19 string: '[{"id":"109367106569496287","created_at":"2022-11-18T22:13:29.521Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109367106569496287","url":"http://localhost:3000/@mastodonpy_test/109367106569496287","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eplease
20 ensure maximum headroom at 2022-11-19 00:13:28.641336\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
21 test suite","website":null},"account":{"id":"109366898092282937","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-18T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":5,"last_status_at":"2022-11-18","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null},{"id":"109367102188706324","created_at":"2022-11-18T22:12:22.677Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109367102188706324","url":"http://localhost:3000/@mastodonpy_test/109367102188706324","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eplease
22 ensure maximum headroom at 2022-11-19 00:12:21.805020\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
23 test suite","website":null},"account":{"id":"109366898092282937","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-18T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":5,"last_status_at":"2022-11-18","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null},{"id":"109367045979515008","created_at":"2022-11-18T21:58:04.992Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109367045979515008","url":"http://localhost:3000/@mastodonpy_test/109367045979515008","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eplease
24 ensure maximum headroom\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
25 test suite","website":null},"account":{"id":"109366898092282937","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-18T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":5,"last_status_at":"2022-11-18","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null},{"id":"109367033669585768","created_at":"2022-11-18T21:54:57.158Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109367033669585768","url":"http://localhost:3000/@mastodonpy_test/109367033669585768","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eplease
26 ensure maximum headroom\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
27 test suite","website":null},"account":{"id":"109366898092282937","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-18T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":5,"last_status_at":"2022-11-18","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null},{"id":"109366923399768814","created_at":"2022-11-18T21:26:54.583Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109366923399768814","url":"http://localhost:3000/@mastodonpy_test/109366923399768814","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eplease
28 ensure maximum headroom\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
29 test suite","website":null},"account":{"id":"109366898092282937","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-18T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":5,"last_status_at":"2022-11-18","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}]'
30 headers:
31 Cache-Control:
32 - no-store
33 Content-Security-Policy:
34 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
35 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
36 style-src ''self'' http://localhost:3000 ''nonce-wSHlCFIT+OKGZueB4x1jVg=='';
37 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
38 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
39 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
40 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
41 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
42 worker-src ''self'' blob: http://localhost:3000'
43 Content-Type:
44 - application/json; charset=utf-8
45 ETag:
46 - W/"ea8a50776524b19f4a57fc911b5836e5"
47 Link:
48 - <http://localhost:3000/api/v1/timelines/home?max_id=109366923399768814>; rel="next",
49 <http://localhost:3000/api/v1/timelines/home?min_id=109367106569496287>; rel="prev"
50 Referrer-Policy:
51 - strict-origin-when-cross-origin
52 Transfer-Encoding:
53 - chunked
54 Vary:
55 - Accept, Origin
56 X-Content-Type-Options:
57 - nosniff
58 X-Download-Options:
59 - noopen
60 X-Frame-Options:
61 - SAMEORIGIN
62 X-Permitted-Cross-Domain-Policies:
63 - none
64 X-Request-Id:
65 - a394cd1c-0cdc-47ea-9eb9-9a76402d8e2b
66 X-Runtime:
67 - '0.038512'
68 X-XSS-Protection:
69 - 1; mode=block
70 status:
71 code: 200
72 message: OK
73version: 1
diff --git a/tests/cassettes_special/test_scheduled_status_long_text.pkl b/tests/cassettes_special/test_scheduled_status_long_text.pkl
new file mode 100644
index 0000000..e455ae5
--- /dev/null
+++ b/tests/cassettes_special/test_scheduled_status_long_text.pkl
Binary files differ
diff --git a/tests/test_status.py b/tests/test_status.py
index 5c139e6..20e32f2 100644
--- a/tests/test_status.py
+++ b/tests/test_status.py
@@ -186,4 +186,30 @@ def test_scheduled_status(api):
186 scheduled_toot_list_3 = api.scheduled_statuses() 186 scheduled_toot_list_3 = api.scheduled_statuses()
187 assert scheduled_toot_4.id in map(lambda x: x.id, statuses) 187 assert scheduled_toot_4.id in map(lambda x: x.id, statuses)
188 assert not scheduled_toot_4.id in map(lambda x: x.id, scheduled_toot_list_3) 188 assert not scheduled_toot_4.id in map(lambda x: x.id, scheduled_toot_list_3)
189 \ No newline at end of file 189
190# The following two tests need to be manually (!) ran 10 minutes apart when recording.
191# Sorry, I can't think of a better way to test scheduled statuses actually work as intended.
192@pytest.mark.vcr(match_on=['path'])
193def test_scheduled_status_long_part1(api):
194 with vcr.use_cassette('test_scheduled_status_long_part1.yaml', cassette_library_dir='tests/cassettes_special', record_mode='once'):
195 if os.path.exists("tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl"):
196 the_medium_term_future = datetime.datetime.fromtimestamp(pickle.load(open("tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl", 'rb')))
197 else:
198 the_medium_term_future = datetime.datetime.now() + datetime.timedelta(minutes=6)
199 pickle.dump(the_medium_term_future.timestamp(), open("tests/cassettes_special/test_scheduled_status_long_datetimeobjects.pkl", 'wb'))
200 scheduled_toot = api.status_post("please ensure maximum headroom at " + str(the_medium_term_future), scheduled_at=the_medium_term_future)
201 scheduled_toot_list = api.scheduled_statuses()
202 assert scheduled_toot.id in map(lambda x: x.id, scheduled_toot_list)
203 pickle.dump(scheduled_toot.params.text, open("tests/cassettes_special/test_scheduled_status_long_text.pkl", 'wb'))
204
205@pytest.mark.vcr(match_on=['path'])
206def test_scheduled_status_long_part2(api):
207 with vcr.use_cassette('test_scheduled_status_long_part2.yaml', cassette_library_dir='tests/cassettes_special', record_mode='once'):
208 text = pickle.load(open("tests/cassettes_special/test_scheduled_status_long_text.pkl", 'rb'))
209 statuses = api.timeline_home()
210 print(text)
211 found_status = False
212 for status in statuses:
213 if text in status.content:
214 found_status = True
215 assert found_status
Powered by cgit v1.2.3 (git 2.41.0)