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/announcements/announcements_screen.dart'; import 'package:metatron_student_erp/models/announcement.dart'; import 'package:metatron_student_erp/providers/announcement_provider.dart'; import 'package:metatron_student_erp/repositories/announcement_repository.dart'; void main() { final sampleAnnouncements = [ const AnnouncementItem( id: 201, title: 'Fee Payment Deadline', name: 'Fee Payment Deadline', date: '2026-10-15', datePublished: '2026-10-15', expiryDate: '2026-11-15', summary: 'Please ensure semester fees are paid before deadline.', content: '

Please ensure semester fees are paid before deadline.

', type: 'circular', priority: '2', author: 'Finance Office', hasAttachment: true, circularFilename: 'fee_notice.pdf', ), const AnnouncementItem( id: 202, title: 'Sports Day 2026', name: 'Sports Day 2026', date: '2026-10-18', datePublished: '2026-10-18', summary: 'Annual athletics and sports events registrations.', content: '

Annual athletics and sports events registrations.

', type: 'event', priority: '1', author: 'Sports Committee', hasAttachment: false, ), ]; Widget buildTestableScreen(List overrides) { return ProviderScope( overrides: overrides, child: const MaterialApp( home: AnnouncementsScreen(), ), ); } testWidgets('AnnouncementsScreen renders loading state initially', (tester) async { await tester.pumpWidget( buildTestableScreen([ announcementsProvider.overrideWith((ref) => Future.delayed( const Duration(seconds: 1), () => const AnnouncementPageResult( announcements: [], totalCount: 0, page: 1, limit: 20, ), )), ]), ); expect(find.byType(CircularProgressIndicator), findsOneWidget); await tester.pumpAndSettle(); }); testWidgets('AnnouncementsScreen renders empty state when no notices exist', (tester) async { await tester.pumpWidget( buildTestableScreen([ announcementsProvider.overrideWith((ref) => Future.value( const AnnouncementPageResult( announcements: [], totalCount: 0, page: 1, limit: 20, ), )), ]), ); await tester.pumpAndSettle(); expect(find.text('No announcements found'), findsOneWidget); }); testWidgets('AnnouncementsScreen renders filter chips and notice cards with priority badges', (tester) async { await tester.pumpWidget( buildTestableScreen([ announcementsProvider.overrideWith((ref) => Future.value( AnnouncementPageResult( announcements: sampleAnnouncements, totalCount: 2, page: 1, limit: 20, ), )), ]), ); await tester.pumpAndSettle(); // Verify filter chips expect(find.text('All'), findsOneWidget); expect(find.text('Notices'), findsOneWidget); expect(find.text('Circulars'), findsOneWidget); expect(find.text('Events'), findsOneWidget); // Verify card titles and badges expect(find.text('Fee Payment Deadline'), findsOneWidget); expect(find.text('Urgent'), findsOneWidget); expect(find.text('Circular'), findsOneWidget); expect(find.text('Sports Day 2026'), findsOneWidget); expect(find.text('Important'), findsOneWidget); expect(find.text('Event'), findsOneWidget); expect(find.text('fee_notice.pdf'), findsOneWidget); }); testWidgets('AnnouncementsScreen opens detail bottom sheet when card is tapped', (tester) async { await tester.pumpWidget( buildTestableScreen([ announcementsProvider.overrideWith((ref) => Future.value( AnnouncementPageResult( announcements: sampleAnnouncements, totalCount: 2, page: 1, limit: 20, ), )), ]), ); await tester.pumpAndSettle(); // Tap the first card await tester.tap(find.text('Fee Payment Deadline')); await tester.pumpAndSettle(); // Check detail sheet elements expect(find.text('Details'), findsOneWidget); expect(find.text('Posted by: Finance Office'), findsOneWidget); expect(find.text('Expires on: 2026-11-15'), findsOneWidget); expect(find.text('Close'), findsOneWidget); // Close the sheet await tester.tap(find.text('Close')); await tester.pumpAndSettle(); expect(find.text('Details'), findsNothing); }); testWidgets('AnnouncementsScreen renders error state and retry button on failure', (tester) async { await tester.pumpWidget( buildTestableScreen([ announcementsProvider.overrideWith((ref) => Future.error('Connection timeout')), ]), ); await tester.pumpAndSettle(); expect(find.text('Failed to load announcements'), findsOneWidget); expect(find.text('Retry'), findsOneWidget); }); }