NotFoundException
from plomtask.db import DatabaseConnection, DatabaseFile
from plomtask.processes import Process
+from plomtask.todos import Todo
TEMPLATES_DIR = 'templates'
"""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')
"""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:
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:
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."""
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)
+);
</p>
<form action="day?date={{day.date}}" method="POST">
comment: <input name="comment" value="{{day.comment|e}}" />
-<input type="submit" value="OK" />
+<input type="submit" value="OK" /><br />
+add todo: <input name="new_todo" list="processes" autocomplete="off" />
+<datalist id="processes">
+{% for process in processes %}
+<option value="{{process.id_}}">{{process.title.newest|e}}</option>
+{% endfor %}
+</datalist>
</form>
+<ul>
+{% for todo in todos %}
+<li><a href="todo?id={{todo.id_}}">{{todo.process.title.newest|e}}</a>
+{% endfor %}
+</ul>
{% endblock %}
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])
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)