msg = f'cannot int form field value for key {key}: {val}'
raise BadFormatException(msg) from e
- def get_bool_or_none(self, key: str) -> bool | None:
- """Return value to key if truish; if no value to key, None."""
- val = self.get_str(key)
- if val is None:
- return None
- return val in {'True', 'true', '1', 'on'}
+ def get_bool(self, key: str) -> bool:
+ """Return if value to key truish; return False if None/no value."""
+ return self.get_str(key) in {'True', 'true', '1', 'on'}
def get_all_of_key_prefixed(self, key_prefix: str) -> dict[str, list[str]]:
"""Retrieve dict of strings at keys starting with key_prefix."""
for id_ in self._form.get_all_int('make_empty')]}
step_fillers_to = self._form.get_all_of_key_prefixed('step_filler_to_')
to_update: dict[str, Any] = {
- 'comment': self._form.get_str_or_fail('comment', '')}
- for k in ('is_done', 'calendarize'):
- v = self._form.get_bool_or_none(k)
- if v is not None:
- to_update[k] = v
+ 'comment': self._form.get_str_or_fail('comment', ''),
+ 'is_done': self._form.get_bool('is_done'),
+ 'calendarize': self._form.get_bool('calendarize')}
cond_rels = [self._form.get_all_int(name) for name in
['conditions', 'blockers', 'enables', 'disables']]
effort_or_not = self._form.get_str('effort')
'effort': self._form.get_float_or_fail('effort')}
cond_rels = [self._form.get_all_int(s) for s
in ['conditions', 'blockers', 'enables', 'disables']]
- calendarize = self._form.get_bool_or_none('calendarize')
+ calendarize = self._form.get_bool('calendarize')
step_of = self._form.get_all_str('step_of')
suppressions = self._form.get_all_int('suppresses')
kept_steps = self._form.get_all_int('kept_steps')
#
for k, v in versioned.items():
getattr(process, k).set(v)
- if calendarize is not None:
- process.calendarize = calendarize
+ process.calendarize = calendarize
process.save(self._conn)
assert isinstance(process.id_, int)
# set relations to Conditions and ProcessSteps / other Processes
"""Update/insert Condition of ?id= and fields defined in postvars."""
title = self._form.get_str_or_fail('title')
description = self._form.get_str_or_fail('description')
- is_active = self._form.get_bool_or_none('is_active')
+ is_active = self._form.get_bool('is_active')
+ condition.is_active = is_active
#
- if is_active is not None:
- condition.is_active = is_active
condition.title.set(title)
condition.description.set(description)
condition.save(self._conn)
'is_active': 1})
self.check_json_get(url_single, exp_single)
self.check_json_get(url_all, exp_all)
+ # test POST sans 'is_active' setting it negative
+ self.post_exp_cond(all_exps, {'title': 'bar', 'description': 'oof'})
+ self.check_json_get(url_single, exp_single)
+ self.check_json_get(url_all, exp_all)
# test deletion POST's effect, both to return id=1 into empty single,
# full /conditions into empty list
self.post_exp_cond(all_exps, {'delete': ''}, redir_to_id=False)
with self.assertRaises(BadFormatException):
InputsParser({'foo': []}).get_float_or_fail('foo')
- def test_InputsParser_get_bool_or_none(self) -> None:
- """Test InputsParser.get_all_str."""
- parser = InputsParser({})
- self.assertEqual(None, parser.get_bool_or_none('foo'))
- parser = InputsParser({'val': ['foo']})
- self.assertEqual(None, parser.get_bool_or_none('foo'))
- parser = InputsParser({'val': ['True']})
- self.assertEqual(None, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': []})
- self.assertEqual(None, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['None']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['0']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['bar']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['bar', 'baz']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['False']})
- self.assertEqual(False, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['true']})
- self.assertEqual(True, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['True']})
- self.assertEqual(True, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['1']})
- self.assertEqual(True, parser.get_bool_or_none('foo'))
- parser = InputsParser({'foo': ['on']})
- self.assertEqual(True, parser.get_bool_or_none('foo'))
+ def test_InputsParser_get_bool(self) -> None:
+ """Test InputsParser.get_bool."""
+ self.assertEqual(0, InputsParser({}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'val': ['foo']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'val': ['True']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': []}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['None']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['0']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['bar']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['bar',
+ 'baz']}).get_bool('foo'))
+ self.assertEqual(0, InputsParser({'foo': ['False']}).get_bool('foo'))
+ self.assertEqual(1, InputsParser({'foo': ['true']}).get_bool('foo'))
+ self.assertEqual(1, InputsParser({'foo': ['True']}).get_bool('foo'))
+ self.assertEqual(1, InputsParser({'foo': ['1']}).get_bool('foo'))
+ self.assertEqual(1, InputsParser({'foo': ['on']}).get_bool('foo'))
def test_InputsParser_get_all_str(self) -> None:
"""Test InputsParser.get_all_str."""
valid_post = {'title': 'foo', 'description': 'oof', 'effort': 2.3}
self.post_exp_process([exp], valid_post, 1)
self.check_json_get('/process?id=1', exp)
+ # check boolean 'calendarize'
+ self.post_exp_process([exp], valid_post | {'calendarize': True}, 1)
+ self.check_json_get('/process?id=1', exp)
+ self.post_exp_process([exp], valid_post, 1)
+ self.check_json_get('/process?id=1', exp)
# check n_todos field
self.post_exp_day([], {'new_todo': ['1']}, '2024-01-01')
self.post_exp_day([], {'new_todo': ['1']}, '2024-01-02')
from plomtask.todos import Todo, TodoNode
from plomtask.processes import Process, ProcessStep
from plomtask.conditions import Condition
-from plomtask.exceptions import (NotFoundException, BadFormatException,
- HandledException)
+from plomtask.exceptions import BadFormatException, HandledException
class TestsWithDB(TestCaseWithDB, TestCaseSansDB):
self.cond2.save(self.db_conn)
self.default_init_kwargs['process'] = self.proc
- def test_Todo_init(self) -> None:
- """Test creation of Todo and what they default to."""
- process = Process(None)
- with self.assertRaises(NotFoundException):
- Todo(None, process, False, self.date1)
- process.save(self.db_conn)
- assert isinstance(self.cond1.id_, int)
- assert isinstance(self.cond2.id_, int)
- process.set_condition_relations(self.db_conn,
- [self.cond1.id_, self.cond2.id_], [],
- [self.cond1.id_], [self.cond2.id_])
- todo_no_id = Todo(None, process, False, self.date1)
- self.assertEqual(todo_no_id.conditions, [self.cond1, self.cond2])
- self.assertEqual(todo_no_id.enables, [self.cond1])
- self.assertEqual(todo_no_id.disables, [self.cond2])
- todo_yes_id = Todo(5, process, False, self.date1)
- self.assertEqual(todo_yes_id.conditions, [])
- self.assertEqual(todo_yes_id.enables, [])
- self.assertEqual(todo_yes_id.disables, [])
-
def test_Todo_by_date(self) -> None:
"""Test findability of Todos by date."""
t1 = Todo(None, self.proc, False, self.date1)
"""Test .by_date_range_with_limits."""
self.check_by_date_range_with_limits('day')
- def test_Todo_on_conditions(self) -> None:
- """Test effect of Todos on Conditions."""
- assert isinstance(self.cond1.id_, int)
- assert isinstance(self.cond2.id_, int)
- todo = Todo(None, self.proc, False, self.date1)
- todo.save(self.db_conn)
- todo.set_condition_relations(self.db_conn, [], [],
- [self.cond1.id_], [self.cond2.id_])
- todo.is_done = True
- self.assertEqual(self.cond1.is_active, True)
- self.assertEqual(self.cond2.is_active, False)
- todo.is_done = False
- self.assertEqual(self.cond1.is_active, True)
- self.assertEqual(self.cond2.is_active, False)
-
def test_Todo_children(self) -> None:
"""Test Todo.children relations."""
todo_1 = Todo(None, self.proc, False, self.date1)
'comment': 'foo', 'effort': 2.3}
self._post_exp_todo(1, todo_post, exp)
self.check_json_get('/todo?id=1', exp)
- # test implicitly un-setting (only) comment by empty post
- self.check_post({}, '/todo?id=1')
- exp.lib_get('Todo', 1)['comment'] = ''
+ # test implicitly un-setting comment/calendarize/is_done by empty post
+ self._post_exp_todo(1, {}, exp)
self.check_json_get('/todo?id=1', exp)
# test effort post can be explicitly unset by "effort":"" post
self.check_post({'effort': ''}, '/todo?id=1')
return
cond = self.lib_get('Condition', id_)
if cond:
- if 'is_active' in d:
- cond['is_active'] = d['is_active']
+ cond['is_active'] = 'is_active' in d and\
+ d['is_active'] in VALID_TRUES
for category in ['title', 'description']:
history = cond['_versioned'][category]
if len(history) > 0:
def set_todo_from_post(self, id_: int, d: dict[str, Any]) -> None:
"""Set Todo of id_ in library based on POST dict d."""
- corrected_kwargs: dict[str, Any] = {'children': []}
+ corrected_kwargs: dict[str, Any] = {
+ 'children': [], 'is_done': 0, 'calendarize': 0, 'comment': ''}
for k, v in d.items():
if k.startswith('step_filler_to_'):
continue
new_children = v if isinstance(v, list) else [v]
corrected_kwargs['children'] += new_children
continue
- if k in {'is_done', 'calendarize'}:
- v = v in VALID_TRUES
+ if k in {'is_done', 'calendarize'} and v in VALID_TRUES:
+ v = True
corrected_kwargs[k] = v
todo = self.lib_get('Todo', id_)
if todo:
d['title'], d['description'], d['effort'])
ignore = {'title', 'description', 'effort', 'new_top_step', 'step_of',
'kept_steps'}
+ proc['calendarize'] = False
for k, v in d.items():
if k in ignore\
or k.startswith('step_') or k.startswith('new_step_to'):
continue
- if k in {'calendarize'}:
- v = v in VALID_TRUES
+ if k in {'calendarize'} and v in VALID_TRUES:
+ v = True
elif k in {'suppressed_steps', 'explicit_steps', 'conditions',
'disables', 'enables', 'blockers'}:
if not isinstance(v, list):