import 'package:flutter_test/flutter_test.dart'; import 'package:tasq/models/task.dart'; import 'package:tasq/models/task_assignment.dart'; import 'package:tasq/models/notification_item.dart'; import 'package:tasq/utils/app_time.dart'; void main() { setUp(() { AppTime.initialize(); }); group('Task model IT Job fields', () { test('fromMap parses it_job_printed correctly', () { final map = { 'id': 'task-1', 'ticket_id': null, 'task_number': 'T-2026-0001', 'title': 'Fix printer', 'description': 'Printer is broken', 'office_id': 'office-1', 'status': 'completed', 'priority': 1, 'queue_order': null, 'created_at': '2026-03-21T08:00:00.000Z', 'creator_id': 'user-1', 'started_at': '2026-03-21T08:30:00.000Z', 'completed_at': '2026-03-21T10:00:00.000Z', 'it_job_printed': true, 'it_job_printed_at': '2026-03-21T10:30:00.000Z', }; final task = Task.fromMap(map); expect(task.itJobPrinted, true); expect(task.itJobPrintedAt, isNotNull); }); test('fromMap defaults it_job_printed to false', () { final map = { 'id': 'task-2', 'ticket_id': null, 'task_number': 'T-2026-0002', 'title': 'Replace cable', 'description': '', 'office_id': null, 'status': 'queued', 'priority': 1, 'queue_order': null, 'created_at': '2026-03-21T08:00:00.000Z', 'creator_id': 'user-1', 'started_at': null, 'completed_at': null, // it_job_printed fields not present }; final task = Task.fromMap(map); expect(task.itJobPrinted, false); expect(task.itJobPrintedAt, isNull); }); test('equality includes it_job_printed fields', () { final base = { 'id': 'task-3', 'ticket_id': null, 'task_number': null, 'title': 'Test', 'description': '', 'office_id': null, 'status': 'completed', 'priority': 1, 'queue_order': null, 'created_at': '2026-03-21T08:00:00.000Z', 'creator_id': null, 'started_at': null, 'completed_at': null, 'it_job_printed': false, 'it_job_printed_at': null, }; final t1 = Task.fromMap(base); final t2 = Task.fromMap({...base, 'it_job_printed': true}); expect(t1, isNot(equals(t2))); }); }); group('IT staff checklist filtering', () { Task makeTask(String id, {bool completed = true, bool printed = false}) { return Task.fromMap({ 'id': id, 'ticket_id': null, 'task_number': 'T-2026-000${id.hashCode % 9}', 'title': 'Task $id', 'description': '', 'office_id': null, 'status': completed ? 'completed' : 'in_progress', 'priority': 1, 'queue_order': null, 'created_at': '2026-04-01T08:00:00.000Z', 'creator_id': 'user-0', 'started_at': null, 'completed_at': completed ? '2026-04-01T09:00:00.000Z' : null, 'it_job_printed': printed, 'it_job_printed_at': null, }); } TaskAssignment makeAssign(String taskId, String userId) => TaskAssignment( taskId: taskId, userId: userId, createdAt: DateTime(2026, 4, 1), ); test('IT staff sees only their assigned completed tasks', () { final tasks = [ makeTask('t1'), // assigned to it_staff_1 makeTask('t2'), // assigned to it_staff_2 makeTask('t3'), // assigned to both makeTask('t4', completed: false), // not completed — excluded ]; final assignments = [ makeAssign('t1', 'it_staff_1'), makeAssign('t2', 'it_staff_2'), makeAssign('t3', 'it_staff_1'), makeAssign('t3', 'it_staff_2'), makeAssign('t4', 'it_staff_1'), ]; const currentUserId = 'it_staff_1'; final myCompleted = tasks .where((t) => t.status == 'completed') .where((t) => assignments .any((a) => a.taskId == t.id && a.userId == currentUserId)) .toList(); expect(myCompleted.map((t) => t.id), containsAll(['t1', 't3'])); expect(myCompleted.map((t) => t.id), isNot(contains('t2'))); expect(myCompleted.map((t) => t.id), isNot(contains('t4'))); }); test('IT staff not_submitted filter excludes already-printed tasks', () { final tasks = [ makeTask('t1', printed: false), makeTask('t2', printed: true), ]; final assignments = [ makeAssign('t1', 'it_staff_1'), makeAssign('t2', 'it_staff_1'), ]; const currentUserId = 'it_staff_1'; final myPending = tasks .where((t) => t.status == 'completed') .where((t) => assignments .any((a) => a.taskId == t.id && a.userId == currentUserId)) .where((t) => !t.itJobPrinted) .toList(); expect(myPending.map((t) => t.id), equals(['t1'])); }); }); group('NotificationItem announcement field', () { test('fromMap parses announcement_id', () { final map = { 'id': 'notif-1', 'user_id': 'user-1', 'actor_id': 'user-2', 'ticket_id': null, 'task_id': null, 'it_service_request_id': null, 'announcement_id': 'ann-1', 'message_id': null, 'type': 'announcement', 'created_at': '2026-03-21T10:00:00.000Z', 'read_at': null, }; final item = NotificationItem.fromMap(map); expect(item.announcementId, 'ann-1'); expect(item.type, 'announcement'); expect(item.isUnread, true); }); test('fromMap defaults announcement_id to null', () { final map = { 'id': 'notif-2', 'user_id': 'user-1', 'actor_id': null, 'ticket_id': null, 'task_id': 'task-1', 'it_service_request_id': null, 'message_id': null, 'type': 'it_job_reminder', 'created_at': '2026-03-21T10:00:00.000Z', 'read_at': '2026-03-21T10:05:00.000Z', }; final item = NotificationItem.fromMap(map); expect(item.announcementId, isNull); expect(item.type, 'it_job_reminder'); expect(item.isUnread, false); }); }); }