238 lines
7.5 KiB
Dart
238 lines
7.5 KiB
Dart
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);
|
|
});
|
|
});
|
|
}
|