kopia lustrzana https://github.com/halcy/Mastodon.py
add grouped notifications
rodzic
861d1c68d5
commit
2fde93fd3c
|
@ -43,6 +43,8 @@ v2.0.0 (IN PROGRESS)
|
|||
* Add `instance_domain_blocks`
|
||||
* Add notification policy and requests (`notifications_policy`, `update_notifications_policy`, `notifications_requests`, `notification_request`, `accept_notification_request`, `reject_notification_request`, `notifications_merged`, `accept_multiple_notification_requests`, `dismiss_multiple_notification_requests`)
|
||||
* Add `instance_languages`
|
||||
* Add notification grouping (`grouped_notifications`, `grouped_notification`, `dismiss_grouped_notification`, `grouped_notification_accounts`, `unread_grouped_notifications_count`)
|
||||
|
||||
|
||||
v1.8.1
|
||||
------
|
||||
|
|
|
@ -5,7 +5,7 @@ Notifications and filtering
|
|||
|
||||
Notifications
|
||||
-------------
|
||||
This function allows you to get information about a user's notifications as well as to clear all or some notifications and to mark conversations as read.
|
||||
These functions allow you to get information about a user's notifications as well as to clear all or some notifications and to mark conversations as read.
|
||||
|
||||
Reading
|
||||
~~~~~~~
|
||||
|
@ -19,6 +19,16 @@ Writing
|
|||
.. automethod:: Mastodon.conversations_read
|
||||
|
||||
|
||||
Grouped notifications
|
||||
---------------------
|
||||
This is the more modern notification API, which delivers notifications grouped.
|
||||
|
||||
.. automethod:: Mastodon.grouped_notifications
|
||||
.. automethod:: Mastodon.grouped_notification
|
||||
.. automethod:: Mastodon.dismiss_grouped_notification
|
||||
.. automethod:: Mastodon.grouped_notification_accounts
|
||||
.. automethod:: Mastodon.unread_grouped_notifications_count
|
||||
|
||||
Source filtering for notifications
|
||||
----------------------------------
|
||||
These functions allow you to get information about source filters as well as to create and update filters, and
|
||||
|
|
|
@ -85,7 +85,8 @@ class Mastodon():
|
|||
return try_cast_recurse(return_type, value)
|
||||
|
||||
def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, base_url_override=None,
|
||||
do_ratelimiting=True, use_json=False, parse=True, return_response_object=False, skip_error_check=False, lang_override=None, override_type=None):
|
||||
do_ratelimiting=True, use_json=False, parse=True, return_response_object=False, skip_error_check=False, lang_override=None, override_type=None,
|
||||
force_pagination=False):
|
||||
"""
|
||||
Internal API request helper.
|
||||
|
||||
|
@ -274,8 +275,8 @@ class Mastodon():
|
|||
response = response_object.content
|
||||
|
||||
# Parse link headers
|
||||
if isinstance(response, list) and 'Link' in response_object.headers and response_object.headers['Link'] != "":
|
||||
if not isinstance(response, PaginatableList):
|
||||
if isinstance(response, list) or force_pagination and 'Link' in response_object.headers and response_object.headers['Link'] != "":
|
||||
if not isinstance(response, PaginatableList) and not force_pagination:
|
||||
response = PaginatableList(response)
|
||||
tmp_urls = requests.utils.parse_header_links(response_object.headers['Link'].rstrip('>').replace('>,<', ',<'))
|
||||
for url in tmp_urls:
|
||||
|
|
|
@ -3,7 +3,7 @@ from mastodon.errors import MastodonIllegalArgumentError
|
|||
from mastodon.utility import api_version
|
||||
|
||||
from mastodon.internals import Mastodon as Internals
|
||||
from mastodon.return_types import Notification, IdType, PaginatableList, Account, UnreadNotificationsCount, NotificationPolicy, NotificationRequest
|
||||
from mastodon.return_types import Notification, IdType, PaginatableList, Account, UnreadNotificationsCount, NotificationPolicy, NotificationRequest, GroupedNotificationsResults, NonPaginatableList
|
||||
from typing import Union, Optional, List
|
||||
|
||||
class Mastodon(Internals):
|
||||
|
@ -183,3 +183,66 @@ class Mastodon(Internals):
|
|||
"""
|
||||
result = self.__api_request('GET', '/api/v1/notifications/requests/merged', override_type = dict)
|
||||
return result["merged"]
|
||||
|
||||
##
|
||||
# Grouped notifications
|
||||
##
|
||||
@api_version("4.3.0", "4.3.0")
|
||||
def grouped_notifications(self, max_id: Optional[IdType] = None, since_id: Optional[IdType] = None,
|
||||
min_id: Optional[IdType] = None, limit: Optional[int] = None,
|
||||
types: Optional[List[str]] = None, exclude_types: Optional[List[str]] = None,
|
||||
account_id: Optional[Union[Account, IdType]] = None,
|
||||
expand_accounts: Optional[str] = "partial_avatars", grouped_types: Optional[List[str]] = None,
|
||||
include_filtered: Optional[bool] = None) -> GroupedNotificationsResults:
|
||||
"""
|
||||
Fetch grouped notifications for the user. Requires scope `read:notifications`.
|
||||
|
||||
For base parameters, see `notifications()`.
|
||||
|
||||
`grouped_types` controls which notication types can be grouped together - all, if not specified.
|
||||
NB: "all" here means favourite, follow and reblog - other types are not groupable and are returned
|
||||
individually (with a unique group key) always.
|
||||
|
||||
Pass `include_filtered=True` to include filtered notifications in the response.
|
||||
|
||||
Pass `expand_accounts="full"` to include full account details in the response, or "partial_avatars" to
|
||||
include a smaller set of account details (in the `partial_accounts` field) for some (but not all - the most
|
||||
recent account triggering a notification is always returned in full) of the included accounts.
|
||||
The default is partial_avatars.
|
||||
"""
|
||||
params = self.__generate_params(locals())
|
||||
return self.__api_request('GET', '/api/v2/notifications', params, force_pagination=True)
|
||||
|
||||
@api_version("4.3.0", "4.3.0")
|
||||
def grouped_notification(self, group_key: str) -> GroupedNotificationsResults:
|
||||
"""
|
||||
Fetch details of a single grouped notification by its group key. Requires scope `read:notifications`.
|
||||
"""
|
||||
return self.__api_request('GET', f'/api/v2/notifications/{group_key}')
|
||||
|
||||
@api_version("4.3.0", "4.3.0")
|
||||
def dismiss_grouped_notification(self, group_key: str) -> None:
|
||||
"""
|
||||
Dismiss a single grouped notification. Requires scope `write:notifications`.
|
||||
"""
|
||||
self.__api_request('POST', f'/api/v2/notifications/{group_key}/dismiss')
|
||||
|
||||
@api_version("4.3.0", "4.3.0")
|
||||
def grouped_notification_accounts(self, group_key: str) -> NonPaginatableList[Account]:
|
||||
"""
|
||||
Fetch accounts associated with a grouped notification. Requires scope `write:notifications`.
|
||||
"""
|
||||
return self.__api_request('GET', f'/api/v2/notifications/{group_key}/accounts')
|
||||
|
||||
@api_version("4.3.0", "4.3.0")
|
||||
def unread_grouped_notifications_count(self, limit: Optional[int] = None,
|
||||
types: Optional[List[str]] = None, exclude_types: Optional[List[str]] = None,
|
||||
account_id: Optional[Union[Account, IdType]] = None,
|
||||
grouped_types: Optional[List[str]] = None) -> int:
|
||||
"""
|
||||
Fetch the count of unread grouped notifications. Requires scope `read:notifications`.
|
||||
|
||||
For parameters, see `notifications()` and `grouped_notifications()`.
|
||||
"""
|
||||
params = self.__generate_params(locals())
|
||||
return self.__api_request('GET', '/api/v2/notifications/unread_count', params, override_type=dict)["count"]
|
||||
|
|
|
@ -29,7 +29,8 @@ class Mastodon(Internals):
|
|||
def markers_get(self, timeline: Union[str, List[str]] = ["home"]) -> Dict[str, Marker]:
|
||||
"""
|
||||
Get the last-read-location markers for the specified timelines. Valid timelines
|
||||
are the same as in :ref:`timeline() <timeline()>`
|
||||
are `home` (the home timeline) and `notifications` (the notifications timeline,
|
||||
affects which notifications are considered read).
|
||||
|
||||
Note that despite the singular name, `timeline` can be a list.
|
||||
|
||||
|
@ -52,6 +53,9 @@ class Mastodon(Internals):
|
|||
"""
|
||||
Set the "last read" marker(s) for the given timeline(s) to the given id(s)
|
||||
|
||||
Valid timelines are `home` (the home timeline) and `notifications` (the notifications timeline,
|
||||
affects which notifications are considered read).
|
||||
|
||||
Note that if you give an invalid timeline name, this will silently do nothing.
|
||||
|
||||
Returns a dict with the updated markers, keyed by timeline name.
|
||||
|
|
|
@ -6330,6 +6330,22 @@ class GroupedNotificationsResults(AttribAccessDict):
|
|||
* 4.3.0: added
|
||||
"""
|
||||
|
||||
_pagination_next: "Optional[PaginationInfo]"
|
||||
"""
|
||||
Information about the next page of results. Added here as a special case to allow for pagination of the lists inside of this object. (optional)
|
||||
|
||||
Version history:
|
||||
* 4.3.0: added
|
||||
"""
|
||||
|
||||
_pagination_prev: "Optional[PaginationInfo]"
|
||||
"""
|
||||
Information about the previous page of results. Added here as a special case to allow for pagination of the lists inside of this object. (optional)
|
||||
|
||||
Version history:
|
||||
* 4.3.0: added
|
||||
"""
|
||||
|
||||
_version = "4.3.0"
|
||||
|
||||
class PartialAccountWithAvatar(AttribAccessDict):
|
||||
|
|
|
@ -11,8 +11,9 @@ from mastodon.internals import Mastodon as Internals
|
|||
|
||||
from mastodon.versions import parse_version_string, max_version, api_version
|
||||
|
||||
from typing import Optional
|
||||
from mastodon.return_types import PaginatableList, PaginationInfo
|
||||
from typing import Optional, Union, Dict
|
||||
from mastodon.return_types import PaginatableList, PaginationInfo, PaginatableList
|
||||
from mastodon.types_base import Entity
|
||||
|
||||
# Class level:
|
||||
class Mastodon(Internals):
|
||||
|
@ -118,7 +119,7 @@ class Mastodon(Internals):
|
|||
###
|
||||
# Pagination
|
||||
###
|
||||
def fetch_next(self, previous_page: PaginatableList) -> Optional[PaginatableList]:
|
||||
def fetch_next(self, previous_page: Union[PaginatableList[Entity], Entity, Dict]) -> Optional[Union[PaginatableList[Entity], Entity]]:
|
||||
"""
|
||||
Fetches the next page of results of a paginated request. Pass in the
|
||||
previous page in its entirety, or the pagination information dict
|
||||
|
@ -143,9 +144,12 @@ class Mastodon(Internals):
|
|||
endpoint = params['_pagination_endpoint']
|
||||
del params['_pagination_endpoint']
|
||||
|
||||
return self.__api_request(method, endpoint, params)
|
||||
force_pagination = False
|
||||
if not isinstance(previous_page, list):
|
||||
force_pagination = True
|
||||
return self.__api_request(method, endpoint, params, force_pagination=force_pagination, override_type=type(previous_page))
|
||||
|
||||
def fetch_previous(self, next_page: PaginatableList) -> Optional[PaginatableList]:
|
||||
def fetch_previous(self, next_page: Union[PaginatableList[Entity], Entity, Dict]) -> Optional[Union[PaginatableList[Entity], Entity]]:
|
||||
"""
|
||||
Fetches the previous page of results of a paginated request. Pass in the
|
||||
previous page in its entirety, or the pagination information dict
|
||||
|
@ -170,9 +174,12 @@ class Mastodon(Internals):
|
|||
endpoint = params['_pagination_endpoint']
|
||||
del params['_pagination_endpoint']
|
||||
|
||||
return self.__api_request(method, endpoint, params)
|
||||
force_pagination = False
|
||||
if not isinstance(next_page, list):
|
||||
force_pagination = True
|
||||
return self.__api_request(method, endpoint, params, force_pagination=force_pagination, override_type=type(next_page))
|
||||
|
||||
def fetch_remaining(self, first_page):
|
||||
def fetch_remaining(self, first_page: PaginatableList[Entity]) -> PaginatableList[Entity]:
|
||||
"""
|
||||
Fetches all the remaining pages of a paginated request starting from a
|
||||
first page and returns the entire set of results (including the first page
|
||||
|
@ -180,6 +187,9 @@ class Mastodon(Internals):
|
|||
|
||||
Be careful, as this might generate a lot of requests, depending on what you are
|
||||
fetching, and might cause you to run into rate limits very quickly.
|
||||
|
||||
Does not currently work with grouped notifications, please deal with those
|
||||
yourself, for now.
|
||||
"""
|
||||
first_page = copy.deepcopy(first_page)
|
||||
|
||||
|
|
|
@ -9462,7 +9462,7 @@
|
|||
"is_nullable": false
|
||||
},
|
||||
"notification_groups": {
|
||||
"description": "The grouped notifications themselves.",
|
||||
"description": "The grouped notifications themselves. Is actually in fact paginatable, but via the parent object.",
|
||||
"enum": null,
|
||||
"version_history": [["4.3.0", "added"]],
|
||||
"field_type": "NonPaginatableList",
|
||||
|
@ -9470,6 +9470,26 @@
|
|||
"field_structuretype": null,
|
||||
"is_optional": false,
|
||||
"is_nullable": false
|
||||
},
|
||||
"_pagination_next": {
|
||||
"description": "Information about the next page of results. Added here as a special case to allow for pagination of the lists inside of this object.",
|
||||
"enum": null,
|
||||
"version_history": [["4.3.0", "added"]],
|
||||
"field_type": "PaginationInfo",
|
||||
"field_subtype": null,
|
||||
"field_structuretype": null,
|
||||
"is_optional": true,
|
||||
"is_nullable": false
|
||||
},
|
||||
"_pagination_prev": {
|
||||
"description": "Information about the previous page of results. Added here as a special case to allow for pagination of the lists inside of this object.",
|
||||
"enum": null,
|
||||
"version_history": [["4.3.0", "added"]],
|
||||
"field_type": "PaginationInfo",
|
||||
"field_subtype": null,
|
||||
"field_structuretype": null,
|
||||
"is_optional": true,
|
||||
"is_nullable": false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,563 @@
|
|||
interactions:
|
||||
- request:
|
||||
body: status=Testing+grouped+notifications%21&visibility=public
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '57'
|
||||
Content-Type:
|
||||
- application/x-www-form-urlencoded
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v1/statuses
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eTesting
|
||||
grouped notifications!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1505'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"06fb25c4bf01795b2054bd152aeb8ef4"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.05, sql.active_record;dur=11.42, cache_generate.active_support;dur=3.55,
|
||||
cache_write.active_support;dur=0.15, instantiation.active_record;dur=0.54,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=4.50,
|
||||
render.active_model_serializers;dur=15.64, process_action.action_controller;dur=63.46
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '298'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T21:00:00.763790Z'
|
||||
X-Request-Id:
|
||||
- d4d9d0c4-0e3e-44ad-a7f8-c2b1dfa7efa3
|
||||
X-Runtime:
|
||||
- '0.093185'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '0'
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v1/statuses/114009357138722264/favourite
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":1,"edited_at":null,"favourited":true,"reblogged":false,"muted":false,"bookmarked":false,"content":"\u003cp\u003eTesting
|
||||
grouped notifications!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1489'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"3ac631610fb82fcfb82750e1f7adccf9"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.06, sql.active_record;dur=7.67, cache_generate.active_support;dur=3.17,
|
||||
cache_write.active_support;dur=0.13, instantiation.active_record;dur=0.67,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=6.21,
|
||||
render.active_model_serializers;dur=16.68, process_action.action_controller;dur=47.95
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.828950Z'
|
||||
X-Request-Id:
|
||||
- 6ec29c54-8c91-4b9f-9c88-275a236b5775
|
||||
X-Runtime:
|
||||
- '0.063835'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '0'
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v1/statuses/114009357138722264/favourite
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":2,"edited_at":null,"favourited":true,"reblogged":false,"muted":false,"bookmarked":false,"content":"\u003cp\u003eTesting
|
||||
grouped notifications!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1489'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"bfcc74cd78fb7eb5b1351bb0f8e1a5fb"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.05, sql.active_record;dur=7.32, cache_generate.active_support;dur=3.52,
|
||||
cache_write.active_support;dur=0.14, instantiation.active_record;dur=0.68,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=5.76,
|
||||
render.active_model_serializers;dur=14.78, process_action.action_controller;dur=48.71
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.926662Z'
|
||||
X-Request-Id:
|
||||
- f0f16848-82d0-457c-876c-9aa3e56deed7
|
||||
X-Runtime:
|
||||
- '0.063387'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: GET
|
||||
uri: http://localhost:3000/api/v2/notifications?limit=10&expand_accounts=partial_avatars
|
||||
response:
|
||||
body:
|
||||
string: '{"accounts":[{"id":"114009019470060047","username":"mastodonpy_test_2","acct":"mastodonpy_test_2","display_name":"","locked":false,"bot":false,"discoverable":true,"indexable":true,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test_2","uri":"http://localhost:3000/users/mastodonpy_test_2","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":0,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]}],"partial_accounts":[{"id":"114009019031846737","acct":"admin","locked":false,"bot":false,"url":"http://localhost:3000/@admin","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png"}],"statuses":[{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":2,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eTesting
|
||||
grouped notifications!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}],"notification_groups":[{"group_key":"favourite-114009357138722264-483234","notifications_count":2,"type":"favourite","most_recent_notification_id":190,"page_min_id":"190","page_max_id":"190","latest_page_notification_at":"2025-02-15T18:38:52.146Z","sample_account_ids":["114009019470060047","114009019031846737"],"status_id":"114009357138722264"}]}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '2901'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"e5e803ebda94a4f2c5aeb551c6ecd9ea"
|
||||
Link:
|
||||
- <http://localhost:3000/api/v2/notifications?limit=10&max_id=190>; rel="next",
|
||||
<http://localhost:3000/api/v2/notifications?limit=10&min_id=190>; rel="prev"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.10, sql.active_record;dur=9.10, cache_generate.active_support;dur=2.97,
|
||||
cache_write.active_support;dur=0.15, instantiation.active_record;dur=1.04,
|
||||
start_processing.action_controller;dur=0.00, cache_fetch_hit.active_support;dur=0.00,
|
||||
render.active_model_serializers;dur=5.52, process_action.action_controller;dur=58.12
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.028981Z'
|
||||
X-Request-Id:
|
||||
- fae9562c-f5be-4da1-af05-181bb7dd30f3
|
||||
X-Runtime:
|
||||
- '0.073893'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: GET
|
||||
uri: http://localhost:3000/api/v2/notifications/favourite-114009357138722264-483234
|
||||
response:
|
||||
body:
|
||||
string: '{"accounts":[{"id":"114009019470060047","username":"mastodonpy_test_2","acct":"mastodonpy_test_2","display_name":"","locked":false,"bot":false,"discoverable":true,"indexable":true,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test_2","uri":"http://localhost:3000/users/mastodonpy_test_2","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":0,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},{"id":"114009019031846737","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","uri":"http://localhost:3000/users/admin","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":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[{"id":"3","name":"Owner","color":""}],"fields":[]}],"statuses":[{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":2,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eTesting
|
||||
grouped notifications!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}],"notification_groups":[{"group_key":"favourite-114009357138722264-483234","notifications_count":2,"type":"favourite","most_recent_notification_id":190,"sample_account_ids":["114009019470060047","114009019031846737"],"status_id":"114009357138722264"}]}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '3295'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"b4015be5d4c161ff654954b9a12091f7"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.15, sql.active_record;dur=4.10, cache_generate.active_support;dur=2.80,
|
||||
cache_write.active_support;dur=0.13, instantiation.active_record;dur=1.19,
|
||||
start_processing.action_controller;dur=0.00, cache_fetch_hit.active_support;dur=0.01,
|
||||
render.active_model_serializers;dur=27.82, process_action.action_controller;dur=49.35
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.158661Z'
|
||||
X-Request-Id:
|
||||
- a0c00eab-c12d-4e1e-a03e-0c10eeab8de2
|
||||
X-Runtime:
|
||||
- '0.063807'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: GET
|
||||
uri: http://localhost:3000/api/v2/notifications/favourite-114009357138722264-483234/accounts
|
||||
response:
|
||||
body:
|
||||
string: '[{"id":"114009019470060047","username":"mastodonpy_test_2","acct":"mastodonpy_test_2","display_name":"","locked":false,"bot":false,"discoverable":true,"indexable":true,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test_2","uri":"http://localhost:3000/users/mastodonpy_test_2","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":0,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},{"id":"114009019031846737","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","uri":"http://localhost:3000/users/admin","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":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[{"id":"3","name":"Owner","color":""}],"fields":[]}]'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1512'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"fb8e14dd97709a52f5a45c9d4e447a24"
|
||||
Link:
|
||||
- <http://localhost:3000/api/v2/notifications/favourite-114009357138722264-483234/accounts?min_id=190>;
|
||||
rel="prev"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.08, sql.active_record;dur=1.64, cache_generate.active_support;dur=1.47,
|
||||
cache_write.active_support;dur=0.11, instantiation.active_record;dur=0.60,
|
||||
start_processing.action_controller;dur=0.01, cache_fetch_hit.active_support;dur=0.00,
|
||||
render.active_model_serializers;dur=3.89, process_action.action_controller;dur=27.45
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.295492Z'
|
||||
X-Request-Id:
|
||||
- 0e34fa26-6d71-4c7d-aeec-8eee17c493fb
|
||||
X-Runtime:
|
||||
- '0.056571'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '0'
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v2/notifications/favourite-114009357138722264-483234/dismiss
|
||||
response:
|
||||
body:
|
||||
string: '{}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '2'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"44136fa355b3678a1146ad16f7e8649e"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.02, sql.active_record;dur=7.02, cache_generate.active_support;dur=0.95,
|
||||
cache_write.active_support;dur=0.08, instantiation.active_record;dur=0.45,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=7.46,
|
||||
render.active_model_serializers;dur=0.03, process_action.action_controller;dur=30.07
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.366862Z'
|
||||
X-Request-Id:
|
||||
- 512683b1-cf01-497d-8e16-e853aae9d9c2
|
||||
X-Runtime:
|
||||
- '0.044774'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: GET
|
||||
uri: http://localhost:3000/api/v2/notifications?limit=10&expand_accounts=partial_avatars
|
||||
response:
|
||||
body:
|
||||
string: '{"accounts":[],"partial_accounts":[],"statuses":[],"notification_groups":[]}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '76'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"eda10f9499b0acd6b521397b2c54e608"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.04, sql.active_record;dur=1.65, cache_generate.active_support;dur=2.39,
|
||||
cache_write.active_support;dur=0.11, instantiation.active_record;dur=0.25,
|
||||
start_processing.action_controller;dur=0.00, render.active_model_serializers;dur=0.26,
|
||||
process_action.action_controller;dur=22.95
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:40:00.414885Z'
|
||||
X-Request-Id:
|
||||
- a16d6183-ac0e-4bb2-bb6d-4415200bb284
|
||||
X-Runtime:
|
||||
- '0.037428'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '0'
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: DELETE
|
||||
uri: http://localhost:3000/api/v1/statuses/114009357138722264
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114009357138722264","created_at":"2025-02-15T18:38:51.731Z","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/114009357138722264","url":"http://localhost:3000/@mastodonpy_test/114009357138722264","replies_count":0,"reblogs_count":0,"favourites_count":2,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"text":"Testing
|
||||
grouped notifications!","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"114009019326978043","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-15T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":0,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1475'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"61fa0386cc5fd7fcd2b5cbd617ebfb55"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.05, sql.active_record;dur=6.22, cache_generate.active_support;dur=2.83,
|
||||
cache_write.active_support;dur=0.17, instantiation.active_record;dur=0.75,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=3.13,
|
||||
render.active_model_serializers;dur=13.62, process_action.action_controller;dur=41.39
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '30'
|
||||
X-RateLimit-Remaining:
|
||||
- '29'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T19:00:00.460335Z'
|
||||
X-Request-Id:
|
||||
- d68ff7be-46c4-4ed4-8f9b-14792c89aa98
|
||||
X-Runtime:
|
||||
- '0.059427'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
|
@ -143,3 +143,70 @@ def test_notification_requests_accept(api, api2):
|
|||
for status in posted:
|
||||
api.status_delete(status)
|
||||
api2.update_notifications_policy(for_not_following="accept", for_not_followers="accept", for_new_accounts="accept", for_limited_accounts="accept", for_private_mentions="accept")
|
||||
|
||||
@pytest.mark.vcr()
|
||||
def test_grouped_notifications(api, api2, api3):
|
||||
try:
|
||||
status = api.status_post("Testing grouped notifications!", visibility="public")
|
||||
api2.status_favourite(status["id"])
|
||||
api3.status_favourite(status["id"])
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
grouped_notifs = api.grouped_notifications(limit=10, expand_accounts="partial_avatars")
|
||||
assert grouped_notifs
|
||||
assert hasattr(grouped_notifs, "_pagination_next")
|
||||
assert hasattr(grouped_notifs, "_pagination_prev")
|
||||
|
||||
group_keys = [group.group_key for group in grouped_notifs.notification_groups]
|
||||
assert any("favourite" in key or "reblog" in key for key in group_keys), "Expected a grouped notification"
|
||||
|
||||
group_key = group_keys[0] # Take first group
|
||||
single_grouped_notif = api.grouped_notification(group_key)
|
||||
assert single_grouped_notif
|
||||
assert single_grouped_notif.notification_groups[0].group_key == group_key
|
||||
|
||||
accounts = api.grouped_notification_accounts(group_key)
|
||||
assert isinstance(accounts, list)
|
||||
assert len(accounts) > 0
|
||||
|
||||
partial_accounts = [acc for acc in accounts if hasattr(acc, 'avatar_static')]
|
||||
assert len(partial_accounts) > 0, "Expected at least one partial account"
|
||||
|
||||
api.dismiss_grouped_notification(group_key)
|
||||
|
||||
updated_grouped_notifs = api.grouped_notifications(limit=10)
|
||||
updated_group_keys = [group.group_key for group in updated_grouped_notifs.notification_groups]
|
||||
assert group_key not in updated_group_keys, "Dismissed notification still appears"
|
||||
finally:
|
||||
api.status_delete(status["id"])
|
||||
|
||||
@pytest.mark.vcr()
|
||||
def test_grouped_notification_pagination(api, api2):
|
||||
try:
|
||||
# Post 10 statuses that mention api
|
||||
posted = []
|
||||
api_name = api.account_verify_credentials().username
|
||||
for i in range(10):
|
||||
posted.append(api2.status_post(f"@{api_name} hey how you doing - {i}!", visibility="public"))
|
||||
time.sleep(5)
|
||||
|
||||
grouped_notifs = api.grouped_notifications(limit=5, expand_accounts="full")
|
||||
assert len(grouped_notifs.notification_groups) == 5
|
||||
assert grouped_notifs._pagination_next
|
||||
assert grouped_notifs._pagination_prev
|
||||
|
||||
# Fetch next page
|
||||
next_notifs = api.fetch_next(grouped_notifs)
|
||||
assert len(next_notifs.notification_groups) == 5
|
||||
assert next_notifs._pagination_next
|
||||
assert next_notifs._pagination_prev
|
||||
|
||||
# Fetch previous page
|
||||
prev_notifs = api.fetch_previous(next_notifs)
|
||||
assert len(prev_notifs.notification_groups) == 5
|
||||
assert prev_notifs._pagination_next
|
||||
assert prev_notifs._pagination_prev
|
||||
finally:
|
||||
for status in posted:
|
||||
api2.status_delete(status["id"])
|
Ładowanie…
Reference in New Issue