import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hidalyx_drluiscastro/features/patient/data/models/patient_model.dart'; import 'package:hidalyx_drluiscastro/features/patient/data/services/patient_service.dart'; import 'package:hidalyx_drluiscastro/features/patient/presentation/store/patient_store.dart'; import 'package:hidalyx_drluiscastro/features/patient/presentation/views/patient_modal_view.dart'; class MockPatientServiceForDelete extends PatientService { int? deletedPatientId; bool shouldFail = false; @override Future deletePatient(int id) async { if (shouldFail) { throw Exception('Error simulado al eliminar paciente'); } deletedPatientId = id; } } void main() { group('Patient Deletion Unit & Store Tests', () { test('PatientStore.deletePatient deletes patient and updates state', () async { final mockService = MockPatientServiceForDelete(); final store = PatientStore(patientService: mockService); // Attempt to delete with null id final nullResult = await store.deletePatient(); expect(nullResult, isFalse); expect(store.errorMessage, contains('No se puede eliminar un paciente que no ha sido guardado')); // Populate patient store.populateFromModel(const PatientModel( id: 777, nombre: 'CARLOS', apellido: 'MARTINEZ', )); expect(store.id, 777); // Execute deletion final success = await store.deletePatient(); expect(success, isTrue); expect(mockService.deletedPatientId, 777); expect(store.isDeleting, isFalse); expect(store.successMessage, 'Paciente eliminado exitosamente'); expect(store.errorMessage, isNull); }); test('PatientStore.deletePatient handles service errors gracefully', () async { final mockService = MockPatientServiceForDelete()..shouldFail = true; final store = PatientStore(patientService: mockService); store.populateFromModel(const PatientModel( id: 888, nombre: 'LUCIA', apellido: 'MENDEZ', )); final success = await store.deletePatient(); expect(success, isFalse); expect(store.isDeleting, isFalse); expect(store.errorMessage, contains('Error simulado al eliminar paciente')); }); }); group('Patient Deletion UI & Role Tests', () { testWidgets('Doctor sees "Eliminar" button when editing an existing patient', (tester) async { tester.view.physicalSize = const Size(1400, 1000); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); const patient = PatientModel( id: 555, nombre: 'JUAN', apellido: 'PEREZ', cedula: '001-9999999-1', ); await tester.pumpWidget( const MaterialApp( home: Scaffold( body: PatientModalView( initialPatient: patient, isSecretary: false, ), ), ), ); await tester.pumpAndSettle(); expect(find.text('Eliminar'), findsOneWidget); }); testWidgets('Doctor does NOT see "Eliminar" button when creating a new patient', (tester) async { tester.view.physicalSize = const Size(1400, 1000); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); await tester.pumpWidget( const MaterialApp( home: Scaffold( body: PatientModalView( isSecretary: false, ), ), ), ); await tester.pumpAndSettle(); expect(find.text('Eliminar'), findsNothing); }); testWidgets('Secretary NEVER sees "Eliminar" button even when editing an existing patient', (tester) async { tester.view.physicalSize = const Size(1400, 1000); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); const patient = PatientModel( id: 555, nombre: 'JUAN', apellido: 'PEREZ', ); await tester.pumpWidget( const MaterialApp( home: Scaffold( body: PatientModalView( initialPatient: patient, isSecretary: true, ), ), ), ); await tester.pumpAndSettle(); expect(find.text('Eliminar'), findsNothing); }); testWidgets('Clicking "Eliminar" opens confirmation dialog, Cancel does not delete', (tester) async { tester.view.physicalSize = const Size(1400, 1000); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); final mockService = MockPatientServiceForDelete(); final store = PatientStore(patientService: mockService); store.populateFromModel(const PatientModel( id: 123, nombre: 'ROBERTO', apellido: 'GARCIA', cedula: '402-1234567-8', )); await tester.pumpWidget( MaterialApp( home: Scaffold( body: PatientModalView( store: store, isSecretary: false, ), ), ), ); await tester.pumpAndSettle(); // Click Eliminar button await tester.tap(find.text('Eliminar')); await tester.pumpAndSettle(); // Verify confirmation dialog expect(find.text('¿Eliminar Ficha del Paciente?'), findsOneWidget); expect(find.text('ROBERTO GARCIA'), findsOneWidget); expect(find.textContaining('#123'), findsOneWidget); expect(find.textContaining('Esta acción es permanente e irreversible'), findsOneWidget); // Click Cancelar await tester.tap(find.text('Cancelar')); await tester.pumpAndSettle(); // Dialog dismissed, patient NOT deleted expect(find.text('¿Eliminar Ficha del Paciente?'), findsNothing); expect(mockService.deletedPatientId, isNull); }); testWidgets('Confirming deletion invokes service, calls onDeleted, and closes modal', (tester) async { tester.view.physicalSize = const Size(1400, 1000); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); final mockService = MockPatientServiceForDelete(); final store = PatientStore(patientService: mockService); store.populateFromModel(const PatientModel( id: 999, nombre: 'ALBERTO', apellido: 'MOREL', )); int? deletedIdReceived; await tester.pumpWidget( MaterialApp( home: Scaffold( body: Builder( builder: (ctx) => ElevatedButton( onPressed: () => showDialog( context: ctx, builder: (_) => PatientModalView( store: store, isSecretary: false, onDeleted: (id) => deletedIdReceived = id, ), ), child: const Text('Open Modal'), ), ), ), ), ); await tester.pumpAndSettle(); // Open modal await tester.tap(find.text('Open Modal')); await tester.pumpAndSettle(); // Click Eliminar await tester.tap(find.text('Eliminar')); await tester.pumpAndSettle(); // Click Eliminar Paciente inside confirmation dialog await tester.tap(find.text('Eliminar Paciente')); await tester.pumpAndSettle(); expect(mockService.deletedPatientId, 999); expect(deletedIdReceived, 999); expect(find.textContaining('eliminada exitosamente'), findsOneWidget); }); }); }