This commit is contained in:
firedotguy
2026-02-06 21:43:12 +03:00
6 changed files with 179 additions and 48 deletions

View File

@@ -10,7 +10,7 @@ from itd.routes.etc import get_top_clans, get_who_to_follow, get_platform_status
from itd.routes.comments import get_comments, add_comment, delete_comment, like_comment, unlike_comment, add_reply_comment from itd.routes.comments import get_comments, add_comment, delete_comment, like_comment, unlike_comment, add_reply_comment
from itd.routes.hashtags import get_hashtags, get_posts_by_hashtag from itd.routes.hashtags import get_hashtags, get_posts_by_hashtag
from itd.routes.notifications import get_notifications, mark_as_read, mark_all_as_read, get_unread_notifications_count from itd.routes.notifications import get_notifications, mark_as_read, mark_all_as_read, get_unread_notifications_count
from itd.routes.posts import create_post, get_posts, get_post, edit_post, delete_post, pin_post, repost, view_post, get_liked_posts from itd.routes.posts import create_post, get_posts, get_post, edit_post, delete_post, pin_post, repost, view_post, get_liked_posts, restore_post, like_post, delete_like_post
from itd.routes.reports import report from itd.routes.reports import report
from itd.routes.search import search from itd.routes.search import search
from itd.routes.files import upload_file from itd.routes.files import upload_file
@@ -19,7 +19,7 @@ from itd.routes.verification import verify, get_verification_status
from itd.models.comment import Comment from itd.models.comment import Comment
from itd.models.notification import Notification from itd.models.notification import Notification
from itd.models.post import Post, NewPost from itd.models.post import Post, NewPost, LikePostResponse
from itd.models.clan import Clan from itd.models.clan import Clan
from itd.models.hashtag import Hashtag from itd.models.hashtag import Hashtag
from itd.models.user import User, UserProfileUpdate, UserPrivacy, UserFollower, UserWhoToFollow from itd.models.user import User, UserProfileUpdate, UserPrivacy, UserFollower, UserWhoToFollow
@@ -158,14 +158,14 @@ class Client:
return self.get_user('me') return self.get_user('me')
@refresh_on_error @refresh_on_error
def update_profile(self, username: str | None = None, display_name: str | None = None, bio: str | None = None, banner_id: UUID | None = None) -> UserProfileUpdate: def update_profile(self, username: str | None = None, display_name: str | None = None, bio: str | None = None, banner_id: UUID | str | None = None) -> UserProfileUpdate:
"""Обновить профиль """Обновить профиль
Args: Args:
username (str | None, optional): username. Defaults to None. username (str | None, optional): username. Defaults to None.
display_name (str | None, optional): Отображаемое имя. Defaults to None. display_name (str | None, optional): Отображаемое имя. Defaults to None.
bio (str | None, optional): Биография (о себе). Defaults to None. bio (str | None, optional): Биография (о себе). Defaults to None.
banner_id (UUID | None, optional): UUID баннера. Defaults to None. banner_id (UUID | str | None, optional): UUID баннера. Defaults to None.
Raises: Raises:
ValidationError: Ошибка валидации ValidationError: Ошибка валидации
@@ -173,6 +173,9 @@ class Client:
Returns: Returns:
UserProfileUpdate: Обновленный профиль UserProfileUpdate: Обновленный профиль
""" """
if isinstance(banner_id, str):
banner_id = UUID(banner_id)
res = update_profile(self.token, bio, display_name, username, banner_id) res = update_profile(self.token, bio, display_name, username, banner_id)
if res.status_code == 422 and 'found' in res.json(): if res.status_code == 422 and 'found' in res.json():
raise ValidationError(*list(res.json()['found'].items())[0]) raise ValidationError(*list(res.json()['found'].items())[0])
@@ -373,14 +376,13 @@ class Client:
@refresh_on_error @refresh_on_error
def add_comment(self, post_id: UUID, content: str, attachment_ids: list[UUID] = []) -> Comment: def add_comment(self, post_id: UUID | str, content: str, attachment_ids: list[UUID | str] = []) -> Comment:
"""Добавить комментарий """Добавить комментарий
Args: Args:
post_id (str): UUID поста post_id (str | UUID): UUID поста
content (str): Содержание content (str): Содержание
attachment_ids (list[UUID]): Список UUID прикреплённых файлов attachment_ids (list[UUID | str]): Список UUID прикреплённых файлов
reply_comment_id (UUID | None, optional): ID коммента для ответа. Defaults to None.
Raises: Raises:
ValidationError: Ошибка валидации ValidationError: Ошибка валидации
@@ -389,6 +391,10 @@ class Client:
Returns: Returns:
Comment: Комментарий Comment: Комментарий
""" """
if isinstance(post_id, str):
post_id = UUID(post_id)
attachment_ids = list(map(lambda id: UUID(id) if isinstance(id, str) else id, attachment_ids))
res = add_comment(self.token, post_id, content, attachment_ids) res = add_comment(self.token, post_id, content, attachment_ids)
if res.status_code == 422 and 'found' in res.json(): if res.status_code == 422 and 'found' in res.json():
raise ValidationError(*list(res.json()['found'].items())[0]) raise ValidationError(*list(res.json()['found'].items())[0])
@@ -400,14 +406,14 @@ class Client:
@refresh_on_error @refresh_on_error
def add_reply_comment(self, comment_id: UUID, content: str, author_id: UUID, attachment_ids: list[UUID] = []) -> Comment: def add_reply_comment(self, comment_id: UUID | str, content: str, author_id: UUID | str, attachment_ids: list[UUID | str] = []) -> Comment:
"""Добавить ответный комментарий """Добавить ответный комментарий
Args: Args:
comment_id (str): UUID комментария comment_id (str | UUID): UUID комментария
content (str): Содержание content (str): Содержание
author_id (UUID | None, optional): ID пользователя, отправившего комментарий. Defaults to None. author_id (UUID | str): ID пользователя, отправившего комментарий.
attachment_ids (list[UUID]): Список UUID прикреплённых файлов attachment_ids (list[UUID | str]): Список UUID прикреплённых файлов
Raises: Raises:
ValidationError: Ошибка валидации ValidationError: Ошибка валидации
@@ -416,6 +422,12 @@ class Client:
Returns: Returns:
Comment: Комментарий Comment: Комментарий
""" """
if isinstance(comment_id, str):
comment_id = UUID(comment_id)
if isinstance(author_id, str):
author_id = UUID(author_id)
attachment_ids = list(map(lambda id: UUID(id) if isinstance(id, str) else id, attachment_ids))
res = add_reply_comment(self.token, comment_id, content, author_id, attachment_ids) res = add_reply_comment(self.token, comment_id, content, author_id, attachment_ids)
if res.status_code == 500 and 'Failed query' in res.text: if res.status_code == 500 and 'Failed query' in res.text:
raise NotFound('User') raise NotFound('User')
@@ -429,11 +441,11 @@ class Client:
@refresh_on_error @refresh_on_error
def get_comments(self, post_id: UUID, limit: int = 20, cursor: int = 0, sort: str = 'popular') -> tuple[list[Comment], Pagination]: def get_comments(self, post_id: UUID | str, limit: int = 20, cursor: int = 0, sort: str = 'popular') -> tuple[list[Comment], Pagination]:
"""Получить список комментариев """Получить список комментариев
Args: Args:
post_id (UUID): UUID поста post_id (UUID | str): UUID поста
limit (int, optional): Лимит. Defaults to 20. limit (int, optional): Лимит. Defaults to 20.
cursor (int, optional): Курсор (сколько пропустить). Defaults to 0. cursor (int, optional): Курсор (сколько пропустить). Defaults to 0.
sort (str, optional): Сортировка. Defaults to 'popular'. sort (str, optional): Сортировка. Defaults to 'popular'.
@@ -445,6 +457,9 @@ class Client:
list[Comment]: Список комментариев list[Comment]: Список комментариев
Pagination: Пагинация Pagination: Пагинация
""" """
if isinstance(post_id, str):
post_id = UUID(post_id)
res = get_comments(self.token, post_id, limit, cursor, sort) res = get_comments(self.token, post_id, limit, cursor, sort)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
raise NotFound('Post') raise NotFound('Post')
@@ -454,11 +469,11 @@ class Client:
return [Comment.model_validate(comment) for comment in data['comments']], Pagination(page=(cursor // limit) or 1, limit=limit, total=data['total'], hasMore=data['hasMore'], nextCursor=None) return [Comment.model_validate(comment) for comment in data['comments']], Pagination(page=(cursor // limit) or 1, limit=limit, total=data['total'], hasMore=data['hasMore'], nextCursor=None)
@refresh_on_error @refresh_on_error
def like_comment(self, id: UUID) -> int: def like_comment(self, id: UUID | str) -> int:
"""Лайкнуть комментарий """Лайкнуть комментарий
Args: Args:
id (UUID): UUID комментария id (UUID | str): UUID комментария
Raises: Raises:
NotFound: Комментарий не найден NotFound: Комментарий не найден
@@ -466,6 +481,9 @@ class Client:
Returns: Returns:
int: Количество лайков int: Количество лайков
""" """
if isinstance(id, str):
id = UUID(id)
res = like_comment(self.token, id) res = like_comment(self.token, id)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
raise NotFound('Comment') raise NotFound('Comment')
@@ -474,11 +492,11 @@ class Client:
return res.json()['likesCount'] return res.json()['likesCount']
@refresh_on_error @refresh_on_error
def unlike_comment(self, id: UUID) -> int: def unlike_comment(self, id: UUID | str) -> int:
"""Убрать лайк с комментария """Убрать лайк с комментария
Args: Args:
id (UUID): UUID комментария id (UUID | str): UUID комментария
Raises: Raises:
NotFound: Комментарий не найден NotFound: Комментарий не найден
@@ -486,6 +504,9 @@ class Client:
Returns: Returns:
int: Количество лайков int: Количество лайков
""" """
if isinstance(id, str):
id = UUID(id)
res = unlike_comment(self.token, id) res = unlike_comment(self.token, id)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
raise NotFound('Comment') raise NotFound('Comment')
@@ -494,16 +515,19 @@ class Client:
return res.json()['likesCount'] return res.json()['likesCount']
@refresh_on_error @refresh_on_error
def delete_comment(self, id: UUID) -> None: def delete_comment(self, id: UUID | str) -> None:
"""Удалить комментарий """Удалить комментарий
Args: Args:
id (UUID): UUID комментария id (UUID | str): UUID комментария
Raises: Raises:
NotFound: Комментарий не найден NotFound: Комментарий не найден
Forbidden: Нет прав на удаление Forbidden: Нет прав на удаление
""" """
if isinstance(id, str):
id = UUID(id)
res = delete_comment(self.token, id) res = delete_comment(self.token, id)
if res.status_code == 204: if res.status_code == 204:
return return
@@ -542,19 +566,22 @@ class Client:
return [Hashtag.model_validate(hashtag) for hashtag in res.json()['data']['hashtags']] return [Hashtag.model_validate(hashtag) for hashtag in res.json()['data']['hashtags']]
@refresh_on_error @refresh_on_error
def get_posts_by_hashtag(self, hashtag: str, limit: int = 20, cursor: UUID | None = None) -> tuple[Hashtag | None, list[Post], Pagination]: def get_posts_by_hashtag(self, hashtag: str, limit: int = 20, cursor: UUID | str | None = None) -> tuple[Hashtag | None, list[Post], Pagination]:
"""Получить посты по хэштэгу """Получить посты по хэштэгу
Args: Args:
hashtag (str): Хэштэг (без #) hashtag (str): Хэштэг (без #)
limit (int, optional): Лимит. Defaults to 20. limit (int, optional): Лимит. Defaults to 20.
cursor (UUID | None, optional): Курсор (UUID последнего поста, после которого брать данные). Defaults to None. cursor (UUID | str | None, optional): Курсор (UUID последнего поста, после которого брать данные). Defaults to None.
Returns: Returns:
Hashtag | None: Хэштэг Hashtag | None: Хэштэг
list[Post]: Посты list[Post]: Посты
Pagination: Пагинация Pagination: Пагинация
""" """
if isinstance(cursor, str):
cursor = UUID(cursor)
res = get_posts_by_hashtag(self.token, hashtag, limit, cursor) res = get_posts_by_hashtag(self.token, hashtag, limit, cursor)
res.raise_for_status() res.raise_for_status()
data = res.json()['data'] data = res.json()['data']
@@ -583,15 +610,18 @@ class Client:
) )
@refresh_on_error @refresh_on_error
def mark_as_read(self, id: UUID) -> bool: def mark_as_read(self, id: UUID | str) -> bool:
"""Прочитать уведомление """Прочитать уведомление
Args: Args:
id (UUID): UUID уведомления id (UUID | str): UUID уведомления
Returns: Returns:
bool: Успешно (False - уже прочитано) bool: Успешно (False - уже прочитано)
""" """
if isinstance(id, str):
id = UUID(id)
res = mark_as_read(self.token, id) res = mark_as_read(self.token, id)
res.raise_for_status() res.raise_for_status()
@@ -618,13 +648,13 @@ class Client:
@refresh_on_error @refresh_on_error
def create_post(self, content: str, wall_recipient_id: UUID | None = None, attach_ids: list[UUID] = []) -> NewPost: def create_post(self, content: str, wall_recipient_id: UUID | str | None = None, attach_ids: list[UUID | str] = []) -> NewPost:
"""Создать пост """Создать пост
Args: Args:
content (str): Содержимое content (str): Содержимое
wall_recipient_id (UUID | None, optional): UUID пользователя (чтобы создать пост ему на стене). Defaults to None. wall_recipient_id (UUID | str | None, optional): UUID пользователя (чтобы создать пост ему на стене). Defaults to None.
attach_ids (list[UUID], optional): UUID вложений. Defaults to []. attach_ids (list[UUID | str], optional): UUID вложений. Defaults to [].
Raises: Raises:
NotFound: Пользователь не найден NotFound: Пользователь не найден
@@ -633,6 +663,10 @@ class Client:
Returns: Returns:
NewPost: Новый пост NewPost: Новый пост
""" """
if isinstance(wall_recipient_id, str):
wall_recipient_id = UUID(wall_recipient_id)
attach_ids = list(map(lambda id: UUID(id) if isinstance(id, str) else id, attach_ids))
res = create_post(self.token, content, wall_recipient_id, attach_ids) res = create_post(self.token, content, wall_recipient_id, attach_ids)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
raise NotFound('Wall recipient') raise NotFound('Wall recipient')
@@ -661,11 +695,11 @@ class Client:
return [Post.model_validate(post) for post in data['posts']], PostsPagintaion.model_validate(data['pagination']) return [Post.model_validate(post) for post in data['posts']], PostsPagintaion.model_validate(data['pagination'])
@refresh_on_error @refresh_on_error
def get_post(self, id: UUID) -> Post: def get_post(self, id: UUID | str) -> Post:
"""Получить пост """Получить пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
Raises: Raises:
NotFound: Пост не найден NotFound: Пост не найден
@@ -673,6 +707,9 @@ class Client:
Returns: Returns:
Post: Пост Post: Пост
""" """
if isinstance(id, str):
id = UUID(id)
res = get_post(self.token, id) res = get_post(self.token, id)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
raise NotFound('Post') raise NotFound('Post')
@@ -681,11 +718,11 @@ class Client:
return Post.model_validate(res.json()['data']) return Post.model_validate(res.json()['data'])
@refresh_on_error @refresh_on_error
def edit_post(self, id: UUID, content: str) -> str: def edit_post(self, id: UUID | str, content: str) -> str:
"""Редактировать пост """Редактировать пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
content (str): Содержимое content (str): Содержимое
Raises: Raises:
@@ -696,6 +733,9 @@ class Client:
Returns: Returns:
str: Новое содержимое str: Новое содержимое
""" """
if isinstance(id, str):
id = UUID(id)
res = edit_post(self.token, id, content) res = edit_post(self.token, id, content)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
@@ -709,16 +749,19 @@ class Client:
return res.json()['content'] return res.json()['content']
@refresh_on_error @refresh_on_error
def delete_post(self, id: UUID) -> None: def delete_post(self, id: UUID | str) -> None:
"""Удалить пост """Удалить пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
Raises: Raises:
NotFound: Пост не найден NotFound: Пост не найден
Forbidden: Нет доступа Forbidden: Нет доступа
""" """
if isinstance(id, str):
id = UUID(id)
res = delete_post(self.token, id) res = delete_post(self.token, id)
if res.status_code == 204: if res.status_code == 204:
return return
@@ -730,16 +773,19 @@ class Client:
res.raise_for_status() res.raise_for_status()
@refresh_on_error @refresh_on_error
def pin_post(self, id: UUID): def pin_post(self, id: UUID | str):
"""Закрепить пост """Закрепить пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
Raises: Raises:
NotFound: Пост не найден NotFound: Пост не найден
Forbidden: Нет доступа Forbidden: Нет доступа
""" """
if isinstance(id, str):
id = UUID(id)
res = pin_post(self.token, id) res = pin_post(self.token, id)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
@@ -749,11 +795,11 @@ class Client:
res.raise_for_status() res.raise_for_status()
@refresh_on_error @refresh_on_error
def repost(self, id: UUID, content: str | None = None) -> NewPost: def repost(self, id: UUID | str, content: str | None = None) -> NewPost:
"""Репостнуть пост """Репостнуть пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
content (str | None, optional): Содержимое (доп. комментарий). Defaults to None. content (str | None, optional): Содержимое (доп. комментарий). Defaults to None.
Raises: Raises:
@@ -765,6 +811,9 @@ class Client:
Returns: Returns:
NewPost: Новый пост NewPost: Новый пост
""" """
if isinstance(id, str):
id = UUID(id)
res = repost(self.token, id, content) res = repost(self.token, id, content)
if res.json().get('error', {}).get('code') == 'NOT_FOUND': if res.json().get('error', {}).get('code') == 'NOT_FOUND':
@@ -780,15 +829,18 @@ class Client:
return NewPost.model_validate(res.json()) return NewPost.model_validate(res.json())
@refresh_on_error @refresh_on_error
def view_post(self, id: UUID) -> None: def view_post(self, id: UUID | str) -> None:
"""Просмотреть пост """Просмотреть пост
Args: Args:
id (UUID): UUID поста id (UUID | str): UUID поста
Raises: Raises:
NotFound: Пост не найден NotFound: Пост не найден
""" """
if isinstance(id, str):
id = UUID(id)
res = view_post(self.token, id) res = view_post(self.token, id)
if res.status_code == 204: if res.status_code == 204:
return return
@@ -808,19 +860,27 @@ class Client:
@refresh_on_error @refresh_on_error
def report(self, id: str, type: str = 'post', reason: str = 'other', description: str = ''): def report(self, id: str | UUID, type: str = 'post', reason: str = 'other', description: str = ''):
if isinstance(id, str):
id = UUID(id)
return report(self.token, id, type, reason, description) return report(self.token, id, type, reason, description)
@refresh_on_error @refresh_on_error
def report_user(self, id: str, reason: str = 'other', description: str = ''): def report_user(self, id: str | UUID, reason: str = 'other', description: str = ''):
if isinstance(id, str):
id = UUID(id)
return report(self.token, id, 'user', reason, description) return report(self.token, id, 'user', reason, description)
@refresh_on_error @refresh_on_error
def report_post(self, id: str, reason: str = 'other', description: str = ''): def report_post(self, id: str | UUID, reason: str = 'other', description: str = ''):
if isinstance(id, str):
id = UUID(id)
return report(self.token, id, 'post', reason, description) return report(self.token, id, 'post', reason, description)
@refresh_on_error @refresh_on_error
def report_comment(self, id: str, reason: str = 'other', description: str = ''): def report_comment(self, id: str | UUID, reason: str = 'other', description: str = ''):
if isinstance(id, str):
id = UUID(id)
return report(self.token, id, 'comment', reason, description) return report(self.token, id, 'comment', reason, description)
@@ -843,4 +903,37 @@ class Client:
def update_banner(self, name: str) -> UserProfileUpdate: def update_banner(self, name: str) -> UserProfileUpdate:
id = self.upload_file(name, cast(BufferedReader, open(name, 'rb')))['id'] id = self.upload_file(name, cast(BufferedReader, open(name, 'rb')))['id']
return self.update_profile(banner_id=id) return self.update_profile(banner_id=id)
@refresh_on_error
def restore_post(self, post_id: UUID) -> None:
"""Восстановить удалённый пост
Args:
post_id: UUID поста
"""
restore_post(self.token, post_id)
@refresh_on_error
def like_post(self, post_id: UUID) -> LikePostResponse:
"""Поставить лайк на пост
Args:
post_id: UUID поста
"""
res = like_post(self.token, post_id)
if res.status_code == 404:
raise NotFound("Post not found")
return LikePostResponse.model_validate(res.json())
@refresh_on_error
def delete_like_post(self, post_id: UUID) -> LikePostResponse:
"""Убрать лайк с поста
Args:
post_id: UUID поста
"""
res = delete_like_post(self.token, post_id)
if res.status_code == 404:
raise NotFound("Post not found")
return LikePostResponse.model_validate(res.json())

View File

@@ -1,6 +1,6 @@
from uuid import UUID from uuid import UUID
from pydantic import Field from pydantic import Field, BaseModel
from itd.models.user import UserPost, UserNewPost from itd.models.user import UserPost, UserNewPost
from itd.models._text import TextObject from itd.models._text import TextObject
@@ -45,3 +45,7 @@ class Post(_Post, PostShort):
class NewPost(_Post): class NewPost(_Post):
author: UserNewPost author: UserNewPost
class LikePostResponse(BaseModel):
liked: bool
likes_count: int = Field(alias="likesCount")

View File

@@ -39,5 +39,11 @@ def view_post(token: str, id: UUID):
def get_liked_posts(token: str, username_or_id: str | UUID, limit: int = 20, cursor: int = 0): def get_liked_posts(token: str, username_or_id: str | UUID, limit: int = 20, cursor: int = 0):
return fetch(token, 'get', f'posts/user/{username_or_id}/liked', {'limit': limit}) return fetch(token, 'get', f'posts/user/{username_or_id}/liked', {'limit': limit})
# todo post restore def restore_post(token: str, post_id: UUID):
# todo post like return fetch(token, "post", f"posts/{post_id}/restore",)
def like_post(token: str, post_id: UUID):
return fetch(token, "post", f"posts/{post_id}/like")
def delete_like_post(token: str, post_id: UUID):
return fetch(token, "delete", f"posts/{post_id}/like")

View File

@@ -1,4 +1,5 @@
from itd.request import fetch from itd.request import fetch
from uuid import UUID
def report(token: str, id: str, type: str = 'post', reason: str = 'other', description: str = ''): def report(token: str, id: UUID, type: str = 'post', reason: str = 'other', description: str = ''):
return fetch(token, 'post', 'reports', {'targetId': id, 'targetType': type, 'reason': reason, 'description': description}) return fetch(token, 'post', 'reports', {'targetId': id, 'targetType': type, 'reason': reason, 'description': description})

1
tests/settings.py Normal file
View File

@@ -0,0 +1 @@
cookies = 'Сюда вставить куки'

26
tests/test_like.py Normal file
View File

@@ -0,0 +1,26 @@
from itd import ITDClient
from itd.models.post import LikePostResponse
from itd.exceptions import NotFound
import unittest
from . import settings
class TestLike(unittest.TestCase):
def test_like(self):
c = ITDClient(None, settings.cookies)
post = c.create_post("post_for_test_like")
self.assertEqual(c.like_post(post.id), LikePostResponse(liked=True, likesCount=1)) # Лайк на пост без лайка
self.assertEqual(c.like_post(post.id), LikePostResponse(liked=True, likesCount=1)) # Лайк на пост с уже поставленным лайком
self.assertEqual(c.delete_like_post(post.id), LikePostResponse(liked=False, likesCount=0)) # Убрать лайк с поста с уже поставленным лайком
self.assertEqual(c.delete_like_post(post.id), LikePostResponse(liked=False, likesCount=0)) # Убрать лайк с поста без лайков
c.delete_post(str(post.id))
self.assertRaises(NotFound, c.like_post, post.id) # лайк на удалённый пост
self.assertRaises(NotFound, c.delete_like_post, post.id) # Убрать лайк с удалённого поста
if __name__ == "__main__":
unittest.main()