From e92254cdaf45067240a2d1c80ac6ff78f411ab7e Mon Sep 17 00:00:00 2001 From: minhtrannhat Date: Sat, 2 Mar 2024 16:53:00 -0500 Subject: [PATCH] feat(api+testing): select todos + testing --- .../src/neo_neo_todo/migrations/test_data.py | 20 ++++++++- backend/src/neo_neo_todo/models/todo.py | 45 +++++++++++++++++++ backend/tests/test_model_todo.py | 19 ++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 backend/src/neo_neo_todo/models/todo.py create mode 100644 backend/tests/test_model_todo.py diff --git a/backend/src/neo_neo_todo/migrations/test_data.py b/backend/src/neo_neo_todo/migrations/test_data.py index 0aecc7f..695999d 100644 --- a/backend/src/neo_neo_todo/migrations/test_data.py +++ b/backend/src/neo_neo_todo/migrations/test_data.py @@ -44,7 +44,25 @@ def generate_test_data() -> None: sql.SQL( """ INSERT INTO todos (member_id, task) - VALUES (1, 'Test Task') + VALUES (1, 'Test Task 1') + """ + ) + ) + + cur.execute( + sql.SQL( + """ + INSERT INTO todos (member_id, task) + VALUES (1, 'Test Task 2') + """ + ) + ) + + cur.execute( + sql.SQL( + """ + INSERT INTO todos (member_id, task) + VALUES (1, 'Test Task 3') """ ) ) diff --git a/backend/src/neo_neo_todo/models/todo.py b/backend/src/neo_neo_todo/models/todo.py new file mode 100644 index 0000000..0c9cc14 --- /dev/null +++ b/backend/src/neo_neo_todo/models/todo.py @@ -0,0 +1,45 @@ +from dataclasses import dataclass +from datetime import datetime + +from psycopg import sql +from psycopg.rows import class_row +from psycopg_pool import AsyncConnectionPool +from pydantic import constr + + +@dataclass +class Todo: + complete: bool + due: datetime | None + id: int + task: constr(strip_whitespace=True, min_length=1) # type: ignore + + +async def select_todos( + db: AsyncConnectionPool, member_id: int, complete: bool | None = None +) -> list[Todo]: + async with db.connection() as conn: + async with conn.cursor(row_factory=class_row(Todo)) as curr: + + if complete is None: + condition = sql.SQL("member_id = {}").format(sql.Literal(member_id)) + else: + condition = sql.SQL("member_id = {} AND complete = {}").format( + sql.Literal(member_id), sql.Literal(complete) + ) + + query = sql.SQL( + """ + SELECT id, complete, due, task + FROM todos + WHERE {} + """ + ).format(condition) + + await curr.execute( + query, + ) + + todos = await curr.fetchall() + + return todos diff --git a/backend/tests/test_model_todo.py b/backend/tests/test_model_todo.py new file mode 100644 index 0000000..9460c26 --- /dev/null +++ b/backend/tests/test_model_todo.py @@ -0,0 +1,19 @@ +from src.neo_neo_todo.models.todo import select_todos + + +async def test_model_todo_select_todos(db_pool): + todos_list_all = await select_todos(db_pool, 1) + + assert len(todos_list_all) == 3 + + todos_list_completed_false = await select_todos(db_pool, 1, False) + + assert len(todos_list_completed_false) == 3 + + todos_list_completed_true = await select_todos(db_pool, 1, True) + + assert len(todos_list_completed_true) == 0 + + todos_list_non_existent_member_id = await select_todos(db_pool, 12341234) + + assert len(todos_list_non_existent_member_id) == 0