From 11102dd59173282164d3a3e3120bddfc4b7e2661 Mon Sep 17 00:00:00 2001 From: Timur Enikeev Date: Sat, 9 Nov 2024 16:38:48 -0500 Subject: [PATCH 01/10] Case insensitive search --- rating_api/models/db.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rating_api/models/db.py b/rating_api/models/db.py index ed6cc9f..5fa2a9b 100644 --- a/rating_api/models/db.py +++ b/rating_api/models/db.py @@ -7,7 +7,7 @@ from sqlalchemy import UUID, DateTime from sqlalchemy import Enum as DbEnum -from sqlalchemy import ForeignKey, Integer, String, and_, or_, true +from sqlalchemy import ForeignKey, Integer, String, and_, func, or_, true from sqlalchemy.ext.hybrid import hybrid_method from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -40,8 +40,14 @@ def search(self, query: str) -> bool: response = true query = query.split(' ') for q in query: + q = q.lower() response = and_( - response, or_(self.first_name.contains(q), self.middle_name.contains(q), self.last_name.contains(q)) + response, + or_( + func.lower(self.first_name).contains(q), + func.lower(self.middle_name).contains(q), + func.lower(self.last_name).contains(q), + ), ) return response From 49046b5d4e9d15f6b93b2b721a7b495454c542e2 Mon Sep 17 00:00:00 2001 From: default Date: Mon, 11 Nov 2024 20:45:40 +0000 Subject: [PATCH 02/10] fixtures+ tests --- rating_api/utils/utils.py | 15 +++ tests/conftest.py | 86 ++++++++++++- tests/test_routes/test_comment.py | 131 +++++++++----------- tests/test_routes/test_lecturer.py | 189 ++++++++++------------------- 4 files changed, 219 insertions(+), 202 deletions(-) create mode 100644 rating_api/utils/utils.py diff --git a/rating_api/utils/utils.py b/rating_api/utils/utils.py new file mode 100644 index 0000000..fb0a47f --- /dev/null +++ b/rating_api/utils/utils.py @@ -0,0 +1,15 @@ +import random +import string + + +def random_string(length: int = 12): + """ + Сгенерировать рандомную строку + :param length: длина строки(по умолчанию 12) + :return: Сгенериированную строку + """ + return "".join([random.choice(string.ascii_lowercase) for _ in range(length)]) + + +def random_mark(): + return random.randint(-2, 2) diff --git a/tests/conftest.py b/tests/conftest.py index cc467ce..1a76254 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,9 +2,10 @@ from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker - +from rating_api.models.db import * from rating_api.routes import app from rating_api.settings import Settings +from rating_api.utils.utils import random_string, random_mark @pytest.fixture @@ -28,3 +29,86 @@ def dbsession() -> Session: engine = create_engine(str(settings.DB_DSN), pool_pre_ping=True) TestingSessionLocal = sessionmaker(bind=engine) yield TestingSessionLocal() + + +@pytest.fixture +def lecturer(dbsession): + """ + Вызов фабрики создает препода и возвращает его + ``` + def test(lecturer): + lecturer1 = lecturer() + lecturer2 = lecturer() + ``` + """ + lecturers = [] + + def _lecturer(first_name: str | None = None, last_name: str | None = None, middle_name: str | None = None): + nonlocal lecturers + first_name = f"test_fname{random_string()}" if first_name is None else first_name + last_name = f"test_lname{random_string()}" if last_name is None else last_name + middle_name = f"test_mname{random_string()}" if middle_name is None else middle_name + __lecturer = Lecturer( + first_name=first_name, last_name=last_name, middle_name=middle_name, timetable_id=len(lecturers) + ) + dbsession.add(__lecturer) + dbsession.commit() + lecturers.append(__lecturer) + return __lecturer + + yield _lecturer + dbsession.expire_all() + dbsession.commit() + for row in lecturers: + dbsession.delete(row) + dbsession.commit() + + +@pytest.fixture +def comment(dbsession, lecturer): + """ " + Вызов фабрики создает комментарий к преподавателю и возвращает его + ``` + def test(comment): + comment1 = comment() + comment2 = comment() + ``` + """ + comments = [] + + def _comment( + lecturer_id: int | None = None, + user_id: int | None = None, + review_status: ReviewStatus = ReviewStatus.APPROVED, + subject: str | None = None, + ): + nonlocal comments + text = random_string() + subject = random_string() if subject is None else subject + mark_kindness = random_mark() + mark_freebie = random_mark() + mark_clarity = random_mark() + if lecturer_id is None: + lecturer = lecturer() + lecturer_id = lecturer.id + __comment = Comment( + subject=subject, + text=text, + mark_kindness=mark_kindness, + mark_clarity=mark_clarity, + mark_freebie=mark_freebie, + lecturer_id=lecturer_id, + user_id=user_id, + review_status=review_status, + ) + dbsession.add(__comment) + dbsession.commit() + comments.append(__comment) + return __comment + + yield _comment + dbsession.expire_all() + dbsession.commit() + for row in comments: + dbsession.delete(row) + dbsession.commit() diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index d31c912..5c16517 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -13,12 +13,8 @@ settings = get_settings() -def test_create_comment(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - +def test_create_comment(client, dbsession, comment, lecturer): + lecturer = lecturer() body = { "subject": "Физика", "text": "Хороший препод", @@ -28,7 +24,6 @@ def test_create_comment(client, dbsession): } params = {"lecturer_id": lecturer.id} post_response = client.post(url, json=body, params=params) - print(post_response.json()) assert post_response.status_code == status.HTTP_200_OK json_response = post_response.json() comment = Comment.query(session=dbsession).filter(Comment.uuid == json_response["uuid"]).one_or_none() @@ -41,17 +36,14 @@ def test_create_comment(client, dbsession): assert user_comment is not None dbsession.delete(user_comment) dbsession.delete(comment) - dbsession.delete(lecturer) dbsession.commit() + params = {"lecturer_id": 1} post_response = client.post(url, json=body, params=params) assert post_response.status_code == status.HTTP_404_NOT_FOUND -def test_post_bad_mark(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() +def test_post_bad_mark(client, lecturer): + test_lecturer = lecturer() body = { "subject": "Физика", @@ -60,76 +52,69 @@ def test_post_bad_mark(client, dbsession): "mark_freebie": -2, "mark_clarity": 0, } - params = {"lecturer_id": lecturer.id} + params = {"lecturer_id": test_lecturer.id} post_response = client.post(url, json=body, params=params) assert post_response.status_code == status.HTTP_400_BAD_REQUEST - dbsession.delete(lecturer) - dbsession.commit() -def test_get_comment(client, dbsession): - body = { - "first_name": 'Иван', - "last_name": 'Иванов', - "middle_name": 'Иванович', - "timetable_id": 0, - } - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - - body = { - "lecturer_id": lecturer.id, - "subject": "Физика", - "text": "Хороший препод", - "mark_kindness": 1, - "mark_freebie": -2, - "mark_clarity": 0, - "review_status": ReviewStatus.APPROVED, - } - comment: Comment = Comment(**body) - dbsession.add(comment) - dbsession.commit() - response_comment = client.get(f'{url}/{comment.uuid}') - assert response_comment.status_code == status.HTTP_200_OK +def test_get_comment(client, dbsession, lecturer, comment): + test_lecturer = lecturer() + test_comment = comment(lecturer_id=test_lecturer.id) random_uuid = uuid.uuid4() response = client.get(f'{url}/{random_uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND - comment = Comment.query(session=dbsession).filter(Comment.uuid == response_comment.json()["uuid"]).one_or_none() - assert comment is not None - dbsession.delete(comment) - dbsession.delete(lecturer) - dbsession.commit() - - -def test_delete_comment(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - - body = { - "lecturer_id": lecturer.id, - "subject": "Физика", - "text": "Хороший препод", - "mark_kindness": 1, - "mark_freebie": -2, - "mark_clarity": 0, - "review_status": ReviewStatus.APPROVED, - } - comment: Comment = Comment(**body) - dbsession.add(comment) - dbsession.commit() - response = client.delete(f'{url}/{comment.uuid}') + response = client.get(f'{url}/{test_comment.uuid}') + assert response.status_code == status.HTTP_200_OK + comment1 = Comment.query(session=dbsession).filter(Comment.uuid == response.json()["uuid"]).one_or_none() + assert comment1 is not None + + +def test_get_comments_by_lecturer_id(client, lecturer, comment): + lecturer1 = lecturer() + lecturer2 = lecturer() + comment1_1 = comment(lecturer_id=lecturer1.id) + comment1_2 = comment(lecturer_id=lecturer1.id) + comment2_1 = comment(lecturer_id=lecturer2.id) + query = {"lecturer_id": lecturer1.id} + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_200_OK + json_response = response.json() + assert json_response["total"] == 2 + query = {"lecturer_id": lecturer2.id} + response = client.get(f'{url}', params=query) assert response.status_code == status.HTTP_200_OK - response = client.get(f'{url}/{comment.uuid}') + json_response = response.json() + assert json_response["total"] == 1 + query = {"lecturer_id": 2} + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_200_OK + json_response = response.json() + assert json_response["total"] == 0 + + +def test_get_comments_unreviewed(client, lecturer, comment): + lecturer1 = lecturer() + lecturer2 = lecturer() + comment1_1 = comment(lecturer_id=lecturer1.id, review_status=ReviewStatus.APPROVED) + comment1_2 = comment(lecturer_id=lecturer1.id, review_status=ReviewStatus.PENDING) + comment2_1 = comment(lecturer_id=lecturer2.id, review_status=ReviewStatus.PENDING) + comment2_2 = comment(lecturer_id=lecturer2.id, review_status=ReviewStatus.DISMISSED) + query = {'unreviewed': True} + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +def test_delete_comment(client, dbsession, lecturer, comment): + test_lecturer = lecturer() + test_comment = comment(lecturer_id=test_lecturer.id) + response = client.delete(f'{url}/{test_comment.uuid}') + dbsession.refresh(test_comment) + assert response.status_code == status.HTTP_200_OK + response = client.get(f'{url}/{test_comment.uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND random_uuid = uuid.uuid4() response = client.delete(f'{url}/{random_uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND - comment1 = Comment.query(session=dbsession).filter(Comment.uuid == comment.uuid).one_or_none() + comment1 = Comment.query(session=dbsession).filter(Comment.uuid == test_comment.uuid).one_or_none() assert comment1 is None - comment.is_deleted = True - dbsession.delete(comment) - dbsession.delete(lecturer) - dbsession.commit() + assert test_comment.is_deleted diff --git a/tests/test_routes/test_lecturer.py b/tests/test_routes/test_lecturer.py index 39027d0..c02742e 100644 --- a/tests/test_routes/test_lecturer.py +++ b/tests/test_routes/test_lecturer.py @@ -1,7 +1,7 @@ import logging from starlette import status - +import pytest from rating_api.models import Comment, Lecturer, ReviewStatus from rating_api.settings import get_settings @@ -26,14 +26,9 @@ def test_create_lecturer(client, dbsession): assert lecturer is None -def test_get_lecturer(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - db_lecturer: Lecturer = Lecturer.query(session=dbsession).filter(Lecturer.timetable_id == 0).one_or_none() - assert db_lecturer is not None - get_response = client.get(f'{url}/{db_lecturer.id}') +def test_get_lecturer(client, lecturer): + lecturer = lecturer() + get_response = client.get(f'{url}/{lecturer.id}') print(get_response.json()) assert get_response.status_code == status.HTTP_200_OK json_response = get_response.json() @@ -42,122 +37,77 @@ def test_get_lecturer(client, dbsession): assert json_response["mark_clarity"] is None assert json_response["mark_general"] is None assert json_response["comments"] is None - dbsession.delete(lecturer) - dbsession.commit() -def test_get_lecturer_with_comments(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - db_lecturer: Lecturer = Lecturer.query(session=dbsession).filter(Lecturer.timetable_id == 0).one_or_none() - assert db_lecturer is not None - - comment1: dict = { - "subject": "Физика", - "text": "Хороший преподаватель", - "mark_kindness": 2, - "mark_freebie": 0, - "mark_clarity": 2, - "lecturer_id": db_lecturer.id, - "review_status": ReviewStatus.APPROVED, - } - comment2: dict = { - "subject": "Физика", - "text": "Средне", - "mark_kindness": -1, - "mark_freebie": 1, - "mark_clarity": -1, - "lecturer_id": db_lecturer.id, - "review_status": ReviewStatus.APPROVED, - } - comment3: dict = { - "subject": "Физика", - "text": "Средне", - "mark_kindness": 2, - "mark_freebie": 2, - "mark_clarity": 2, - "lecturer_id": db_lecturer.id, - "review_status": ReviewStatus.PENDING, - } - comment1: Comment = Comment.create(session=dbsession, **comment1) - comment2: Comment = Comment.create(session=dbsession, **comment2) - comment3: Comment = Comment.create(session=dbsession, **comment3) - dbsession.commit() - assert comment1 is not None - assert comment2 is not None - assert comment3 is not None +def test_get_lecturer_with_comments(client, lecturer, comment): + test_lecturer = lecturer() + comment1 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.APPROVED) + comment2 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.PENDING) + comment3 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.DISMISSED) query = { "info": ['comments', 'mark'], } - response = client.get(f'{url}/{db_lecturer.id}', params=query) - print(response.json()) + response = client.get(f'{url}/{test_lecturer.id}', params=query) assert response.status_code == status.HTTP_200_OK json_response = response.json() - assert json_response["mark_kindness"] == 0.5 - assert json_response["mark_freebie"] == 0.5 - assert json_response["mark_clarity"] == 0.5 - assert json_response["mark_general"] == 0.5 - assert "Физика" in json_response["subjects"] - assert len(json_response["comments"]) != 0 - dbsession.delete(comment1) - dbsession.delete(comment2) - dbsession.delete(comment3) - dbsession.delete(lecturer) - dbsession.commit() - - -def test_get_lecturers_by_name(client, dbsession): - body_list = [ - {"first_name": 'Алиса', "last_name": 'Селезнёва', "middle_name": 'Ивановна', "timetable_id": 0}, - {"first_name": 'Марат', "last_name": 'Сельков', "middle_name": 'Анатольевич', "timetable_id": 1}, - {"first_name": 'М.', "last_name": 'Измайлов', "middle_name": 'Р.', "timetable_id": 2}, - {"first_name": 'Михаил', "last_name": 'Измайлов', "middle_name": 'Ильич', "timetable_id": 3}, - ] - lecturer_list: list[Lecturer] = [Lecturer(**body_list[i]) for i in range(4)] - for lecturer in lecturer_list: - dbsession.add(lecturer) - dbsession.commit() - db_lecturer: Lecturer = Lecturer.query(session=dbsession).filter(Lecturer.timetable_id == 0).one_or_none() - assert db_lecturer is not None + assert json_response["mark_kindness"] == comment1.mark_kindness + assert json_response["mark_freebie"] == comment1.mark_freebie + assert json_response["mark_clarity"] == comment1.mark_clarity + assert json_response["mark_general"] == (comment1.mark_kindness + comment1.mark_freebie + comment1.mark_clarity) / 3 + assert len(json_response["comments"]) == 1 + assert json_response["comments"][0]["text"] == comment1.text + + +def test_get_lecturers_by_name(client, lecturer): + lecturer1 = lecturer(first_name='Алиса', last_name='Селезнёва', middle_name='Ивановна') + lecturer2 = lecturer(first_name='Марат', last_name='Сельков', middle_name='Анатольевич') + lecturer3 = lecturer(first_name='М', last_name='Измайлов', middle_name='Р') + lecturer4 = lecturer(first_name='Михаил', last_name='Измайлов', middle_name='Ильич') query = {"name": "Селезнёва"} - get_response = client.get(f'{url}', params=query) - assert get_response.status_code == status.HTTP_200_OK - json_response = get_response.json() + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_200_OK + json_response = response.json() assert json_response["total"] == 1 assert json_response["lecturers"][0]["first_name"] == "Алиса" query = {"name": "Сел"} - get_response = client.get(f'{url}', params=query) - assert get_response.status_code == status.HTTP_200_OK - json_response = get_response.json() + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_200_OK + json_response = response.json() assert json_response["total"] == 2 assert json_response["lecturers"][0]["first_name"] == "Алиса" assert json_response["lecturers"][1]["first_name"] == "Марат" query = {"name": "Измайлова"} - get_response = client.get(f'{url}', params=query) - assert get_response.status_code == status.HTTP_404_NOT_FOUND + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_404_NOT_FOUND - for lecturer in lecturer_list: - dbsession.delete(lecturer) - dbsession.commit() +def test_get_lecturers_by_subject(client, lecturer, comment): + lecturer1 = lecturer() + comment1 = comment(lecturer_id=lecturer1.id, subject="bibki") + lecturer2 = lecturer() + comment2 = comment(lecturer_id=lecturer2.id, subject="bibki") + lecturer3 = lecturer() + comment3 = comment(lecturer_id=lecturer2.id, subject="bobki") + query = {"subject": "bibki"} + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_200_OK + json_response = response.json() + assert json_response["total"] == 2 + query = {"subject": "bibobki"} + response = client.get(f'{url}', params=query) + assert response.status_code == status.HTTP_404_NOT_FOUND -def test_update_lecturer(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() + +def test_update_lecturer(client, lecturer): + test_lecturer = lecturer() body = { "first_name": 'Алексей', "last_name": 'Алексеев', "middle_name": 'Алексеевич', } - db_lecturer: Lecturer = Lecturer.query(session=dbsession).filter(Lecturer.timetable_id == 0).one_or_none() - assert db_lecturer is not None - response = client.patch(f"{url}/{db_lecturer.id}", json=body) + response = client.patch(f"{url}/{test_lecturer.id}", json=body) assert response.status_code == status.HTTP_200_OK json_response = response.json() assert json_response["first_name"] == 'Алексей' @@ -168,40 +118,23 @@ def test_update_lecturer(client, dbsession): "last_name": 'Иванов', "middle_name": 'Иванович', } - response = client.patch(f"{url}/{db_lecturer.id}", json=body) + response = client.patch(f"{url}/{test_lecturer.id}", json=body) assert response.status_code == status.HTTP_200_OK json_response = response.json() assert json_response["first_name"] == 'Иван' assert json_response["last_name"] == 'Иванов' assert json_response["middle_name"] == "Иванович" - dbsession.delete(lecturer) - dbsession.commit() -def test_delete_lecturer(client, dbsession): - body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} - lecturer: Lecturer = Lecturer(**body) - dbsession.add(lecturer) - dbsession.commit() - comment: dict = { - "subject": "Физика", - "text": "Хороший преподаватель", - "mark_kindness": 2, - "mark_freebie": 0, - "mark_clarity": 2, - "lecturer_id": lecturer.id, - "review_status": ReviewStatus.APPROVED, - } - comment: Comment = Comment.create(session=dbsession, **comment) - dbsession.commit() - lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == 0).one_or_none() - assert lecturer is not None - response = client.delete(f"{url}/{lecturer.id}") +def test_delete_lecturer(client, lecturer, comment, dbsession): + test_lecturer = lecturer() + test_comment = comment(lecturer_id=test_lecturer.id) + response = client.delete(f"{url}/{test_lecturer.id}") assert response.status_code == status.HTTP_200_OK - response = client.delete(f"{url}/{lecturer.id}") + response = client.delete(f"{url}/{test_lecturer.id}") + dbsession.refresh(test_lecturer) assert response.status_code == status.HTTP_404_NOT_FOUND - lecturer.is_deleted = True - comment.is_deleted = True - dbsession.delete(comment) - dbsession.delete(lecturer) - dbsession.commit() + response = client.get(f"{url}/{test_lecturer.id}") + assert response.status_code == status.HTTP_404_NOT_FOUND + assert test_comment.is_deleted + assert test_lecturer.is_deleted From 6f6a6e30660624ae6b35d4520d4553d64e9269af Mon Sep 17 00:00:00 2001 From: default Date: Mon, 11 Nov 2024 20:49:26 +0000 Subject: [PATCH 03/10] lint --- tests/conftest.py | 3 ++- tests/test_routes/test_lecturer.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1a76254..884c224 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,10 +2,11 @@ from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker + from rating_api.models.db import * from rating_api.routes import app from rating_api.settings import Settings -from rating_api.utils.utils import random_string, random_mark +from rating_api.utils.utils import random_mark, random_string @pytest.fixture diff --git a/tests/test_routes/test_lecturer.py b/tests/test_routes/test_lecturer.py index c02742e..13e5728 100644 --- a/tests/test_routes/test_lecturer.py +++ b/tests/test_routes/test_lecturer.py @@ -1,7 +1,8 @@ import logging -from starlette import status import pytest +from starlette import status + from rating_api.models import Comment, Lecturer, ReviewStatus from rating_api.settings import get_settings From a8df68cc991f914b42ed3a899ec3adaee6a332db Mon Sep 17 00:00:00 2001 From: default Date: Tue, 12 Nov 2024 13:45:21 +0000 Subject: [PATCH 04/10] refactoring --- tests/conftest.py | 146 ++++++++++------- tests/test_routes/test_comment.py | 186 +++++++++++---------- tests/test_routes/test_lecturer.py | 251 +++++++++++++++-------------- 3 files changed, 310 insertions(+), 273 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 884c224..a84a9cf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,6 @@ from rating_api.models.db import * from rating_api.routes import app from rating_api.settings import Settings -from rating_api.utils.utils import random_mark, random_string @pytest.fixture @@ -29,87 +28,110 @@ def dbsession() -> Session: settings = Settings() engine = create_engine(str(settings.DB_DSN), pool_pre_ping=True) TestingSessionLocal = sessionmaker(bind=engine) - yield TestingSessionLocal() + session = TestingSessionLocal() + yield session @pytest.fixture def lecturer(dbsession): + _lecturer = Lecturer(first_name="test_fname", last_name="test_lname", middle_name="test_mname", timetable_id=0) + dbsession.add(_lecturer) + dbsession.commit() + yield _lecturer + dbsession.refresh(_lecturer) + dbsession.delete(_lecturer) + dbsession.commit() + + +@pytest.fixture +def comment(dbsession, lecturer): + _comment = Comment( + subject="test_subject", + text="test_comment", + mark_kindness=1, + mark_clarity=1, + mark_freebie=1, + lecturer_id=lecturer.id, + review_status=ReviewStatus.APPROVED, + ) + dbsession.add(_comment) + dbsession.commit() + yield _comment + dbsession.refresh(_comment) + dbsession.delete(_comment) + dbsession.commit() + + +@pytest.fixture(scope='function') +def lecturers(dbsession): """ - Вызов фабрики создает препода и возвращает его - ``` - def test(lecturer): - lecturer1 = lecturer() - lecturer2 = lecturer() - ``` + Creates 4 lecturers(one with flag is_deleted=True) """ - lecturers = [] - - def _lecturer(first_name: str | None = None, last_name: str | None = None, middle_name: str | None = None): - nonlocal lecturers - first_name = f"test_fname{random_string()}" if first_name is None else first_name - last_name = f"test_lname{random_string()}" if last_name is None else last_name - middle_name = f"test_mname{random_string()}" if middle_name is None else middle_name - __lecturer = Lecturer( - first_name=first_name, last_name=last_name, middle_name=middle_name, timetable_id=len(lecturers) - ) - dbsession.add(__lecturer) - dbsession.commit() - lecturers.append(__lecturer) - return __lecturer + lecturers_data = [ + ("test_fname1", "test_lname1", "test_mname1", 0), + ("test_fname2", "test_lname2", "test_mname2", 1), + ("Bibka", "Bobka", "Bobkovich", 2), + ] - yield _lecturer - dbsession.expire_all() + lecturers = [ + Lecturer(first_name=fname, last_name=lname, middle_name=mname, timetable_id=timetable_id) + for fname, lname, mname, timetable_id in lecturers_data + ] + lecturers.append( + Lecturer(first_name='test_fname3', last_name='test_lname3', middle_name='test_mname3', timetable_id=3) + ) + lecturers[-1].is_deleted = True + for lecturer in lecturers: + dbsession.add(lecturer) dbsession.commit() - for row in lecturers: - dbsession.delete(row) + yield lecturers + for lecturer in lecturers: + dbsession.refresh(lecturer) + for row in lecturer.comments: + dbsession.delete(row) + lecturer_user_comments = dbsession.query(LecturerUserComment).filter( + LecturerUserComment.lecturer_id == lecturer.id + ) + for row in lecturer_user_comments: + dbsession.delete(row) + dbsession.delete(lecturer) dbsession.commit() @pytest.fixture -def comment(dbsession, lecturer): - """ " - Вызов фабрики создает комментарий к преподавателю и возвращает его - ``` - def test(comment): - comment1 = comment() - comment2 = comment() - ``` +def lecturers_with_comments(dbsession, lecturers): + """ + Creates 4 lecturers(one with flag is_deleted=True) with 3 comments to non-deleted lecturers 2 approved and one dismissed. Two of them have alike names. """ - comments = [] - - def _comment( - lecturer_id: int | None = None, - user_id: int | None = None, - review_status: ReviewStatus = ReviewStatus.APPROVED, - subject: str | None = None, - ): - nonlocal comments - text = random_string() - subject = random_string() if subject is None else subject - mark_kindness = random_mark() - mark_freebie = random_mark() - mark_clarity = random_mark() - if lecturer_id is None: - lecturer = lecturer() - lecturer_id = lecturer.id - __comment = Comment( + comments_data = [ + (lecturers[0].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[0].id, 'test_subject1', ReviewStatus.APPROVED, 2, 2, 2), + (lecturers[0].id, 'test_subject2', ReviewStatus.DISMISSED, -1, -1, -1), + (lecturers[1].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[1].id, 'test_subject1', ReviewStatus.APPROVED, -1, -1, -1), + (lecturers[1].id, 'test_subject2', ReviewStatus.DISMISSED, -2, -2, -2), + (lecturers[2].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[2].id, 'test_subject1', ReviewStatus.APPROVED, 0, 0, 0), + (lecturers[2].id, 'test_subject2', ReviewStatus.DISMISSED, 2, 2, 2), + ] + + comments = [ + Comment( subject=subject, - text=text, + text="test_comment", mark_kindness=mark_kindness, mark_clarity=mark_clarity, mark_freebie=mark_freebie, lecturer_id=lecturer_id, - user_id=user_id, review_status=review_status, ) - dbsession.add(__comment) - dbsession.commit() - comments.append(__comment) - return __comment + for lecturer_id, subject, review_status, mark_kindness, mark_clarity, mark_freebie in comments_data + ] - yield _comment - dbsession.expire_all() + dbsession.add_all(comments) dbsession.commit() - for row in comments: - dbsession.delete(row) + yield lecturers, comments + for comment in comments: + dbsession.refresh(comment) + dbsession.delete(comment) dbsession.commit() diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index 5c16517..da6b28b 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -1,6 +1,7 @@ import logging import uuid +import pytest from starlette import status from rating_api.models import Comment, Lecturer, LecturerUserComment, ReviewStatus @@ -13,108 +14,105 @@ settings = get_settings() -def test_create_comment(client, dbsession, comment, lecturer): - lecturer = lecturer() - body = { - "subject": "Физика", - "text": "Хороший препод", - "mark_kindness": 1, - "mark_freebie": -2, - "mark_clarity": 0, - } - params = {"lecturer_id": lecturer.id} +@pytest.mark.parametrize( + 'body,timetable_id,response_status', + [ + ( + { + "subject": "test_subject", + "text": "test_text", + "mark_kindness": 1, + "mark_freebie": 0, + "mark_clarity": 0, + }, + 0, + status.HTTP_200_OK, + ), + ( + { + "subject": "test1_subject", + "text": "test_text", + "mark_kindness": -2, + "mark_freebie": -2, + "mark_clarity": -2, + }, + 1, + status.HTTP_200_OK, + ), + ( # bad mark + { + "subject": "test_subject", + "text": "test_text", + "mark_kindness": 5, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 2, + status.HTTP_400_BAD_REQUEST, + ), + ( # deleted lecturer + { + "subject": "test_subject", + "text": "test_text", + "mark_kindness": 5, + "mark_freebie": -2, + "mark_clarity": 0, + }, + 3, + status.HTTP_400_BAD_REQUEST, + ), + ], +) +def test_create_comment(client, dbsession, lecturers, body, timetable_id, response_status): + params = {"lecturer_id": lecturers[timetable_id].id} # Ensure we get the ID of the lecturer post_response = client.post(url, json=body, params=params) - assert post_response.status_code == status.HTTP_200_OK - json_response = post_response.json() - comment = Comment.query(session=dbsession).filter(Comment.uuid == json_response["uuid"]).one_or_none() - assert comment is not None - user_comment = ( - LecturerUserComment.query(session=dbsession) - .filter(LecturerUserComment.lecturer_id == lecturer.id) - .one_or_none() - ) - assert user_comment is not None - dbsession.delete(user_comment) - dbsession.delete(comment) - dbsession.commit() - params = {"lecturer_id": 1} - post_response = client.post(url, json=body, params=params) - assert post_response.status_code == status.HTTP_404_NOT_FOUND - - -def test_post_bad_mark(client, lecturer): - test_lecturer = lecturer() - - body = { - "subject": "Физика", - "text": "Хороший препод", - "mark_kindness": 4, - "mark_freebie": -2, - "mark_clarity": 0, - } - params = {"lecturer_id": test_lecturer.id} - post_response = client.post(url, json=body, params=params) - assert post_response.status_code == status.HTTP_400_BAD_REQUEST - - -def test_get_comment(client, dbsession, lecturer, comment): - test_lecturer = lecturer() - test_comment = comment(lecturer_id=test_lecturer.id) + assert post_response.status_code == response_status + 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 + user_comment = ( + LecturerUserComment.query(session=dbsession) + .filter(LecturerUserComment.lecturer_id == lecturers[timetable_id].id) + .one_or_none() + ) + assert user_comment is not None + + +def test_get_comment(client, comment): + response_comment = client.get(f'{url}/{comment.uuid}') + assert response_comment.status_code == status.HTTP_200_OK random_uuid = uuid.uuid4() response = client.get(f'{url}/{random_uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND - response = client.get(f'{url}/{test_comment.uuid}') - assert response.status_code == status.HTTP_200_OK - comment1 = Comment.query(session=dbsession).filter(Comment.uuid == response.json()["uuid"]).one_or_none() - assert comment1 is not None -def test_get_comments_by_lecturer_id(client, lecturer, comment): - lecturer1 = lecturer() - lecturer2 = lecturer() - comment1_1 = comment(lecturer_id=lecturer1.id) - comment1_2 = comment(lecturer_id=lecturer1.id) - comment2_1 = comment(lecturer_id=lecturer2.id) - query = {"lecturer_id": lecturer1.id} - response = client.get(f'{url}', params=query) +@pytest.mark.parametrize( + 'timetable_id,response_status', [(0, status.HTTP_200_OK), (1, status.HTTP_200_OK), (3, status.HTTP_200_OK)] +) +def test_comments_by_lecturer_id(client, lecturers_with_comments, timetable_id, response_status): + lecturers, comments = lecturers_with_comments + response = client.get(f'{url}', params={"lecturer_id": lecturers[timetable_id].id}) + assert response.status_code == response_status + if response.status_code == status.HTTP_200_OK: + json_response = response.json() + assert len(json_response["comments"]) == len( + [ + comment + for comment in lecturers[timetable_id].comments + if comment.review_status == ReviewStatus.APPROVED and not comment.is_deleted + ] + ) + + +def test_delete_comment(client, dbsession, comment): + response = client.delete(f'{url}/{comment.uuid}') assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["total"] == 2 - query = {"lecturer_id": lecturer2.id} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["total"] == 1 - query = {"lecturer_id": 2} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["total"] == 0 - - -def test_get_comments_unreviewed(client, lecturer, comment): - lecturer1 = lecturer() - lecturer2 = lecturer() - comment1_1 = comment(lecturer_id=lecturer1.id, review_status=ReviewStatus.APPROVED) - comment1_2 = comment(lecturer_id=lecturer1.id, review_status=ReviewStatus.PENDING) - comment2_1 = comment(lecturer_id=lecturer2.id, review_status=ReviewStatus.PENDING) - comment2_2 = comment(lecturer_id=lecturer2.id, review_status=ReviewStatus.DISMISSED) - query = {'unreviewed': True} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_403_FORBIDDEN - - -def test_delete_comment(client, dbsession, lecturer, comment): - test_lecturer = lecturer() - test_comment = comment(lecturer_id=test_lecturer.id) - response = client.delete(f'{url}/{test_comment.uuid}') - dbsession.refresh(test_comment) - assert response.status_code == status.HTTP_200_OK - response = client.get(f'{url}/{test_comment.uuid}') + response = client.get(f'{url}/{comment.uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND random_uuid = uuid.uuid4() response = client.delete(f'{url}/{random_uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND - comment1 = Comment.query(session=dbsession).filter(Comment.uuid == test_comment.uuid).one_or_none() - assert comment1 is None - assert test_comment.is_deleted + dbsession.refresh(comment) + assert comment.is_deleted + response = client.get(f'{url}/{comment.uuid}') + assert response.status_code == status.HTTP_404_NOT_FOUND diff --git a/tests/test_routes/test_lecturer.py b/tests/test_routes/test_lecturer.py index 13e5728..52c251b 100644 --- a/tests/test_routes/test_lecturer.py +++ b/tests/test_routes/test_lecturer.py @@ -13,129 +13,146 @@ settings = get_settings() -def test_create_lecturer(client, dbsession): +@pytest.mark.parametrize('response_status', [status.HTTP_200_OK, status.HTTP_409_CONFLICT]) +def test_create_lecturer(client, dbsession, response_status): body = {"first_name": 'Иван', "last_name": 'Иванов', "middle_name": 'Иванович', "timetable_id": 0} post_response = client.post(url, json=body) - assert post_response.status_code == status.HTTP_200_OK - check_same_response = client.post(url, json=body) - assert check_same_response.status_code == status.HTTP_409_CONFLICT - lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == 0).one_or_none() - assert lecturer is not None - dbsession.delete(lecturer) - dbsession.commit() - lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == 0).one_or_none() - assert lecturer is None - - -def test_get_lecturer(client, lecturer): - lecturer = lecturer() - get_response = client.get(f'{url}/{lecturer.id}') - print(get_response.json()) - assert get_response.status_code == status.HTTP_200_OK - json_response = get_response.json() - assert json_response["mark_kindness"] is None - assert json_response["mark_freebie"] is None - assert json_response["mark_clarity"] is None - assert json_response["mark_general"] is None - assert json_response["comments"] is None - - -def test_get_lecturer_with_comments(client, lecturer, comment): - test_lecturer = lecturer() - comment1 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.APPROVED) - comment2 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.PENDING) - comment3 = comment(lecturer_id=test_lecturer.id, review_status=ReviewStatus.DISMISSED) - query = { - "info": ['comments', 'mark'], - } - response = client.get(f'{url}/{test_lecturer.id}', params=query) + assert post_response.status_code == response_status + # cleanup on a last run + if response_status == status.HTTP_409_CONFLICT: + lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == 0).one_or_none() + assert lecturer is not None + dbsession.delete(lecturer) + dbsession.commit() + lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == 0).one_or_none() + assert lecturer is None + + +@pytest.mark.parametrize( + 'timetable_id,response_status', + [ + (0, status.HTTP_200_OK), + (1, status.HTTP_200_OK), + (2, status.HTTP_200_OK), + (3, status.HTTP_404_NOT_FOUND), + ], +) +def test_get_lecturer(client, dbsession, lecturers, timetable_id, response_status): + lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == timetable_id).one_or_none() + # check non-existing id request + lecturer_id = -1 + if lecturer: + lecturer_id = lecturer.id + get_response = client.get(f'{url}/{lecturer_id}') + assert get_response.status_code == response_status + if response_status == status.HTTP_200_OK: + json_response = get_response.json() + assert json_response["mark_kindness"] is None + assert json_response["mark_freebie"] is None + assert json_response["mark_clarity"] is None + assert json_response["mark_general"] is None + assert json_response["comments"] is None + + +@pytest.mark.parametrize( + 'timetable_id,mark_kindness,mark_freebie,mark_clarity,mark_general', + [(0, 1.5, 1.5, 1.5, 1.5), (1, 0, 0, 0, 0), (2, 0.5, 0.5, 0.5, 0.5)], +) +def test_get_lecturer_with_comments( + client, lecturers_with_comments, timetable_id, mark_kindness, mark_freebie, mark_clarity, mark_general +): + lecturers, comments = lecturers_with_comments + query = {"info": ['comments', 'mark']} + response = client.get(f'{url}/{lecturers[timetable_id].id}', params=query) assert response.status_code == status.HTTP_200_OK json_response = response.json() - assert json_response["mark_kindness"] == comment1.mark_kindness - assert json_response["mark_freebie"] == comment1.mark_freebie - assert json_response["mark_clarity"] == comment1.mark_clarity - assert json_response["mark_general"] == (comment1.mark_kindness + comment1.mark_freebie + comment1.mark_clarity) / 3 - assert len(json_response["comments"]) == 1 - assert json_response["comments"][0]["text"] == comment1.text - - -def test_get_lecturers_by_name(client, lecturer): - lecturer1 = lecturer(first_name='Алиса', last_name='Селезнёва', middle_name='Ивановна') - lecturer2 = lecturer(first_name='Марат', last_name='Сельков', middle_name='Анатольевич') - lecturer3 = lecturer(first_name='М', last_name='Измайлов', middle_name='Р') - lecturer4 = lecturer(first_name='Михаил', last_name='Измайлов', middle_name='Ильич') - query = {"name": "Селезнёва"} - response = client.get(f'{url}', params=query) + assert json_response["mark_kindness"] == mark_kindness + assert json_response["mark_freebie"] == mark_freebie + assert json_response["mark_clarity"] == mark_clarity + assert json_response["mark_general"] == mark_general + assert "test_subject" in json_response["subjects"] + assert "test_subject1" in json_response["subjects"] + assert "test_subject2" not in json_response["subjects"] + assert len(json_response["comments"]) == 2 + + +@pytest.mark.parametrize( + 'query,total,response_status', + [ + ({'name': 'test_lname1'}, 1, status.HTTP_200_OK), + ({'name': 'test'}, 2, status.HTTP_200_OK), + ({'name': 'testlname123'}, 0, status.HTTP_404_NOT_FOUND), + ], +) +def test_get_lecturers_by_name(client, lecturers, query, total, response_status): + get_response = client.get(f'{url}', params=query) + assert get_response.status_code == response_status + if response_status == status.HTTP_200_OK: + json_response = get_response.json() + json_response["total"] == total + assert json_response["lecturers"][0]["first_name"] == lecturers[0].first_name + + +@pytest.mark.parametrize( + 'body,response_status', + [ + ( + { + "first_name": 'Test', + "last_name": 'Testov', + "middle_name": 'Testovich', + }, + status.HTTP_200_OK, + ), + ( + { + "first_name": 'Testa', + "last_name": 'Testova', + "middle_name": 'Testovna', + }, + status.HTTP_200_OK, + ), + ( + { + "first_name": 'Test', + "last_name": 'Testov', + "middle_name": 1, + }, + status.HTTP_422_UNPROCESSABLE_ENTITY, + ), + ], +) +def test_update_lecturer(client, lecturer, body, response_status): + response = client.get(f'{url}/{lecturer.id}') assert response.status_code == status.HTTP_200_OK json_response = response.json() - assert json_response["total"] == 1 - assert json_response["lecturers"][0]["first_name"] == "Алиса" - - query = {"name": "Сел"} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["total"] == 2 - assert json_response["lecturers"][0]["first_name"] == "Алиса" - assert json_response["lecturers"][1]["first_name"] == "Марат" - - query = {"name": "Измайлова"} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_404_NOT_FOUND - - -def test_get_lecturers_by_subject(client, lecturer, comment): - lecturer1 = lecturer() - comment1 = comment(lecturer_id=lecturer1.id, subject="bibki") - lecturer2 = lecturer() - comment2 = comment(lecturer_id=lecturer2.id, subject="bibki") - lecturer3 = lecturer() - comment3 = comment(lecturer_id=lecturer2.id, subject="bobki") - query = {"subject": "bibki"} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["total"] == 2 - query = {"subject": "bibobki"} - response = client.get(f'{url}', params=query) - assert response.status_code == status.HTTP_404_NOT_FOUND - - -def test_update_lecturer(client, lecturer): - test_lecturer = lecturer() - body = { - "first_name": 'Алексей', - "last_name": 'Алексеев', - "middle_name": 'Алексеевич', - } - response = client.patch(f"{url}/{test_lecturer.id}", json=body) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["first_name"] == 'Алексей' - assert json_response["last_name"] == 'Алексеев' - assert json_response["middle_name"] == "Алексеевич" - body = { - "first_name": 'Иван', - "last_name": 'Иванов', - "middle_name": 'Иванович', - } - response = client.patch(f"{url}/{test_lecturer.id}", json=body) - assert response.status_code == status.HTTP_200_OK - json_response = response.json() - assert json_response["first_name"] == 'Иван' - assert json_response["last_name"] == 'Иванов' - assert json_response["middle_name"] == "Иванович" - - -def test_delete_lecturer(client, lecturer, comment, dbsession): - test_lecturer = lecturer() - test_comment = comment(lecturer_id=test_lecturer.id) - response = client.delete(f"{url}/{test_lecturer.id}") + assert json_response['first_name'] == 'test_fname' + assert json_response['last_name'] == 'test_lname' + assert json_response['middle_name'] == 'test_mname' + response = client.patch(f"{url}/{lecturer.id}", json=body) + assert response.status_code == response_status + if response_status == status.HTTP_200_OK: + json_response = response.json() + assert json_response["first_name"] == body["first_name"] + assert json_response["last_name"] == body["last_name"] + assert json_response["middle_name"] == body["middle_name"] + + +def test_delete_lecturer(client, dbsession, lecturers_with_comments): + lecturers, comments = lecturers_with_comments + response = client.delete(f"{url}/{lecturers[0].id}") assert response.status_code == status.HTTP_200_OK - response = client.delete(f"{url}/{test_lecturer.id}") - dbsession.refresh(test_lecturer) + # trying to delete deleted + response = client.delete(f"{url}/{lecturers[0].id}") assert response.status_code == status.HTTP_404_NOT_FOUND - response = client.get(f"{url}/{test_lecturer.id}") + dbsession.refresh(comments[0]) + dbsession.refresh(comments[1]) + dbsession.refresh(comments[2]) + dbsession.refresh(lecturers[0]) + assert comments[0].is_deleted + assert comments[1].is_deleted + assert comments[2].is_deleted + assert lecturers[0].is_deleted + # trying to get deleted + response = client.get(f'{url}/{lecturers[0].id}') assert response.status_code == status.HTTP_404_NOT_FOUND - assert test_comment.is_deleted - assert test_lecturer.is_deleted From b314da9ed8007d8c17418f73eafcd742c1ff320f Mon Sep 17 00:00:00 2001 From: default Date: Tue, 12 Nov 2024 13:50:08 +0000 Subject: [PATCH 05/10] lint --- tests/test_routes/test_comment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index da6b28b..7a33de2 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -64,7 +64,7 @@ ], ) def test_create_comment(client, dbsession, lecturers, body, timetable_id, response_status): - params = {"lecturer_id": lecturers[timetable_id].id} # Ensure we get the ID of the lecturer + params = {"lecturer_id": lecturers[timetable_id].id} post_response = client.post(url, json=body, params=params) assert post_response.status_code == response_status if response_status == status.HTTP_200_OK: From 912a1cecbb6b61b94f9ce6af3efb17857489e4f7 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 12 Nov 2024 13:51:19 +0000 Subject: [PATCH 06/10] delete file --- rating_api/utils/utils.py | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 rating_api/utils/utils.py diff --git a/rating_api/utils/utils.py b/rating_api/utils/utils.py deleted file mode 100644 index fb0a47f..0000000 --- a/rating_api/utils/utils.py +++ /dev/null @@ -1,15 +0,0 @@ -import random -import string - - -def random_string(length: int = 12): - """ - Сгенерировать рандомную строку - :param length: длина строки(по умолчанию 12) - :return: Сгенериированную строку - """ - return "".join([random.choice(string.ascii_lowercase) for _ in range(length)]) - - -def random_mark(): - return random.randint(-2, 2) From 66da6db9af4c57db7e4a2b081dfec66d8d7f0149 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 14 Nov 2024 14:37:43 +0000 Subject: [PATCH 07/10] +test_review_comment --- tests/conftest.py | 47 +++++++++++++++++++++++-------- tests/test_routes/test_comment.py | 17 +++++++++++ 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index a84a9cf..369cc80 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -62,6 +62,25 @@ def comment(dbsession, lecturer): dbsession.commit() +@pytest.fixture +def unreviewed_comment(dbsession, lecturer): + _comment = Comment( + subject="test_subject", + text="test_comment", + mark_kindness=1, + mark_clarity=1, + mark_freebie=1, + lecturer_id=lecturer.id, + review_status=ReviewStatus.PENDING, + ) + dbsession.add(_comment) + dbsession.commit() + yield _comment + dbsession.refresh(_comment) + dbsession.delete(_comment) + dbsession.commit() + + @pytest.fixture(scope='function') def lecturers(dbsession): """ @@ -101,18 +120,23 @@ def lecturers(dbsession): @pytest.fixture def lecturers_with_comments(dbsession, lecturers): """ - Creates 4 lecturers(one with flag is_deleted=True) with 3 comments to non-deleted lecturers 2 approved and one dismissed. Two of them have alike names. + Creates 4 lecturers(one with flag is_deleted=True) + with 4 comments to non-deleted lecturers 2 approved and one dismissed and one pending. + Two of them have alike names. """ comments_data = [ - (lecturers[0].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), - (lecturers[0].id, 'test_subject1', ReviewStatus.APPROVED, 2, 2, 2), - (lecturers[0].id, 'test_subject2', ReviewStatus.DISMISSED, -1, -1, -1), - (lecturers[1].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), - (lecturers[1].id, 'test_subject1', ReviewStatus.APPROVED, -1, -1, -1), - (lecturers[1].id, 'test_subject2', ReviewStatus.DISMISSED, -2, -2, -2), - (lecturers[2].id, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), - (lecturers[2].id, 'test_subject1', ReviewStatus.APPROVED, 0, 0, 0), - (lecturers[2].id, 'test_subject2', ReviewStatus.DISMISSED, 2, 2, 2), + (lecturers[0].id, 0, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[0].id, None, 'test_subject1', ReviewStatus.APPROVED, 2, 2, 2), + (lecturers[0].id, 0, 'test_subject2', ReviewStatus.DISMISSED, -1, -1, -1), + (lecturers[0].id, 0, 'test_subject2', ReviewStatus.PENDING, -2, -2, -2), + (lecturers[1].id, 0, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[1].id, None, 'test_subject1', ReviewStatus.APPROVED, -1, -1, -1), + (lecturers[1].id, 0, 'test_subject2', ReviewStatus.DISMISSED, -2, -2, -2), + (lecturers[1].id, 0, 'test_subject2', ReviewStatus.PENDING, -2, -2, -2), + (lecturers[2].id, 0, 'test_subject', ReviewStatus.APPROVED, 1, 1, 1), + (lecturers[2].id, None, 'test_subject1', ReviewStatus.APPROVED, 0, 0, 0), + (lecturers[2].id, 0, 'test_subject2', ReviewStatus.DISMISSED, 2, 2, 2), + (lecturers[2].id, 0, 'test_subject2', ReviewStatus.PENDING, -2, -2, -2), ] comments = [ @@ -123,9 +147,10 @@ def lecturers_with_comments(dbsession, lecturers): mark_clarity=mark_clarity, mark_freebie=mark_freebie, lecturer_id=lecturer_id, + user_id=user_id, review_status=review_status, ) - for lecturer_id, subject, review_status, mark_kindness, mark_clarity, mark_freebie in comments_data + for lecturer_id, user_id, subject, review_status, mark_kindness, mark_clarity, mark_freebie in comments_data ] dbsession.add_all(comments) diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index 7a33de2..5939f57 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -104,6 +104,23 @@ def test_comments_by_lecturer_id(client, lecturers_with_comments, timetable_id, ) +@pytest.mark.parametrize( + 'review_status, response_status', + [ + ("approved", status.HTTP_200_OK), + ("dismissed", status.HTTP_200_OK), + ("wrong_status", status.HTTP_422_UNPROCESSABLE_ENTITY), + ], +) +def test_review_comment(client, dbsession, unreviewed_comment, review_status, response_status): + query = {"review_status": review_status} + response = client.patch(f"{url}/{unreviewed_comment.uuid}", params=query) + assert response.status_code == response_status + if response.status_code == status.HTTP_200_OK: + dbsession.refresh(unreviewed_comment) + assert unreviewed_comment.review_status == ReviewStatus(review_status) + + def test_delete_comment(client, dbsession, comment): response = client.delete(f'{url}/{comment.uuid}') assert response.status_code == status.HTTP_200_OK From 4cbde9a778dbe77a4e0534aaa2ac6e61c36b269a Mon Sep 17 00:00:00 2001 From: Timur Enikeev Date: Sat, 9 Nov 2024 16:38:48 -0500 Subject: [PATCH 08/10] Case insensitive search --- rating_api/models/db.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rating_api/models/db.py b/rating_api/models/db.py index a25a820..ab645c6 100644 --- a/rating_api/models/db.py +++ b/rating_api/models/db.py @@ -41,8 +41,14 @@ def search_by_name(self, query: str) -> bool: response = true query = query.split(' ') for q in query: + q = q.lower() response = and_( - response, or_(self.first_name.contains(q), self.middle_name.contains(q), self.last_name.contains(q)) + response, + or_( + func.lower(self.first_name).contains(q), + func.lower(self.middle_name).contains(q), + func.lower(self.last_name).contains(q), + ), ) return response From 7c6290c23ced8ad658a4ebd37fca1ce6da2800e1 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 15 Nov 2024 15:03:04 +0000 Subject: [PATCH 09/10] fixes + Register check --- tests/conftest.py | 8 +++---- tests/test_routes/test_comment.py | 36 +++++++++++++++++------------- tests/test_routes/test_lecturer.py | 27 ++++++++++++---------- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 369cc80..a0a455e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -34,7 +34,7 @@ def dbsession() -> Session: @pytest.fixture def lecturer(dbsession): - _lecturer = Lecturer(first_name="test_fname", last_name="test_lname", middle_name="test_mname", timetable_id=0) + _lecturer = Lecturer(first_name="test_fname", last_name="test_lname", middle_name="test_mname", timetable_id=9900) dbsession.add(_lecturer) dbsession.commit() yield _lecturer @@ -87,9 +87,9 @@ def lecturers(dbsession): Creates 4 lecturers(one with flag is_deleted=True) """ lecturers_data = [ - ("test_fname1", "test_lname1", "test_mname1", 0), - ("test_fname2", "test_lname2", "test_mname2", 1), - ("Bibka", "Bobka", "Bobkovich", 2), + ("test_fname1", "test_lname1", "test_mname1", 9900), + ("test_fname2", "test_lname2", "test_mname2", 9901), + ("Bibka", "Bobka", "Bobkovich", 9902), ] lecturers = [ diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index 5939f57..03e7cbd 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -15,7 +15,7 @@ @pytest.mark.parametrize( - 'body,timetable_id,response_status', + 'body,lecturer_n,response_status', [ ( { @@ -63,8 +63,8 @@ ), ], ) -def test_create_comment(client, dbsession, lecturers, body, timetable_id, response_status): - params = {"lecturer_id": lecturers[timetable_id].id} +def test_create_comment(client, dbsession, lecturers, body, lecturer_n, response_status): + params = {"lecturer_id": lecturers[lecturer_n].id} post_response = client.post(url, json=body, params=params) assert post_response.status_code == response_status if response_status == status.HTTP_200_OK: @@ -72,7 +72,7 @@ def test_create_comment(client, dbsession, lecturers, body, timetable_id, respon assert comment is not None user_comment = ( LecturerUserComment.query(session=dbsession) - .filter(LecturerUserComment.lecturer_id == lecturers[timetable_id].id) + .filter(LecturerUserComment.lecturer_id == lecturers[lecturer_n].id) .one_or_none() ) assert user_comment is not None @@ -87,38 +87,42 @@ def test_get_comment(client, comment): @pytest.mark.parametrize( - 'timetable_id,response_status', [(0, status.HTTP_200_OK), (1, status.HTTP_200_OK), (3, status.HTTP_200_OK)] + 'lecturer_n,response_status', [(0, status.HTTP_200_OK), (1, status.HTTP_200_OK), (3, status.HTTP_200_OK)] ) -def test_comments_by_lecturer_id(client, lecturers_with_comments, timetable_id, response_status): +def test_comments_by_lecturer_id(client, lecturers_with_comments, lecturer_n, response_status): lecturers, comments = lecturers_with_comments - response = client.get(f'{url}', params={"lecturer_id": lecturers[timetable_id].id}) + response = client.get(f'{url}', params={"lecturer_id": lecturers[lecturer_n].id}) assert response.status_code == response_status if response.status_code == status.HTTP_200_OK: json_response = response.json() assert len(json_response["comments"]) == len( [ comment - for comment in lecturers[timetable_id].comments + for comment in lecturers[lecturer_n].comments if comment.review_status == ReviewStatus.APPROVED and not comment.is_deleted ] ) @pytest.mark.parametrize( - 'review_status, response_status', + 'review_status, response_status,is_reviewed', [ - ("approved", status.HTTP_200_OK), - ("dismissed", status.HTTP_200_OK), - ("wrong_status", status.HTTP_422_UNPROCESSABLE_ENTITY), + ("approved", status.HTTP_200_OK, True), + ("approved", status.HTTP_200_OK, False), + ("dismissed", status.HTTP_200_OK, True), + ("dismissed", status.HTTP_200_OK, False), + ("wrong_status", status.HTTP_422_UNPROCESSABLE_ENTITY, True), + ("wrong_status", status.HTTP_422_UNPROCESSABLE_ENTITY, False), ], ) -def test_review_comment(client, dbsession, unreviewed_comment, review_status, response_status): +def test_review_comment(client, dbsession, unreviewed_comment, comment, review_status, response_status, is_reviewed): + commment_to_reivew = comment if is_reviewed else unreviewed_comment query = {"review_status": review_status} - response = client.patch(f"{url}/{unreviewed_comment.uuid}", params=query) + response = client.patch(f"{url}/{commment_to_reivew.uuid}", params=query) assert response.status_code == response_status if response.status_code == status.HTTP_200_OK: - dbsession.refresh(unreviewed_comment) - assert unreviewed_comment.review_status == ReviewStatus(review_status) + dbsession.refresh(commment_to_reivew) + assert commment_to_reivew.review_status == ReviewStatus(review_status) def test_delete_comment(client, dbsession, comment): diff --git a/tests/test_routes/test_lecturer.py b/tests/test_routes/test_lecturer.py index 52c251b..81b90cb 100644 --- a/tests/test_routes/test_lecturer.py +++ b/tests/test_routes/test_lecturer.py @@ -29,7 +29,7 @@ def test_create_lecturer(client, dbsession, response_status): @pytest.mark.parametrize( - 'timetable_id,response_status', + 'lecturer_n,response_status', [ (0, status.HTTP_200_OK), (1, status.HTTP_200_OK), @@ -37,8 +37,10 @@ def test_create_lecturer(client, dbsession, response_status): (3, status.HTTP_404_NOT_FOUND), ], ) -def test_get_lecturer(client, dbsession, lecturers, timetable_id, response_status): - lecturer = dbsession.query(Lecturer).filter(Lecturer.timetable_id == timetable_id).one_or_none() +def test_get_lecturer(client, dbsession, lecturers, lecturer_n, response_status): + lecturer = ( + dbsession.query(Lecturer).filter(Lecturer.timetable_id == lecturers[lecturer_n].timetable_id).one_or_none() + ) # check non-existing id request lecturer_id = -1 if lecturer: @@ -55,24 +57,24 @@ def test_get_lecturer(client, dbsession, lecturers, timetable_id, response_statu @pytest.mark.parametrize( - 'timetable_id,mark_kindness,mark_freebie,mark_clarity,mark_general', + 'lecturer_n,mark_kindness,mark_freebie,mark_clarity,mark_general', [(0, 1.5, 1.5, 1.5, 1.5), (1, 0, 0, 0, 0), (2, 0.5, 0.5, 0.5, 0.5)], ) def test_get_lecturer_with_comments( - client, lecturers_with_comments, timetable_id, mark_kindness, mark_freebie, mark_clarity, mark_general + client, lecturers_with_comments, lecturer_n, mark_kindness, mark_freebie, mark_clarity, mark_general ): lecturers, comments = lecturers_with_comments query = {"info": ['comments', 'mark']} - response = client.get(f'{url}/{lecturers[timetable_id].id}', params=query) + response = client.get(f'{url}/{lecturers[lecturer_n].id}', params=query) assert response.status_code == status.HTTP_200_OK json_response = response.json() assert json_response["mark_kindness"] == mark_kindness assert json_response["mark_freebie"] == mark_freebie assert json_response["mark_clarity"] == mark_clarity assert json_response["mark_general"] == mark_general - assert "test_subject" in json_response["subjects"] - assert "test_subject1" in json_response["subjects"] - assert "test_subject2" not in json_response["subjects"] + assert comments[lecturer_n * 4 + 0].subject in json_response["subjects"] + assert comments[lecturer_n * 4 + 1].subject in json_response["subjects"] + assert comments[lecturer_n * 4 + 2].subject not in json_response["subjects"] assert len(json_response["comments"]) == 2 @@ -80,6 +82,7 @@ def test_get_lecturer_with_comments( 'query,total,response_status', [ ({'name': 'test_lname1'}, 1, status.HTTP_200_OK), + ({'name': 'TeSt_LnAmE1'}, 1, status.HTTP_200_OK), ({'name': 'test'}, 2, status.HTTP_200_OK), ({'name': 'testlname123'}, 0, status.HTTP_404_NOT_FOUND), ], @@ -126,9 +129,9 @@ def test_update_lecturer(client, lecturer, body, response_status): response = client.get(f'{url}/{lecturer.id}') assert response.status_code == status.HTTP_200_OK json_response = response.json() - assert json_response['first_name'] == 'test_fname' - assert json_response['last_name'] == 'test_lname' - assert json_response['middle_name'] == 'test_mname' + assert json_response['first_name'] == lecturer.first_name + assert json_response['last_name'] == lecturer.last_name + assert json_response['middle_name'] == lecturer.middle_name response = client.patch(f"{url}/{lecturer.id}", json=body) assert response.status_code == response_status if response_status == status.HTTP_200_OK: From 6576929e2fed36574feb8dac905f149b78b7c7fb Mon Sep 17 00:00:00 2001 From: default Date: Fri, 15 Nov 2024 15:19:10 +0000 Subject: [PATCH 10/10] redo create comment for deleted lecturer check --- tests/test_routes/test_comment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index 03e7cbd..44c3462 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -54,12 +54,12 @@ { "subject": "test_subject", "text": "test_text", - "mark_kindness": 5, + "mark_kindness": 1, "mark_freebie": -2, "mark_clarity": 0, }, 3, - status.HTTP_400_BAD_REQUEST, + status.HTTP_404_NOT_FOUND, ), ], )