diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index fecbc52..1962433 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -20,25 +20,33 @@ @comment.post("", response_model=CommentGet) async def create_comment(lecturer_id: int, comment_info: CommentPost, user=Depends(UnionAuth())) -> CommentGet: """ + Scopes: `["rating.comment.import"]` Создает комментарий к преподавателю в базе данных RatingAPI Для создания комментария нужно быть авторизованным + + Для возможности создания комментария с указанием времени создания и изменения необходим скоуп ["rating.comment.import"] """ lecturer = Lecturer.get(session=db.session, id=lecturer_id) if not lecturer: raise ObjectNotFound(Lecturer, lecturer_id) - user_comments: list[LecturerUserComment] = ( - LecturerUserComment.query(session=db.session).filter(LecturerUserComment.user_id == user.get("id")).all() - ) - for user_comment in user_comments: - if datetime.datetime.utcnow() - user_comment.update_ts < datetime.timedelta( - minutes=settings.COMMENT_CREATE_FREQUENCY_IN_MINUTES - ): - raise TooManyCommentRequests( - dtime=user_comment.update_ts - + datetime.timedelta(minutes=settings.COMMENT_CREATE_FREQUENCY_IN_MINUTES) - - datetime.datetime.utcnow() - ) + has_create_scope = "rating.comment.import" in [scope['name'] for scope in user.get('session_scopes')] + if (comment_info.create_ts or comment_info.update_ts) and not has_create_scope: + raise ForbiddenAction(Comment) + + if not has_create_scope: + user_comments: list[LecturerUserComment] = ( + LecturerUserComment.query(session=db.session).filter(LecturerUserComment.user_id == user.get("id")).all() + ) + for user_comment in user_comments: + if datetime.datetime.utcnow() - user_comment.update_ts < datetime.timedelta( + minutes=settings.COMMENT_CREATE_FREQUENCY_IN_MINUTES + ): + raise TooManyCommentRequests( + dtime=user_comment.update_ts + + datetime.timedelta(minutes=settings.COMMENT_CREATE_FREQUENCY_IN_MINUTES) + - datetime.datetime.utcnow() + ) # Сначала добавляем с user_id, который мы получили при авторизации, # в LecturerUserComment, чтобы нельзя было слишком быстро добавлять комментарии diff --git a/rating_api/schemas/models.py b/rating_api/schemas/models.py index 8179854..2e2cc1e 100644 --- a/rating_api/schemas/models.py +++ b/rating_api/schemas/models.py @@ -24,6 +24,8 @@ class CommentGet(Base): class CommentPost(Base): subject: str text: str + create_ts: datetime.datetime | None = None + update_ts: datetime.datetime | None = None mark_kindness: int mark_freebie: int mark_clarity: int diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index 3a89b90..d093d92 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -1,3 +1,4 @@ +import datetime import logging import uuid @@ -76,6 +77,19 @@ 3, status.HTTP_404_NOT_FOUND, ), + ( + { + "subject": "test_subject", + "text": "test_text", + "create_ts": "2077-11-16T19:15:27.306Z", + "update_ts": "2077-11-16T19:15:27.306Z", + "mark_kindness": 1, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 0, + status.HTTP_200_OK, + ), ( # Anonymous comment { "subject": "test_subject", @@ -88,6 +102,18 @@ 0, status.HTTP_200_OK, ), + ( + { + "subject": "test_subject", + "text": "test_text", + "update_ts": "2077-11-16T19:15:27.306Z", + "mark_kindness": 1, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 0, + status.HTTP_200_OK, + ), ( # NotAnonymous comment { "subject": "test_subject", @@ -100,6 +126,30 @@ 0, status.HTTP_200_OK, ), + ( + { + "subject": "test_subject", + "text": "test_text", + "create_ts": "2077-11-16T19:15:27.306Z", + "mark_kindness": 1, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 0, + status.HTTP_200_OK, + ), + ( # wrong date + { + "subject": "test_subject", + "text": "test_text", + "create_ts": "wasd", + "mark_kindness": 1, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 0, + status.HTTP_422_UNPROCESSABLE_ENTITY, + ), ( # Bad anonymity { "subject": "test_subject", @@ -133,6 +183,12 @@ def test_create_comment(client, dbsession, lecturers, body, lecturer_n, response if response_status == status.HTTP_200_OK: comment = Comment.query(session=dbsession).filter(Comment.uuid == post_response.json()["uuid"]).one_or_none() assert comment is not None + + if "create_ts" in body: + assert comment.create_ts == datetime.datetime.fromisoformat(body["create_ts"]).replace(tzinfo=None) + if "update_ts" in body: + assert comment.update_ts == datetime.datetime.fromisoformat(body["update_ts"]).replace(tzinfo=None) + user_comment = ( LecturerUserComment.query(session=dbsession) .filter(LecturerUserComment.lecturer_id == lecturers[lecturer_n].id)