Metatron_Student_ERP/flutter_app/test/timetable_widget_test.dart

102 lines
3.5 KiB
Dart

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<Override> 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);
});
}