164 lines
5.2 KiB
Dart
164 lines
5.2 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/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: '<p>Please ensure semester fees are paid before deadline.</p>',
|
|
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: '<p>Annual athletics and sports events registrations.</p>',
|
|
type: 'event',
|
|
priority: '1',
|
|
author: 'Sports Committee',
|
|
hasAttachment: false,
|
|
),
|
|
];
|
|
|
|
Widget buildTestableScreen(List<Override> 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);
|
|
});
|
|
}
|