From: Christian Heller
Date: Fri, 12 Apr 2024 20:17:25 +0000 (+0200)
Subject: Add GET /todo and Todo retrieval by ID.
X-Git-Url: https://plomlompom.com/repos/%22https:/validator.w3.org/%7B%7Bdb.prefix%7D%7D/%7B%7Bprefix%7D%7D?a=commitdiff_plain;h=982d712cbf12acde21ce448e0d1ed28468f1c90e;p=plomtask
Add GET /todo and Todo retrieval by ID.
---
diff --git a/plomtask/http.py b/plomtask/http.py
index 1743b90..91c3224 100644
--- a/plomtask/http.py
+++ b/plomtask/http.py
@@ -10,6 +10,7 @@ from plomtask.exceptions import HandledException, BadFormatException, \
NotFoundException
from plomtask.db import DatabaseConnection, DatabaseFile
from plomtask.processes import Process
+from plomtask.todos import Todo
TEMPLATES_DIR = 'templates'
@@ -110,7 +111,7 @@ class TaskHandler(BaseHTTPRequestHandler):
"""Handle any GET request."""
try:
conn, site, params = self._init_handling()
- if site in {'calendar', 'day', 'process', 'processes'}:
+ if site in {'calendar', 'day', 'process', 'processes', 'todo'}:
html = getattr(self, f'do_GET_{site}')(conn, params)
elif '' == site:
self._redirect('/day')
@@ -137,7 +138,18 @@ class TaskHandler(BaseHTTPRequestHandler):
"""Show single Day of ?date=."""
date = params.get_str('date', todays_date())
day = Day.by_date(conn, date, create=True)
- return self.server.jinja.get_template('day.html').render(day=day)
+ todos = Todo.by_date(conn, date)
+ return self.server.jinja.get_template('day.html').render(
+ day=day, processes=Process.all(conn), todos=todos)
+
+ def do_GET_todo(self, conn: DatabaseConnection, params:
+ ParamsParser) -> str:
+ """Show single Todo of ?id=."""
+ id_ = params.get_int_or_none('id')
+ if id_ is None:
+ raise NotFoundException('Todo of ID not found.')
+ todo = Todo.by_id(conn, id_)
+ return self.server.jinja.get_template('todo.html').render(todo=todo)
def do_GET_process(self, conn: DatabaseConnection,
params: ParamsParser) -> str:
@@ -177,11 +189,16 @@ class TaskHandler(BaseHTTPRequestHandler):
def do_POST_day(self, conn: DatabaseConnection, params: ParamsParser,
form_data: PostvarsParser) -> None:
- """Update or insert Day of date and fields defined in postvars."""
+ """Update or insert Day of date and Todos mapped to it."""
date = params.get_str('date')
day = Day.by_date(conn, date, create=True)
day.comment = form_data.get_str('comment')
day.save(conn)
+ process_id = form_data.get_int_or_none('new_todo')
+ if process_id is not None:
+ process = Process.by_id(conn, process_id)
+ todo = Todo(None, process, False, day)
+ todo.save(conn)
def do_POST_process(self, conn: DatabaseConnection, params: ParamsParser,
form_data: PostvarsParser) -> None:
diff --git a/plomtask/todos.py b/plomtask/todos.py
index 1b6b740..7150f0d 100644
--- a/plomtask/todos.py
+++ b/plomtask/todos.py
@@ -28,6 +28,13 @@ class Todo:
is_done=row[2],
day=Day.by_date(db_conn, row[3]))
+ @classmethod
+ def by_id(cls, db_conn: DatabaseConnection, id_: int) -> Todo:
+ """Get Todo of .id_=id_."""
+ for row in db_conn.exec('SELECT * FROM todos WHERE id = ?', (id_,)):
+ return cls.from_table_row(row, db_conn)
+ raise NotFoundException(f'Todo of ID not found: {id_}')
+
@classmethod
def by_date(cls, db_conn: DatabaseConnection, date: str) -> list[Todo]:
"""Collect all Todos for Day of date."""
diff --git a/scripts/init.sql b/scripts/init.sql
index 1245030..6dca372 100644
--- a/scripts/init.sql
+++ b/scripts/init.sql
@@ -35,3 +35,11 @@ CREATE TABLE process_titles (
CREATE TABLE processes (
id INTEGER PRIMARY KEY
);
+CREATE TABLE todos (
+ id INTEGER PRIMARY KEY,
+ process_id INTEGER NOT NULL,
+ is_done BOOLEAN NOT NULL,
+ day TEXT NOT NULL,
+ FOREIGN KEY (process_id) REFERENCES processes(id),
+ FOREIGN KEY (day) REFERENCES days(date)
+);
diff --git a/templates/day.html b/templates/day.html
index 7a34e58..44fd90d 100644
--- a/templates/day.html
+++ b/templates/day.html
@@ -7,7 +7,18 @@
+
{% endblock %}
diff --git a/tests/todos.py b/tests/todos.py
index 93b34d1..8bcd181 100644
--- a/tests/todos.py
+++ b/tests/todos.py
@@ -9,20 +9,36 @@ from plomtask.exceptions import NotFoundException
class TestsWithDB(TestCaseWithDB):
"""Tests not requiring DB setup."""
- def test_Todo_by_date(self) -> None:
+ def test_Todo_by_id(self) -> None:
"""Test creation and findability of Todos."""
+ day = Day('2024-01-01')
+ process = Process(None)
+ todo = Todo(None, process, False, day)
+ with self.assertRaises(NotFoundException):
+ todo.save(self.db_conn)
+ process.save_without_steps(self.db_conn)
+ todo.save(self.db_conn)
+ with self.assertRaises(NotFoundException):
+ _ = Todo.by_id(self.db_conn, 1)
+ day.save(self.db_conn)
+ self.assertEqual(Todo.by_id(self.db_conn, 1), todo)
+ with self.assertRaises(NotFoundException):
+ self.assertEqual(Todo.by_id(self.db_conn, 0), todo)
+ with self.assertRaises(NotFoundException):
+ self.assertEqual(Todo.by_id(self.db_conn, 2), todo)
+
+ def test_Todo_by_date(self) -> None:
+ """Test findability of Todos by date."""
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)
+ process = Process(None)
+ process.save_without_steps(self.db_conn)
+ todo1 = Todo(None, process, False, day1)
todo1.save(self.db_conn)
- todo2 = Todo(None, process1, False, day1)
+ todo2 = Todo(None, process, False, day1)
todo2.save(self.db_conn)
with self.assertRaises(NotFoundException):
- Todo.by_date(self.db_conn, day1.date),
+ _ = 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])
@@ -58,3 +74,15 @@ class TestsWithServer(TestCaseWithServer):
self.assertEqual(todo1.id_, 2)
self.assertEqual(todo1.process.id_, process2.id_)
self.assertEqual(todo1.is_done, False)
+
+ def test_do_GET_todo(self) -> None:
+ """Test GET /todo response codes."""
+ form_data = {'title': '', 'description': '', 'effort': 1}
+ self.check_post(form_data, '/process?id=', 302, '/')
+ form_data = {'comment': '', 'new_todo': 1}
+ self.check_post(form_data, '/day?date=2024-01-01', 302, '/')
+ self.check_get('/todo', 404)
+ self.check_get('/todo?id=', 404)
+ self.check_get('/todo?id=foo', 400)
+ self.check_get('/todo?id=0', 404)
+ self.check_get('/todo?id=1', 200)