Files

238 lines
7.5 KiB
Dart
Raw Permalink Normal View History

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