Fix overdue detection ignoring due_time, harden SW precache installs

Task.is_overdue only compared due_date to today, so a task due at 9am
stayed "not overdue" until midnight regardless of due_time (Gitea #7).
Now factors in due_time when the due date is today, mirrored in the
offline app's isTaskOverdue().

Also hardened the service worker's install step: cache.addAll() lets
the browser's HTTP cache satisfy each precache fetch, and since static
assets here send no Cache-Control/ETag (just Last-Modified), a
CACHE_NAME bump wasn't reliably guaranteed to pick up fresh files.
Forcing {cache: 'reload'} on each precache fetch fixes that.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2026-09-05 09:29:37 -06:00
co-authored by Claude Sonnet 5
parent c454423d4d
commit d67a7e4d8f
4 changed files with 78 additions and 8 deletions
+49 -1
View File
@@ -1,7 +1,9 @@
from datetime import date
from datetime import date, datetime, time as dt_time
from unittest.mock import patch
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.utils import timezone as django_timezone
from tasks.models import Task
@@ -85,3 +87,49 @@ class CustomRecurrenceTests(TestCase):
parsed = task.parsed_custom_recurrence
self.assertIsNone(parsed['freq'])
self.assertEqual(parsed['byweekday'], [])
class IsOverdueTests(TestCase):
"""Tests for Task.is_overdue, which must account for due_time, not just due_date (Gitea #7)."""
def setUp(self):
self.user = User.objects.create_user(
username='overdueuser',
email='overdueuser@example.com',
password='testpass123',
)
def make_task(self, **kwargs):
defaults = {'user': self.user, 'title': 'Test task', 'status': 'pending'}
defaults.update(kwargs)
return Task.objects.create(**defaults)
@patch('django.utils.timezone.now')
def test_not_overdue_before_due_time_same_day(self, mock_now):
mock_now.return_value = django_timezone.make_aware(datetime(2026, 1, 15, 8, 0, 0))
task = self.make_task(due_date=date(2026, 1, 15), due_time=dt_time(17, 0, 0))
self.assertFalse(task.is_overdue)
@patch('django.utils.timezone.now')
def test_overdue_after_due_time_same_day(self, mock_now):
mock_now.return_value = django_timezone.make_aware(datetime(2026, 1, 15, 18, 0, 0))
task = self.make_task(due_date=date(2026, 1, 15), due_time=dt_time(17, 0, 0))
self.assertTrue(task.is_overdue)
@patch('django.utils.timezone.now')
def test_not_overdue_same_day_without_due_time(self, mock_now):
mock_now.return_value = django_timezone.make_aware(datetime(2026, 1, 15, 23, 59, 0))
task = self.make_task(due_date=date(2026, 1, 15), due_time=None)
self.assertFalse(task.is_overdue)
@patch('django.utils.timezone.now')
def test_overdue_once_date_has_passed(self, mock_now):
mock_now.return_value = django_timezone.make_aware(datetime(2026, 1, 16, 0, 1, 0))
task = self.make_task(due_date=date(2026, 1, 15), due_time=dt_time(23, 0, 0))
self.assertTrue(task.is_overdue)
@patch('django.utils.timezone.now')
def test_completed_task_never_overdue(self, mock_now):
mock_now.return_value = django_timezone.make_aware(datetime(2026, 1, 15, 23, 0, 0))
task = self.make_task(due_date=date(2026, 1, 1), due_time=dt_time(9, 0, 0), status='completed')
self.assertFalse(task.is_overdue)