From a4ca74f81ae42abe27cf6dbab7ef18c850db72c2 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Fri, 12 Apr 2024 21:50:19 +0200 Subject: [PATCH] Add most basic Todo infrastructure. --- plomtask/todos.py | 46 ++++++++++++++++++++++++++++++++++++ tests/todos.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 plomtask/todos.py create mode 100644 tests/todos.py diff --git a/plomtask/todos.py b/plomtask/todos.py new file mode 100644 index 0000000..1b6b740 --- /dev/null +++ b/plomtask/todos.py @@ -0,0 +1,46 @@ +"""Actionables.""" +from __future__ import annotations +from sqlite3 import Row +from plomtask.db import DatabaseConnection +from plomtask.days import Day +from plomtask.processes import Process +from plomtask.exceptions import NotFoundException + + +class Todo: + """Individual actionable.""" + + def __init__(self, id_: int | None, process: Process, + is_done: bool, day: Day) -> None: + self.id_ = id_ + self.process = process + self.is_done = is_done + self.day = day + + def __eq__(self, other: object) -> bool: + return isinstance(other, self.__class__) and self.id_ == other.id_ + + @classmethod + def from_table_row(cls, row: Row, db_conn: DatabaseConnection) -> Todo: + """Make Todo from database row.""" + return cls(id_=row[0], + process=Process.by_id(db_conn, row[1]), + is_done=row[2], + day=Day.by_date(db_conn, row[3])) + + @classmethod + def by_date(cls, db_conn: DatabaseConnection, date: str) -> list[Todo]: + """Collect all Todos for Day of date.""" + todos = [] + for row in db_conn.exec('SELECT * FROM todos WHERE day = ?', (date,)): + todos += [cls.from_table_row(row, db_conn)] + return todos + + def save(self, db_conn: DatabaseConnection) -> None: + """Write self to DB.""" + if self.process.id_ is None: + raise NotFoundException('Process of Todo without ID (not saved?)') + cursor = db_conn.exec('REPLACE INTO todos VALUES (?,?,?,?)', + (self.id_, self.process.id_, + self.is_done, self.day.date)) + self.id_ = cursor.lastrowid diff --git a/tests/todos.py b/tests/todos.py new file mode 100644 index 0000000..93b34d1 --- /dev/null +++ b/tests/todos.py @@ -0,0 +1,60 @@ +"""Test Todos module.""" +from tests.utils import TestCaseWithDB, TestCaseWithServer +from plomtask.todos import Todo +from plomtask.days import Day +from plomtask.processes import Process +from plomtask.exceptions import NotFoundException + + +class TestsWithDB(TestCaseWithDB): + """Tests not requiring DB setup.""" + + def test_Todo_by_date(self) -> None: + """Test creation and findability of Todos.""" + day1 = Day('2024-01-01') + day2 = Day('2024-01-02') + process1 = Process(None) + todo1 = Todo(None, process1, False, day1) + with self.assertRaises(NotFoundException): + todo1.save(self.db_conn) + process1.save_without_steps(self.db_conn) + todo1.save(self.db_conn) + todo2 = Todo(None, process1, False, day1) + todo2.save(self.db_conn) + with self.assertRaises(NotFoundException): + Todo.by_date(self.db_conn, day1.date), + day1.save(self.db_conn) + day2.save(self.db_conn) + self.assertEqual(Todo.by_date(self.db_conn, day1.date), [todo1, todo2]) + self.assertEqual(Todo.by_date(self.db_conn, day2.date), []) + self.assertEqual(Todo.by_date(self.db_conn, 'foo'), []) + + +class TestsWithServer(TestCaseWithServer): + """Tests against our HTTP server/handler (and database).""" + + def test_do_POST_todo(self) -> None: + """Test Todo posting of POST /day.""" + form_data = {'title': '', 'description': '', 'effort': 1} + self.check_post(form_data, '/process?id=', 302, '/') + self.check_post(form_data, '/process?id=', 302, '/') + process1 = Process.by_id(self.db_conn, 1) + process2 = Process.by_id(self.db_conn, 2) + form_data = {'comment': ''} + self.check_post(form_data, '/day?date=2024-01-01', 302, '/') + self.assertEqual(Todo.by_date(self.db_conn, '2024-01-01'), []) + form_data['new_todo'] = str(process1.id_) + self.check_post(form_data, '/day?date=2024-01-01', 302, '/') + todos = Todo.by_date(self.db_conn, '2024-01-01') + self.assertEqual(1, len(todos)) + todo1 = todos[0] + self.assertEqual(todo1.id_, 1) + self.assertEqual(todo1.process.id_, process1.id_) + self.assertEqual(todo1.is_done, False) + form_data['new_todo'] = str(process2.id_) + self.check_post(form_data, '/day?date=2024-01-01', 302, '/') + todos = Todo.by_date(self.db_conn, '2024-01-01') + todo1 = todos[1] + self.assertEqual(todo1.id_, 2) + self.assertEqual(todo1.process.id_, process2.id_) + self.assertEqual(todo1.is_done, False) -- 2.30.2