205 lines
7.5 KiB
Dart
205 lines
7.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:metatron_student_erp/features/profile/profile_screen.dart';
|
|
import 'package:metatron_student_erp/models/student.dart';
|
|
import 'package:metatron_student_erp/providers/dashboard_provider.dart';
|
|
import 'package:metatron_student_erp/providers/student_provider.dart';
|
|
|
|
void main() {
|
|
const dummyProfile = StudentProfile(
|
|
id: 4,
|
|
studentId: 'STU-9999',
|
|
admissionNumber: 'ADM-9999',
|
|
registrationNumber: 'REG-001',
|
|
rollNumber: 'ROLL-01',
|
|
fullName: 'Demo Student',
|
|
email: 'demo.student@test.edu',
|
|
mobile: '+919876543210',
|
|
gender: 'male',
|
|
dateOfBirth: '2004-01-01',
|
|
bloodGroup: 'o+',
|
|
emergencyContact: 'Jane Doe',
|
|
emergencyPhone: '+919876543219',
|
|
city: 'Chennai',
|
|
street: '123 College Road',
|
|
zip: '600001',
|
|
status: 'active',
|
|
profileCompletion: 75,
|
|
hasPhoto: false,
|
|
campus: NamedRecord(id: 11, name: 'Test Campus'),
|
|
department: NamedRecord(id: 11, name: 'Computer Science'),
|
|
program: NamedRecord(id: 11, name: 'B.Tech CS'),
|
|
);
|
|
|
|
const dummyDoc = StudentDocument(
|
|
id: 1,
|
|
name: '10th Marksheet',
|
|
category: 'academic',
|
|
categoryLabel: 'Academic Certificate / Marksheet',
|
|
fileName: 'marksheet.pdf',
|
|
fileSize: 1024,
|
|
verificationStatus: 'verified',
|
|
uploadDate: '2026-10-10',
|
|
);
|
|
|
|
const dummyCert = StudentCertificate(
|
|
id: 1,
|
|
name: 'CERT/2026/00001',
|
|
certificateType: 'bonafide',
|
|
certificateTypeLabel: 'Bonafide Certificate',
|
|
state: 'issued',
|
|
requestDate: '2026-10-10',
|
|
issueDate: '2026-10-11',
|
|
remarks: 'Passport requirement',
|
|
hasFile: true,
|
|
);
|
|
|
|
Widget buildTestableScreen([List<Override>? overrides]) {
|
|
return ProviderScope(
|
|
overrides: overrides ??
|
|
[
|
|
studentProfileProvider.overrideWith((ref) async => dummyProfile),
|
|
studentDocumentsProvider.overrideWith((ref) async => [dummyDoc]),
|
|
studentCertificatesProvider.overrideWith((ref) async => [dummyCert]),
|
|
],
|
|
child: const MaterialApp(
|
|
home: ProfileScreen(),
|
|
),
|
|
);
|
|
}
|
|
|
|
group('ProfileScreen Widget Tests', () {
|
|
testWidgets('renders all 3 tabs: Profile, Documents, Certificates', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen());
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Profile'), findsOneWidget);
|
|
expect(find.text('Documents'), findsOneWidget);
|
|
expect(find.text('Certificates'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('renders profile academic and contact cards on Profile tab', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen());
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Demo Student'), findsOneWidget);
|
|
expect(find.text('ID: STU-9999'), findsOneWidget);
|
|
expect(find.text('75%'), findsOneWidget);
|
|
expect(find.text('Academic Details (Institutional)'), findsOneWidget);
|
|
expect(find.text('ADM-9999'), findsOneWidget);
|
|
expect(find.text('B.Tech CS'), findsOneWidget);
|
|
await tester.drag(find.byType(ListView).first, const Offset(0, -350));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Contact & Emergency'), findsOneWidget);
|
|
expect(find.text('demo.student@test.edu'), findsOneWidget);
|
|
expect(find.text('+919876543210'), findsOneWidget);
|
|
expect(find.text('Jane Doe'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('tapping Edit Contact Info opens edit dialog with pre-filled fields', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen());
|
|
await tester.pumpAndSettle();
|
|
|
|
final editButton = find.text('Edit Contact Info');
|
|
expect(editButton, findsOneWidget);
|
|
|
|
await tester.tap(editButton);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Edit Contact Info'), findsNWidgets(2)); // dialog title + button
|
|
expect(find.text('Save Changes'), findsOneWidget);
|
|
expect(find.text('Cancel'), findsOneWidget);
|
|
|
|
// Dismiss dialog
|
|
await tester.tap(find.text('Cancel'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Save Changes'), findsNothing);
|
|
});
|
|
|
|
testWidgets('Documents tab renders documents list and verification badge', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen());
|
|
await tester.pumpAndSettle();
|
|
|
|
// Switch to Documents tab
|
|
await tester.tap(find.text('Documents'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('10th Marksheet'), findsOneWidget);
|
|
expect(find.text('VERIFIED'), findsOneWidget);
|
|
expect(find.text('Academic Certificate / Marksheet'), findsOneWidget);
|
|
expect(find.text('Upload Document'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Documents tab renders empty state when list is empty', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen([
|
|
studentProfileProvider.overrideWith((ref) async => dummyProfile),
|
|
studentDocumentsProvider.overrideWith((ref) async => []),
|
|
studentCertificatesProvider.overrideWith((ref) async => [dummyCert]),
|
|
]));
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.tap(find.text('Documents'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('No documents uploaded yet'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Certificates tab renders certificates list and state badge', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen());
|
|
await tester.pumpAndSettle();
|
|
|
|
// Switch to Certificates tab
|
|
await tester.tap(find.text('Certificates'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Bonafide Certificate'), findsOneWidget);
|
|
expect(find.text('ISSUED'), findsOneWidget);
|
|
expect(find.text('Cert No: CERT/2026/00001'), findsOneWidget);
|
|
expect(find.text('Request Certificate'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Certificates tab renders empty state when list is empty', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen([
|
|
studentProfileProvider.overrideWith((ref) async => dummyProfile),
|
|
studentDocumentsProvider.overrideWith((ref) async => [dummyDoc]),
|
|
studentCertificatesProvider.overrideWith((ref) async => []),
|
|
]));
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.tap(find.text('Certificates'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('No certificates requested yet'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('renders loading state initially', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen([
|
|
studentProfileProvider.overrideWith(
|
|
(ref) => Future.delayed(const Duration(seconds: 2), () => dummyProfile),
|
|
),
|
|
studentDocumentsProvider.overrideWith((ref) async => [dummyDoc]),
|
|
studentCertificatesProvider.overrideWith((ref) async => [dummyCert]),
|
|
]));
|
|
|
|
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
|
await tester.pumpAndSettle();
|
|
});
|
|
|
|
testWidgets('renders error and retry button on profile failure', (tester) async {
|
|
await tester.pumpWidget(buildTestableScreen([
|
|
studentProfileProvider.overrideWith(
|
|
(ref) => Future.error('Network failure'),
|
|
),
|
|
studentDocumentsProvider.overrideWith((ref) async => [dummyDoc]),
|
|
studentCertificatesProvider.overrideWith((ref) async => [dummyCert]),
|
|
]));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Failed to load profile details'), findsOneWidget);
|
|
expect(find.text('Retry'), findsOneWidget);
|
|
});
|
|
});
|
|
}
|