import datetime from unittest.mock import patch from django.test import TestCase from django.contrib.auth import get_user_model from modules.task_management.tasks import notify_upcoming_tasks from modules.task_management.models import Task from modules.fleet.models import Vehicle, WorkOrder class NotifyUpcomingTasksTests(TestCase): def setUp(self): User = get_user_model() self.user = User.objects.create_user( username="serviser-notif", email="serviser@example.test", password="pass", ) self.vehicle = Vehicle.objects.create( registration_number="ZG-NOTIF-01", asset_type='crane', ) @patch('modules.fleet.services.NotificationService.create_notification') def test_notifies_for_task_scheduled_tomorrow(self, mock_notify): tomorrow = datetime.date.today() + datetime.timedelta(days=1) Task.objects.create( title="Sutrašnji zadatak", assigned_to=self.user, vehicle=self.vehicle, status='aktivan', scheduled_date=tomorrow, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 1) mock_notify.assert_called_once() call_kwargs = mock_notify.call_args.kwargs self.assertEqual(call_kwargs['recipient'], self.user) self.assertIn('Sutrašnji zadatak', call_kwargs['title']) self.assertEqual(call_kwargs['level'], 'info') self.assertTrue(call_kwargs.get('send_email')) @patch('modules.fleet.services.NotificationService.create_notification') def test_notifies_multiple_upcoming_tasks(self, mock_notify): tomorrow = datetime.date.today() + datetime.timedelta(days=1) Task.objects.create(title="Task A", assigned_to=self.user, vehicle=self.vehicle, status='aktivan', scheduled_date=tomorrow) Task.objects.create(title="Task B", assigned_to=self.user, vehicle=self.vehicle, status='servis', scheduled_date=tomorrow) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 2) self.assertEqual(mock_notify.call_count, 2) @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_task_without_scheduled_date(self, mock_notify): Task.objects.create( title="Bez datuma", assigned_to=self.user, vehicle=self.vehicle, status='aktivan', scheduled_date=None, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_task_scheduled_today(self, mock_notify): today = datetime.date.today() Task.objects.create( title="Danas", assigned_to=self.user, vehicle=self.vehicle, status='aktivan', scheduled_date=today, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_task_scheduled_in_past(self, mock_notify): yesterday = datetime.date.today() - datetime.timedelta(days=1) Task.objects.create( title="Jučer", assigned_to=self.user, vehicle=self.vehicle, status='aktivan', scheduled_date=yesterday, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_finished_task(self, mock_notify): tomorrow = datetime.date.today() + datetime.timedelta(days=1) vehicle2 = Vehicle.objects.create(registration_number="ZG-NOTIF-02", asset_type='crane') work_order = WorkOrder.objects.create( vehicle=vehicle2, creator=self.user, purpose='defektaza', status='closed', start_mileage=100, end_mileage=200, ) Task.objects.create( title="Završeni", assigned_to=self.user, vehicle=vehicle2, status='zavrsen', scheduled_date=tomorrow, work_order=work_order, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_cancelled_task(self, mock_notify): tomorrow = datetime.date.today() + datetime.timedelta(days=1) vehicle3 = Vehicle.objects.create(registration_number="ZG-NOTIF-03", asset_type='crane') work_order = WorkOrder.objects.create( vehicle=vehicle3, creator=self.user, purpose='kontrola', status='closed', start_mileage=50, end_mileage=100, ) Task.objects.create( title="Otkazani", assigned_to=self.user, vehicle=vehicle3, status='neaktivan', scheduled_date=tomorrow, work_order=work_order, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_skips_task_without_assigned_user(self, mock_notify): tomorrow = datetime.date.today() + datetime.timedelta(days=1) Task.objects.create( title="Bez servisera", assigned_to=None, vehicle=self.vehicle, status='aktivan', scheduled_date=tomorrow, ) result = notify_upcoming_tasks() self.assertEqual(result['notified'], 0) mock_notify.assert_not_called() @patch('modules.fleet.services.NotificationService.create_notification') def test_result_includes_date_string(self, mock_notify): result = notify_upcoming_tasks() tomorrow = datetime.date.today() + datetime.timedelta(days=1) self.assertEqual(result['date'], tomorrow.isoformat()) self.assertEqual(result['notified'], 0)