import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:metatron_student_erp/features/timetable/timetable_screen.dart'; import 'package:metatron_student_erp/models/student.dart'; import 'package:metatron_student_erp/models/timetable.dart'; import 'package:metatron_student_erp/providers/timetable_provider.dart'; void main() { final sampleSlots = [ const TimetableSlot( id: 101, date: '2026-10-13', day: 'Tuesday', startTime: '09:00 AM', endTime: '10:30 AM', subject: NamedRecord(id: 4, name: 'Database Systems'), faculty: NamedRecord(id: 6, name: 'Dr. Turing'), room: NamedRecord(id: 1, name: 'Lecture Hall 101'), ), const TimetableSlot( id: 102, date: '2026-10-13', day: 'Tuesday', startTime: '11:00 AM', endTime: '12:30 PM', subject: NamedRecord(id: 5, name: 'Operating Systems'), faculty: NamedRecord(id: 6, name: 'Dr. Turing'), room: NamedRecord(id: 2, name: 'Lecture Hall 102'), ), ]; Widget buildTestableScreen(List overrides) { return ProviderScope( overrides: overrides, child: const MaterialApp( home: TimetableScreen(), ), ); } testWidgets('TimetableScreen renders loading state initially', (tester) async { await tester.pumpWidget( buildTestableScreen([ timetableProvider.overrideWith((ref) => Future.delayed( const Duration(seconds: 1), () => sampleSlots, )), ]), ); expect(find.byType(CircularProgressIndicator), findsOneWidget); await tester.pumpAndSettle(); }); testWidgets('TimetableScreen renders empty state when no slots exist', (tester) async { await tester.pumpWidget( buildTestableScreen([ timetableProvider.overrideWith((ref) => Future.value([])), ]), ); await tester.pumpAndSettle(); expect(find.text('Weekly Timetable'), findsOneWidget); expect(find.text('No timetable slots scheduled'), findsOneWidget); expect(find.text('Your class schedule has not been published yet.'), findsOneWidget); }); testWidgets('TimetableScreen renders slot cards and day groups with live data', (tester) async { await tester.pumpWidget( buildTestableScreen([ timetableProvider.overrideWith((ref) => Future.value(sampleSlots)), ]), ); await tester.pumpAndSettle(); expect(find.text('Weekly Timetable'), findsOneWidget); expect(find.text('TUESDAY'), findsOneWidget); expect(find.text('Database Systems'), findsOneWidget); expect(find.text('Lecture Hall 101'), findsOneWidget); expect(find.text('Operating Systems'), findsOneWidget); expect(find.text('Lecture Hall 102'), findsOneWidget); expect(find.text('09:00 AM'), findsOneWidget); expect(find.text('10:30 AM'), findsOneWidget); expect(find.text('11:00 AM'), findsOneWidget); expect(find.text('12:30 PM'), findsOneWidget); }); testWidgets('TimetableScreen renders error state and retry button on failure', (tester) async { await tester.pumpWidget( buildTestableScreen([ timetableProvider.overrideWith((ref) => Future.error(Exception('Network timeout'))), ]), ); await tester.pumpAndSettle(); expect(find.text('Failed to load timetable'), findsOneWidget); expect(find.text('Retry'), findsOneWidget); expect(find.byIcon(Icons.error_outline_rounded), findsOneWidget); }); }