Skip to content

Commit 38bb0eb

Browse files
committed
test: that higher priority tasks are rescheduled first
1 parent 78d469e commit 38bb0eb

File tree

1 file changed

+78
-3
lines changed

1 file changed

+78
-3
lines changed

tests/rescheduler_test.py

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@
1414
from postpwn.cli import RescheduleParams, postpwn
1515

1616
# TODO: Tests to make:
17-
# Easy - Rules with a weight > max weight should return an error
18-
# Medium - With rules, tasks that have higher priority should be rescheduled first, according to knapsack algorithm
1917
# Medium/Hard - Application should retry on failure
2018
# Hard - Passing in a valid cron string triggers rescheduling on that cron schedule and doesn't raise an error
2119
# Hard - Test this as part of an E2E test? - When time zone is specified, tasks should be rescheduled properly according to that time zone
2220

23-
# TODO: How to treat items with overlapping labels?
21+
# TODO: How to treat items with overlapping labels? - Check for them, and then
22+
# only reschedule according to the first rule that matches
2423

2524

2625
logging.basicConfig(stream=sys.stderr, level=logging.WARNING)
@@ -305,6 +304,82 @@ def test_reschedule_with_rules(event_loop: AbstractEventLoop) -> None:
305304
)
306305

307306

307+
def test_reschedule_with_priority(event_loop: AbstractEventLoop) -> None:
308+
"""when tasks have different priorities, it prioritizes the higher priority tasks first for rescheduling"""
309+
310+
kwargs: RescheduleParams = {
311+
"token": "VALID_TOKEN",
312+
"filter": "label:test",
313+
"rules": "tests/fixtures/single_max_weight_rules.json",
314+
"dry_run": False,
315+
"time_zone": "UTC",
316+
"schedule": None,
317+
}
318+
319+
fake_api = FakeTodoistAPI("VALID_TOKEN")
320+
321+
high_priority_task = build_task({"labels": ["weight_two"], "priority": 4})
322+
tasks = [
323+
*[build_task({"labels": ["weight_one"]}) for _ in range(2)],
324+
build_task({"labels": ["weight_two"]}, is_datetime=True),
325+
high_priority_task,
326+
]
327+
328+
fake_api.setup_tasks(tasks)
329+
330+
curr_datetime = datetime(2025, 1, 5, 0, 0, 0)
331+
332+
with set_env({"RETRY_ATTEMPTS": "1"}):
333+
postpwn(fake_api, event_loop, curr_datetime, **kwargs)
334+
335+
assert fake_api.update_task.call_count == 4
336+
337+
# Group tasks by due_datetime
338+
calls = fake_api.update_task.call_args_list
339+
scheduled_dates: dict[datetime, list[str]] = defaultdict(list)
340+
341+
for call in calls:
342+
task_id = call.args[0]
343+
due_datetime = (
344+
call.kwargs["due_datetime"]
345+
if "due_datetime" in call.kwargs
346+
else datetime.combine(call.kwargs["due_date"], datetime.min.time())
347+
)
348+
349+
matching_task = next(t for t in tasks if t.id == task_id)
350+
task_label = (
351+
next(label for label in matching_task.labels)
352+
if matching_task.labels
353+
else None
354+
)
355+
356+
if task_label:
357+
scheduled_dates[due_datetime].append(task_label)
358+
359+
# TODO: Assert that the high priority task is the one rescheduled to the current day
360+
361+
# Current day (Jan 5)
362+
assert curr_datetime in scheduled_dates
363+
assert scheduled_dates[curr_datetime].count("weight_one") == 0
364+
assert scheduled_dates[curr_datetime].count("weight_two") == 1
365+
366+
# Next day (Jan 6)
367+
second_day = curr_datetime + timedelta(days=1)
368+
assert second_day in scheduled_dates
369+
assert (
370+
scheduled_dates[second_day].count("weight_one") == 2
371+
and scheduled_dates[second_day].count("weight_two") == 0
372+
)
373+
374+
# Day after next (Jan 7)
375+
third_day = curr_datetime + timedelta(days=2)
376+
assert third_day in scheduled_dates
377+
assert (
378+
scheduled_dates[third_day].count("weight_one") == 0
379+
and scheduled_dates[third_day].count("weight_two") == 1
380+
)
381+
382+
308383
def test_reschedule_with_rules_and_daily_weight(event_loop: AbstractEventLoop):
309384
"""when rules with a daily max weight are provided, it reschedules tasks using smart rescheduling, respecting the daily max weight"""
310385

0 commit comments

Comments
 (0)