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/%7B%7B%20web_path%20%7D%7D/%7B%7Bprefix%7D%7D/add_structured?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 @@

comment: - +
+add todo: + +{% for process in processes %} + +{% endfor %} +
+ {% 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)