home · contact · privacy
Add most basic Todo infrastructure.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 12 Apr 2024 19:50:19 +0000 (21:50 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 12 Apr 2024 19:50:19 +0000 (21:50 +0200)
plomtask/todos.py [new file with mode: 0644]
tests/todos.py [new file with mode: 0644]

diff --git a/plomtask/todos.py b/plomtask/todos.py
new file mode 100644 (file)
index 0000000..1b6b740
--- /dev/null
@@ -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 (file)
index 0000000..93b34d1
--- /dev/null
@@ -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)