Mocking mastodon server and more timeline support
Build and Release / run-terraform (push) Successful in 43s Details

This commit is contained in:
jfm 2024-05-01 20:41:01 +02:00
parent 00ba83e0b2
commit 9c2cb10fd4
12 changed files with 251 additions and 4 deletions

BIN
.coverage

Binary file not shown.

View File

@ -19,6 +19,7 @@ pytest-cov = "*"
bumpver = "*" bumpver = "*"
twine = "*" twine = "*"
build = "*" build = "*"
responses = "*"
[requires] [requires]
python_version = "3.12" python_version = "3.12"

67
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "33b12a5b029959f1e6600a02e05245c3a1d03e76abac6888c867dbfd5ff5270c" "sha256": "d3742f295ed54650736ca679ed6d8dac317b290d5c53ce74cc38b9239d95b558"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -758,6 +758,63 @@
"index": "pypi", "index": "pypi",
"version": "==5.0.0" "version": "==5.0.0"
}, },
"pyyaml": {
"hashes": [
"sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
"sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
"sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
"sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
"sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
"sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
"sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
"sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
"sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
"sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
"sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
"sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
"sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
"sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
"sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
"sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
"sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
"sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
"sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
"sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
"sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
"sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
"sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
"sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
"sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
"sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
"sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
"sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
"sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
"sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
"sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
"sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
"sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
"sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
"sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
"sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
"sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
"sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
"sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
"sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
"sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
"sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
"sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
"sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
"sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
"sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
"sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
"sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
"sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
],
"markers": "python_version >= '3.6'",
"version": "==6.0.1"
},
"readme-renderer": { "readme-renderer": {
"hashes": [ "hashes": [
"sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311", "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311",
@ -782,6 +839,14 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.0.0" "version": "==1.0.0"
}, },
"responses": {
"hashes": [
"sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66",
"sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a"
],
"index": "pypi",
"version": "==0.25.0"
},
"rfc3986": { "rfc3986": {
"hashes": [ "hashes": [
"sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd",

View File

@ -36,6 +36,7 @@ class MastodonAuthorization():
}) })
response_json = response.json() response_json = response.json()
logger.info(response_json)
if response.status_code == 200: if response.status_code == 200:
self.config.set_value("access_token", response_json["access_token"]) self.config.set_value("access_token", response_json["access_token"])
self.config.save() self.config.save()

View File

@ -8,9 +8,18 @@ class Timelines():
self.config = configuration self.config = configuration
self.auth = authorization self.auth = authorization
def home_timeline(self): def home_timeline(self, min_id=None, max_id=None, since_id=None, limit=None):
url = "https://"+self.config.get_value("server")+"/api/v1/timelines/home" url = "https://"+self.config.get_value("server")+"/api/v1/timelines/home"
response = requests.get(url, headers=self.auth.get_auth_headers()) parameters = dict()
return response.json() if(min_id is not None):
parameters["min_id"] = min_id
if(max_id is not None):
parameters["max_id"] = max_id
if(since_id is not None):
parameters["since_id"] = since_id
if(limit is not None):
parameters["limit"] = limit
response = requests.get(url, headers=self.auth.get_auth_headers(), params=parameters)
return response.json()

View File

@ -0,0 +1 @@
{"access_token": "-Us2pbm240grRk1AtDV8WR2LKGdXxSgmijS9hDTN_UU", "token_type": "Bearer", "scope": "read write follow", "created_at": 1714575791}

View File

@ -0,0 +1 @@
{"id": "23", "name": "pymastodon", "website": null, "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", "client_id": "eCOa1SxyccrfUBcimdntj6USlf7ythGlLnCFvYDHD5E", "client_secret": "eugdHJ7ckwukrPJmT09lrl8DBLbAmLdonsrQNjvMfIA", "vapid_key": "BH5OXv4oZ56KihDwvApTep3us7Ex2c7bnYVDpfM8CCnkSNC64bj_22NZwoYCVczleMj08xxT5nkupjS8c-ldDdo="}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,79 @@
[{
"id": "103270115826048975",
"created_at": "2019-12-08T03:48:33.901Z",
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"sensitive": false,
"spoiler_text": "",
"visibility": "public",
"language": "en",
"uri": "https://mastodon.social/users/Gargron/statuses/103270115826048975",
"url": "https://mastodon.social/@Gargron/103270115826048975",
"replies_count": 5,
"reblogs_count": 6,
"favourites_count": 11,
"favourited": false,
"reblogged": false,
"muted": false,
"bookmarked": false,
"content": "<p>&quot;I lost my inheritance with one wrong digit on my sort code&quot;</p><p><a href=\"https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">theguardian.com/money/2019/dec</span><span class=\"invisible\">/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code</span}</p>",
"reblog": null,
"application": {
"name": "Web",
"website": null
},
"account": {
"id": "1",
"username": "Gargron",
"acct": "Gargron",
"display_name": "Eugen",
"locked": false,
"bot": false,
"discoverable": true,
"group": false,
"created_at": "2016-03-16T14:34:26.392Z",
"note": "<p>Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.</p>",
"url": "https://mastodon.social/@Gargron",
"avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg",
"avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg",
"header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png",
"header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png",
"followers_count": 322930,
"following_count": 459,
"statuses_count": 61323,
"last_status_at": "2019-12-10T08:14:44.811Z",
"emojis": [],
"fields": [
{
"name": "Patreon",
"value": "<a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span}",
"verified_at": null
},
{
"name": "Homepage",
"value": "<a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span}",
"verified_at": "2019-07-15T18:29:57.191+00:00"
}
]
},
"media_attachments": [],
"mentions": [],
"tags": [],
"emojis": [],
"card": {
"url": "https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code",
"title": "I lost my £193,000 inheritance with one wrong digit on my sort code",
"description": "When Peter Teichs money went to another Barclays customer, the bank offered £25 as a token gesture",
"type": "link",
"author_name": "",
"author_url": "",
"provider_name": "",
"provider_url": "",
"html": "",
"width": 0,
"height": 0,
"image": null,
"embed_url": ""
},
"poll": null
}]

View File

@ -1,11 +1,20 @@
from mastodon.application import MastodonApplication from mastodon.application import MastodonApplication
import pytest import pytest
import responses
@pytest.fixture @pytest.fixture
def app(): def app():
yield MastodonApplication("pymastodon") yield MastodonApplication("pymastodon")
@responses.activate
def test_authorize(app): def test_authorize(app):
# responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
# json={'error': 'not found'}, status=404)
responses.post(
"http://social.example.com/oauth/token",
json={"type": "post"},
)
app.authorization.authorize() app.authorization.authorize()
token = app.authorization.fetch_token() token = app.authorization.fetch_token()
assert token is not None assert token is not None

View File

@ -5,6 +5,10 @@ import json
def test_status_parse(): def test_status_parse():
Status.model_validate(json_reader("./tests/resources/status.json")) Status.model_validate(json_reader("./tests/resources/status.json"))
#def test_status_reblog_parse():
# Status.model_validate(json_reader("./tests/resources/status_reblog.json"))
def json_reader(path): def json_reader(path):
with open(path) as f: with open(path) as f:
return json.load(f) return json.load(f)

View File

@ -2,14 +2,19 @@ from mastodon.application import MastodonApplication
from mastodon.timelines import Timelines from mastodon.timelines import Timelines
from mastodon.model.status import Status from mastodon.model.status import Status
from loguru import logger from loguru import logger
import json
import pytest import pytest
from responses import matchers
import responses
@pytest.fixture @pytest.fixture
def app(): def app():
yield MastodonApplication("pymastodon") yield MastodonApplication("pymastodon")
@responses.activate
def test_home_timeline(app): def test_home_timeline(app):
responses.get("https://social.example.com/api/v1/timelines/home", json=json_reader("./tests/resources/timeline_home_response.json"))
response = app.timelines.home_timeline() response = app.timelines.home_timeline()
assert response is not None assert response is not None
statuses = [] statuses = []
@ -19,3 +24,74 @@ def test_home_timeline(app):
except Exception as ve: except Exception as ve:
logger.debug(status) logger.debug(status)
logger.error(ve) logger.error(ve)
@responses.activate
def test_home_timeline_max_id(app):
params = {"max_id": "1"}
responses.get("https://social.example.com/api/v1/timelines/home",
json=json_reader("./tests/resources/timeline_home_response.json"),
match=[matchers.query_param_matcher(params)])
response = app.timelines.home_timeline(max_id="1")
assert response is not None
statuses = []
for status in response:
try:
statuses.append(Status.model_validate(status))
except Exception as ve:
logger.debug(status)
logger.error(ve)
@responses.activate
def test_home_timeline_min_id(app):
params = {"min_id": "1"}
responses.get("https://social.example.com/api/v1/timelines/home",
json=json_reader("./tests/resources/timeline_home_response.json"),
match=[matchers.query_param_matcher(params)])
response = app.timelines.home_timeline(min_id="1")
assert response is not None
statuses = []
for status in response:
try:
statuses.append(Status.model_validate(status))
except Exception as ve:
logger.debug(status)
logger.error(ve)
@responses.activate
def test_home_timeline_since_id(app):
params = {"since_id": "1"}
responses.get("https://social.example.com/api/v1/timelines/home",
json=json_reader("./tests/resources/timeline_home_response.json"),
match=[matchers.query_param_matcher(params)])
response = app.timelines.home_timeline(since_id="1")
assert response is not None
statuses = []
for status in response:
try:
statuses.append(Status.model_validate(status))
except Exception as ve:
logger.debug(status)
logger.error(ve)
@responses.activate
def test_home_timeline_limt(app):
params = {"limit": "1"}
responses.get("https://social.example.com/api/v1/timelines/home",
json=json_reader("./tests/resources/timeline_home_response.json"),
match=[matchers.query_param_matcher(params)])
response = app.timelines.home_timeline(limit="1")
assert response is not None
statuses = []
for status in response:
try:
statuses.append(Status.model_validate(status))
except Exception as ve:
logger.debug(status)
logger.error(ve)
def json_reader(path):
with open(path) as f:
return json.load(f)
#match=[matchers.query_param_matcher(params)],