From 5cf062c7a049577c2f92d10f0bb312d7f9284812 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Thu, 29 Dec 2022 17:47:40 +0100 Subject: [PATCH] Feat: add put for student and fix fixture around database --- backend/api/main.py | 23 ++++++ .../repository/student_sqlite_repository.py | 17 ++++- tests/conftest.py | 17 +++-- tests/e2e/test_api_students.py | 21 ++++++ tests/e2e/test_api_tribes.py | 2 +- .../test_repository_student_sqlite.py | 18 ++++- tests/integration/test_repository_tribe.py | 73 ------------------- .../test_repository_tribe_sqlite.py | 10 ++- 8 files changed, 94 insertions(+), 87 deletions(-) delete mode 100644 tests/integration/test_repository_tribe.py diff --git a/backend/api/main.py b/backend/api/main.py index 3498813..6fdf1c8 100644 --- a/backend/api/main.py +++ b/backend/api/main.py @@ -86,3 +86,26 @@ async def post_student(item: StudentModel): conn.commit() return student.to_dict() + + +@app.put( + "/students/{student_id}", + status_code=status.HTTP_200_OK, + response_model=StudentModel, +) +async def put_student(student_id, item: StudentModel): + tribe_name = item.tribe_name + try: + tribe = tribe_repo.get(tribe_name) + except TribeRepositoryError: + return JSONResponse( + status_code=status.HTTP_409_CONFLICT, + content=f"The tribe {tribe_name} does not exists. You can't add a student in it.", + ) + + student = Student(name=item.name, tribe=tribe, id=student_id) + + student_repo.update(student) + conn.commit() + + return student.to_dict() diff --git a/backend/repository/student_sqlite_repository.py b/backend/repository/student_sqlite_repository.py index 1573843..03c7156 100644 --- a/backend/repository/student_sqlite_repository.py +++ b/backend/repository/student_sqlite_repository.py @@ -3,6 +3,10 @@ from backend.model.tribe import Tribe from backend.repository.abstract_repository import AbstractRepository +class StudentRepositoryError(Exception): + pass + + class StudentSQLiteRepository(AbstractRepository): def __init__(self, conn) -> None: self.conn = conn @@ -19,7 +23,16 @@ class StudentSQLiteRepository(AbstractRepository): ), ) - def update(self, name: str, student: Student) -> None: + def update(self, student: Student) -> None: + search_student = self.conn.execute( + """ + SELECT id FROM students WHERE id=:id + """, + {"id": student.id}, + ).fetchone() + if search_student is None: + raise StudentRepositoryError(f"The student ({student.id=}) does not exists") + self.conn.execute( """ UPDATE students SET name=:newname, tribe_name=:newtribe WHERE id=:id @@ -32,6 +45,8 @@ class StudentSQLiteRepository(AbstractRepository): ) def _rebuild_student(self, row: tuple, tribes: list[Tribe]) -> Student: + print(row) + print([t.name for t in tribes]) tribe = next(filter(lambda t: t.name == row[2], tribes)) return Student(id=row[0], name=row[1], tribe=tribe) diff --git a/tests/conftest.py b/tests/conftest.py index d60ca59..7667366 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -30,18 +30,23 @@ def session(in_memory_db): @pytest.fixture def sqlite_conn(): - conn = sqlite3.connect("sqlite.db") + sqlite_db = ":memory:" + conn = sqlite3.connect(sqlite_db) create_db(conn) yield conn conn.close() @pytest.fixture -def clean_db(sqlite_conn): - sqlite_conn.execute("""DROP TABLE tribes""") - sqlite_conn.execute("""DROP TABLE students""") - sqlite_conn.commit() - create_db(sqlite_conn) +def clean_db(): + sqlite_db = "sqlite.db" + conn = sqlite3.connect(sqlite_db) + create_db(conn) + yield + cursor = conn.cursor() + cursor.execute("""DROP TABLE tribes""") + cursor.execute("""DROP TABLE students""") + conn.commit() @pytest.fixture diff --git a/tests/e2e/test_api_students.py b/tests/e2e/test_api_students.py index e05de00..b29bd95 100644 --- a/tests/e2e/test_api_students.py +++ b/tests/e2e/test_api_students.py @@ -55,3 +55,24 @@ def test_api_post_student_in_non_existant_tribe(): r.json() == f"The tribe {tribe.name+'_'} does not exists. You can't add a student in it." ) + + +@pytest.mark.usefixtures("restart_api") +@pytest.mark.usefixtures("clean_db") +def test_api_put_student(): + url = config.get_api_url() + tribe = build_tribes(1)[0] + requests.post(f"{url}/tribes", json=tribe.to_dict()) + + data = {"name": "zart", "tribe_name": tribe.name} + r = requests.post(f"{url}/students", json=data) + + student = r.json() + student["name"] = "Choupinou" + + r2 = requests.put(f"{url}/students/{student['id']}", json=student) + + assert r2.status_code == 200 + assert r2.json()["name"] == "Choupinou" + assert r2.json()["tribe_name"] == tribe.name + assert r2.json()["id"] == r.json()["id"] diff --git a/tests/e2e/test_api_tribes.py b/tests/e2e/test_api_tribes.py index a5b529b..b027aa9 100644 --- a/tests/e2e/test_api_tribes.py +++ b/tests/e2e/test_api_tribes.py @@ -28,7 +28,7 @@ def test_api_post_tribe_already_exists(): data = {"name": "Pioupiou", "level": "2nd"} url = config.get_api_url() - r = requests.post(f"{url}/tribes", json=data) + requests.post(f"{url}/tribes", json=data) r = requests.post(f"{url}/tribes", json=data) assert r.status_code == 409 diff --git a/tests/integration/test_repository_student_sqlite.py b/tests/integration/test_repository_student_sqlite.py index 2e70854..705e1aa 100644 --- a/tests/integration/test_repository_student_sqlite.py +++ b/tests/integration/test_repository_student_sqlite.py @@ -4,7 +4,10 @@ import pytest from backend.model.student import Student from backend.model.tribe import Tribe -from backend.repository.student_sqlite_repository import StudentSQLiteRepository +from backend.repository.student_sqlite_repository import ( + StudentRepositoryError, + StudentSQLiteRepository, +) from tests.integration.test_repository_tribe_sqlite import populate_tribes from tests.model.fakes import build_student @@ -100,7 +103,7 @@ def test_update_student(sqlite_conn): student.name = "Boby" student.tribe = prebuild_tribes[-1] - student_repo.update(student.id, student) + student_repo.update(student) sqlite_conn.commit() student_list = student_repo.list(prebuild_tribes) @@ -110,6 +113,17 @@ def test_update_student(sqlite_conn): assert moded_student == student +def test_update_student_does_not_exists(sqlite_conn): + prebuild_tribes = populate_tribes(sqlite_conn) + + student_repo = StudentSQLiteRepository(sqlite_conn) + + student = Student(name="jkl", tribe=prebuild_tribes[0]) + + with pytest.raises(StudentRepositoryError): + student_repo.update(student) + + def test_delete_student(sqlite_conn): prebuild_tribes = populate_tribes(sqlite_conn) prebuild_students = populate_students(sqlite_conn, prebuild_tribes) diff --git a/tests/integration/test_repository_tribe.py b/tests/integration/test_repository_tribe.py deleted file mode 100644 index acd253c..0000000 --- a/tests/integration/test_repository_tribe.py +++ /dev/null @@ -1,73 +0,0 @@ -from backend.model.tribe import Tribe -from backend.repository.tribe_sqlalchemy_repository import TribeSQLAlchemyRepository - - -def test_add_tribe(session): - tribe_infos = ("tribe1", "2nd") - tribe = Tribe(*tribe_infos) - tribe_repo = TribeSQLAlchemyRepository(session) - - tribe_repo.add(tribe) - session.commit() - - rows = list(session.execute("SELECT name, level FROM 'tribes'")) - assert rows == [tribe_infos] - - -def test_list_tribes(session): - session.execute( - "INSERT INTO tribes (name, level) VALUES " - "('tribe1', '2nd')," - "('tribe2', '1ST')" - ) - expected = [ - (Tribe("tribe1", "2nd")), - (Tribe("tribe2", "1ST")), - ] - tribe_repo = TribeSQLAlchemyRepository(session) - assert tribe_repo.list() == expected - - -def test_update_tribe(session): - session.execute( - "INSERT INTO tribes (name, level) VALUES " - "('tribe1', '2nd')," - "('tribe2', '1ST')" - ) - tribe_repo = TribeSQLAlchemyRepository(session) - tribe_repo.update("tribe1", Tribe("tribe3", "Term")) - session.commit() - - expected = [ - (Tribe("tribe3", "Term")), - (Tribe("tribe2", "1ST")), - ] - assert tribe_repo.list() == expected - - -def test_get_tribes(session): - session.execute( - "INSERT INTO tribes (name, level) VALUES " - "('tribe1', '2nd')," - "('tribe2', '1ST')" - ) - expected = Tribe("tribe1", "2nd") - tribe_repo = TribeSQLAlchemyRepository(session) - assert tribe_repo.get("tribe1") == expected - - -def test_delete_tribes(session): - session.execute( - "INSERT INTO tribes (name, level) VALUES " - "('tribe1', '2nd')," - "('tribe2', '1ST')" - ) - expected = [ - (Tribe("tribe2", "1ST")), - ] - tribe_repo = TribeSQLAlchemyRepository(session) - - tribe_repo.delete(Tribe("tribe1", "2nd")) - session.commit() - - assert tribe_repo.list() == expected diff --git a/tests/integration/test_repository_tribe_sqlite.py b/tests/integration/test_repository_tribe_sqlite.py index e4492d2..6e8f709 100644 --- a/tests/integration/test_repository_tribe_sqlite.py +++ b/tests/integration/test_repository_tribe_sqlite.py @@ -3,7 +3,10 @@ import sqlite3 import pytest from backend.model.tribe import Tribe -from backend.repository.tribe_sqlite_repository import TribeSQLiteRepository +from backend.repository.tribe_sqlite_repository import ( + TribeRepositoryError, + TribeSQLiteRepository, +) from tests.model.fakes import build_tribes @@ -36,7 +39,7 @@ def test_get_tribe_not_exists(sqlite_conn): prebuild_tribes = populate_tribes(sqlite_conn) tribe_repo = TribeSQLiteRepository(sqlite_conn) - with pytest.raises(ValueError): + with pytest.raises(TribeRepositoryError): tribe_repo.get("Tribe0") @@ -50,7 +53,6 @@ def test_list_tribes(sqlite_conn): def test_add_tribe(sqlite_conn): - tribe_repo = TribeSQLiteRepository(sqlite_conn) tribe_infos = ("tribe1", "2nd") @@ -76,7 +78,7 @@ def test_add_tribe_fail_exists(sqlite_conn): tribe_repo = TribeSQLiteRepository(sqlite_conn) existing_tribe = prebuild_tribes[0] - with pytest.raises(sqlite3.IntegrityError): + with pytest.raises(TribeRepositoryError): tribe_repo.add(existing_tribe)