2026-09-21 16:33:51 -04:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
|
import 'package:hidalyx_drluiscastro/core/widgets/medical_modal.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';
|
2026-10-02 11:09:02 -04:00
|
|
|
import 'package:hidalyx_drluiscastro/features/patient/presentation/widgets/patient_clinical_tabs.dart';
|
2026-09-21 16:33:51 -04:00
|
|
|
import 'package:hidalyx_drluiscastro/features/patient/presentation/widgets/patient_demographics_form.dart';
|
|
|
|
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|
|
|
|
import 'package:toggle_switch/toggle_switch.dart';
|
|
|
|
|
|
|
|
|
|
class MockPatientService extends PatientService {
|
|
|
|
|
PatientModel? storedPatient;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<PatientModel> getPatientById(int id) async {
|
|
|
|
|
return const PatientModel(
|
|
|
|
|
id: 99,
|
|
|
|
|
nombre: 'MARIA',
|
|
|
|
|
apellido: 'SANTOS',
|
|
|
|
|
cedula: '402-0000000-1',
|
|
|
|
|
telefono: '809-555-9999',
|
|
|
|
|
direccion: 'Santiago',
|
|
|
|
|
ocupacion: 'Docente',
|
|
|
|
|
edad: '35',
|
|
|
|
|
sexo: 'Femenino',
|
|
|
|
|
seguro: 'Sí',
|
|
|
|
|
estCivil: 'Casado',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<PatientModel> createPatient(PatientModel model) async {
|
|
|
|
|
storedPatient = model;
|
|
|
|
|
return PatientModel.fromJson({
|
|
|
|
|
...model.toJson(),
|
|
|
|
|
'id': 101,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<PatientModel> updatePatient(int id, Map<String, dynamic> updates) async {
|
|
|
|
|
return PatientModel.fromJson({
|
|
|
|
|
...updates,
|
|
|
|
|
'id': id,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
|
group('PatientModel serialization', () {
|
|
|
|
|
test('serializes and deserializes properly from Directus schema', () {
|
|
|
|
|
final json = {
|
|
|
|
|
'id': 50,
|
|
|
|
|
'nombre': 'CARLOS',
|
|
|
|
|
'apellido': 'ARIAS',
|
|
|
|
|
'telefono': '809-555-1234',
|
|
|
|
|
'direccion': 'Calle 1 #2',
|
|
|
|
|
'cedula': '001-0000000-0',
|
|
|
|
|
'ocupacion': 'Ingeniero',
|
|
|
|
|
'edad': '40',
|
|
|
|
|
'sexo': 'Masculino',
|
|
|
|
|
'seguro': 'Sí',
|
|
|
|
|
'est_civil': 'Casado',
|
|
|
|
|
'mot_cons': 'Dolor de cabeza',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
final model = PatientModel.fromJson(json);
|
|
|
|
|
expect(model.id, equals(50));
|
|
|
|
|
expect(model.fullName, equals('CARLOS ARIAS'));
|
|
|
|
|
expect(model.sexo, equals('Masculino'));
|
|
|
|
|
expect(model.seguro, equals('Sí'));
|
|
|
|
|
|
|
|
|
|
final outJson = model.toJson(includeId: true);
|
|
|
|
|
expect(outJson['id'], equals(50));
|
|
|
|
|
expect(outJson['nombre'], equals('CARLOS'));
|
|
|
|
|
expect(outJson['mot_cons'], equals('Dolor de cabeza'));
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
group('PatientStore business logic', () {
|
|
|
|
|
test('validation requires nombre, apellido, sexo and seguro', () {
|
|
|
|
|
final store = PatientStore(patientService: MockPatientService());
|
|
|
|
|
store.initForCreate();
|
|
|
|
|
expect(store.isValid, isFalse);
|
|
|
|
|
|
|
|
|
|
store.nombre = 'Ana';
|
|
|
|
|
expect(store.isValid, isFalse);
|
|
|
|
|
|
|
|
|
|
store.apellido = 'Gomez';
|
|
|
|
|
expect(store.isValid, isTrue); // sexo and seguro default to 'Masculino'/'Sí'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('calculates remaining days for proxima cita correctly', () {
|
|
|
|
|
final store = PatientStore(patientService: MockPatientService());
|
|
|
|
|
store.initForCreate();
|
|
|
|
|
|
|
|
|
|
expect(store.diasParaProximaCita, isNull);
|
|
|
|
|
|
|
|
|
|
final now = DateTime.now();
|
|
|
|
|
final futureDate = now.add(const Duration(days: 10));
|
|
|
|
|
final day = futureDate.day.toString().padLeft(2, '0');
|
|
|
|
|
final month = futureDate.month.toString().padLeft(2, '0');
|
|
|
|
|
final year = futureDate.year.toString();
|
|
|
|
|
|
|
|
|
|
store.fecProxcita = '$day/$month/$year';
|
|
|
|
|
expect(store.diasParaProximaCita, equals(10));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('creates new patient successfully', () async {
|
|
|
|
|
final mock = MockPatientService();
|
|
|
|
|
final store = PatientStore(patientService: mock);
|
|
|
|
|
store.initForCreate();
|
|
|
|
|
store.nombre = 'Pedro';
|
|
|
|
|
store.apellido = 'Martinez';
|
|
|
|
|
|
|
|
|
|
final success = await store.savePatient();
|
|
|
|
|
expect(success, isTrue);
|
|
|
|
|
expect(store.id, equals(101));
|
|
|
|
|
expect(store.successMessage, contains('guardado correctamente'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('updates existing patient successfully', () async {
|
|
|
|
|
final mock = MockPatientService();
|
|
|
|
|
final store = PatientStore(patientService: mock);
|
|
|
|
|
await store.loadPatient(99);
|
|
|
|
|
|
|
|
|
|
expect(store.isEditing, isTrue);
|
|
|
|
|
expect(store.nombre, equals('MARIA'));
|
|
|
|
|
expect(store.apellido, equals('SANTOS'));
|
|
|
|
|
|
|
|
|
|
store.ocupacion = 'Directora';
|
|
|
|
|
final success = await store.savePatient();
|
|
|
|
|
expect(success, isTrue);
|
|
|
|
|
expect(store.successMessage, contains('actualizado correctamente'));
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
group('PatientModalView strict closure tests', () {
|
|
|
|
|
testWidgets('modal adheres to strict ESC and (X) close rules', (tester) async {
|
|
|
|
|
tester.view.physicalSize = const Size(1280, 800);
|
|
|
|
|
tester.view.devicePixelRatio = 1.0;
|
|
|
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
|
|
|
|
|
|
|
|
await tester.pumpWidget(
|
|
|
|
|
MaterialApp(
|
|
|
|
|
home: Scaffold(
|
|
|
|
|
body: Builder(
|
|
|
|
|
builder: (context) => ElevatedButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
showMedicalModal(
|
|
|
|
|
context: context,
|
|
|
|
|
builder: (_) => const PatientModalView(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
child: const Text('Registrar'),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await tester.tap(find.text('Registrar'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(find.text('Registro De Paciente'), findsOneWidget);
|
|
|
|
|
|
|
|
|
|
// Outside tap does NOT close
|
|
|
|
|
await tester.tapAt(const Offset(5, 5));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(find.text('Registro De Paciente'), findsOneWidget);
|
|
|
|
|
|
|
|
|
|
// ESC key closes the modal
|
|
|
|
|
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(find.text('Registro De Paciente'), findsNothing);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
testWidgets('date button inserts current date at cursor in Consultas', (tester) async {
|
|
|
|
|
tester.view.physicalSize = const Size(1280, 800);
|
|
|
|
|
tester.view.devicePixelRatio = 1.0;
|
|
|
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
|
|
|
|
|
|
|
|
await tester.pumpWidget(
|
|
|
|
|
MaterialApp(
|
|
|
|
|
home: Scaffold(
|
|
|
|
|
body: Builder(
|
|
|
|
|
builder: (context) => ElevatedButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
showMedicalModal(
|
|
|
|
|
context: context,
|
|
|
|
|
builder: (_) => const PatientModalView(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
child: const Text('Registrar'),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await tester.tap(find.text('Registrar'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Find the Fecha actual button
|
|
|
|
|
final insertBtn = find.widgetWithText(ElevatedButton, 'Fecha actual');
|
|
|
|
|
expect(insertBtn, findsOneWidget);
|
|
|
|
|
|
|
|
|
|
await tester.tap(insertBtn);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Verify that current year is present in the field
|
|
|
|
|
final currentYear = DateTime.now().year.toString();
|
|
|
|
|
expect(find.textContaining(currentYear), findsWidgets);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
testWidgets('renders and switches ToggleSwitch for Sexo, Seguro, and Est. Civil', (tester) async {
|
|
|
|
|
await tester.binding.setSurfaceSize(const Size(1200, 900));
|
|
|
|
|
|
|
|
|
|
await tester.pumpWidget(
|
|
|
|
|
MaterialApp(
|
|
|
|
|
home: Scaffold(
|
|
|
|
|
body: Builder(
|
|
|
|
|
builder: (ctx) => ElevatedButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
showMedicalModal(
|
|
|
|
|
context: ctx,
|
|
|
|
|
builder: (_) => const PatientModalView(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
child: const Text('Registrar'),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await tester.tap(find.text('Registrar'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Verify ToggleSwitch instances exist for Sexo, Seguro, and Est. Civil
|
|
|
|
|
expect(find.byType(ToggleSwitch), findsNWidgets(3));
|
|
|
|
|
|
|
|
|
|
// Tap Femenino
|
|
|
|
|
await tester.tap(find.text('Femenino'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Tap Sin Seguro
|
|
|
|
|
await tester.tap(find.text('Sin Seguro'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Tap Casado
|
|
|
|
|
await tester.tap(find.text('Casado'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Verify the 8 demographic text fields have unifiedRowHeight matching toggle containers and save button
|
|
|
|
|
final textFields = find.byType(FormBuilderTextField);
|
|
|
|
|
|
|
|
|
|
// Verify all 8 fields, 3 toggle selector boxes, and the Save button have unifiedRowHeight
|
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
|
final decFinder = find.descendant(of: textFields.at(i), matching: find.byType(InputDecorator));
|
|
|
|
|
final customPaintFinder = find.descendant(of: decFinder, matching: find.byType(CustomPaint));
|
|
|
|
|
final rb = customPaintFinder.evaluate().first.renderObject as RenderBox;
|
|
|
|
|
final translation = rb.localToGlobal(Offset.zero);
|
|
|
|
|
final rect = translation & rb.size;
|
|
|
|
|
expect(rect.height, equals(PatientDemographicsForm.unifiedRowHeight));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify the 3 toggle selector visible boxes have unifiedRowHeight
|
|
|
|
|
final selectorBoxes = find.byWidgetPredicate((w) => w is Container && w.decoration is BoxDecoration && (w.decoration as BoxDecoration).color == const Color(0xFFF8FAFC));
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
|
final boxRect = tester.getRect(selectorBoxes.at(i));
|
|
|
|
|
expect(boxRect.height, equals(PatientDemographicsForm.unifiedRowHeight));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify the Save button has unifiedRowHeight
|
|
|
|
|
final saveBtn = find.widgetWithText(ElevatedButton, 'Guardar Paciente');
|
|
|
|
|
expect(tester.getRect(saveBtn).height, equals(PatientDemographicsForm.unifiedRowHeight));
|
|
|
|
|
|
|
|
|
|
// Row-by-row pixel-exact alignment check for all 4 rows
|
|
|
|
|
for (int row = 0; row < 4; row++) {
|
|
|
|
|
// Col 1 field
|
|
|
|
|
final f1Dec = find.descendant(of: textFields.at(row), matching: find.byType(InputDecorator));
|
|
|
|
|
final f1Cp = find.descendant(of: f1Dec, matching: find.byType(CustomPaint));
|
|
|
|
|
final f1Rb = f1Cp.evaluate().first.renderObject as RenderBox;
|
|
|
|
|
final f1Rect = f1Rb.localToGlobal(Offset.zero) & f1Rb.size;
|
|
|
|
|
|
|
|
|
|
// Col 2 field
|
|
|
|
|
final f2Dec = find.descendant(of: textFields.at(row + 4), matching: find.byType(InputDecorator));
|
|
|
|
|
final f2Cp = find.descendant(of: f2Dec, matching: find.byType(CustomPaint));
|
|
|
|
|
final f2Rb = f2Cp.evaluate().first.renderObject as RenderBox;
|
|
|
|
|
final f2Rect = f2Rb.localToGlobal(Offset.zero) & f2Rb.size;
|
|
|
|
|
|
|
|
|
|
// Col 3 item (selector box for rows 0..2, saveBtn for row 3)
|
|
|
|
|
final Rect f3Rect = row < 3 ? tester.getRect(selectorBoxes.at(row)) : tester.getRect(saveBtn);
|
|
|
|
|
|
|
|
|
|
// Verify tops match
|
|
|
|
|
expect(f1Rect.top, equals(f2Rect.top), reason: 'Row $row tops Col1 vs Col2');
|
|
|
|
|
expect(f1Rect.top, equals(f3Rect.top), reason: 'Row $row tops Col1 vs Col3');
|
|
|
|
|
|
|
|
|
|
// Verify bottoms match
|
|
|
|
|
expect(f1Rect.bottom, equals(f2Rect.bottom), reason: 'Row $row bottoms Col1 vs Col2');
|
|
|
|
|
expect(f1Rect.bottom, equals(f3Rect.bottom), reason: 'Row $row bottoms Col1 vs Col3');
|
|
|
|
|
|
|
|
|
|
// Verify heights match exactly
|
|
|
|
|
expect(f1Rect.height, equals(f3Rect.height), reason: 'Row $row heights Col1 vs Col3');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
testWidgets('OutlineInputBorder and Toggle Container alignment check', (tester) async {
|
|
|
|
|
await tester.pumpWidget(
|
|
|
|
|
MaterialApp(
|
|
|
|
|
home: Scaffold(
|
|
|
|
|
body: Center(
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
width: 800,
|
|
|
|
|
child: Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
height: 51,
|
|
|
|
|
child: FormBuilder(
|
|
|
|
|
child: FormBuilderTextField(
|
|
|
|
|
name: 'test',
|
|
|
|
|
initialValue: 'Texto',
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
labelText: 'Nombre *',
|
|
|
|
|
isDense: true,
|
|
|
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 11, vertical: 12),
|
|
|
|
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Container(
|
|
|
|
|
margin: const EdgeInsets.only(top: 7),
|
|
|
|
|
height: 44,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: const Color(0xFFF8FAFC),
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
border: Border.all(color: const Color(0xFFE2E8F0)),
|
|
|
|
|
),
|
|
|
|
|
child: const Text('Toggle Container'),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(find.byType(FormBuilderTextField), findsOneWidget);
|
|
|
|
|
expect(find.text('Toggle Container'), findsOneWidget);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
group('PatientStore consultation workflow', () {
|
|
|
|
|
test('savePatient transitions estadoEspera from en_consulta to atendido', () async {
|
|
|
|
|
final mockService = MockPatientService();
|
|
|
|
|
final store = PatientStore(patientService: mockService);
|
|
|
|
|
store.id = 10;
|
|
|
|
|
store.nombre = 'JUAN';
|
|
|
|
|
store.apellido = 'PEREZ';
|
|
|
|
|
store.sexo = 'Masculino';
|
|
|
|
|
store.seguro = 'Sí';
|
|
|
|
|
store.estadoEspera = 'en_consulta';
|
|
|
|
|
|
|
|
|
|
final success = await store.savePatient();
|
|
|
|
|
|
|
|
|
|
expect(success, isTrue);
|
|
|
|
|
expect(store.estadoEspera, 'atendido');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('savePatient transitions estadoEspera from en_espera to atendido', () async {
|
|
|
|
|
final mockService = MockPatientService();
|
|
|
|
|
final store = PatientStore(patientService: mockService);
|
|
|
|
|
store.id = 11;
|
|
|
|
|
store.nombre = 'PEDRO';
|
|
|
|
|
store.apellido = 'GOMEZ';
|
|
|
|
|
store.sexo = 'Masculino';
|
|
|
|
|
store.seguro = 'Sí';
|
|
|
|
|
store.estadoEspera = 'en_espera';
|
|
|
|
|
|
|
|
|
|
final success = await store.savePatient();
|
|
|
|
|
|
|
|
|
|
expect(success, isTrue);
|
|
|
|
|
expect(store.estadoEspera, 'atendido');
|
|
|
|
|
});
|
2026-10-02 11:09:02 -04:00
|
|
|
|
|
|
|
|
testWidgets('Antec. patologicos fields are editable and allow custom text or clear', (tester) async {
|
|
|
|
|
await tester.binding.setSurfaceSize(const Size(1200, 900));
|
|
|
|
|
final store = PatientStore(patientService: MockPatientService());
|
|
|
|
|
|
|
|
|
|
await tester.pumpWidget(
|
|
|
|
|
MaterialApp(
|
|
|
|
|
home: Scaffold(
|
|
|
|
|
body: PatientClinicalTabs(store: store),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Tap on the 'Antec. patológicos' tab
|
|
|
|
|
await tester.tap(find.text('Antec. patológicos'));
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Verify that section and labels exist
|
|
|
|
|
expect(find.text('Antecedentes Personales Patológicos'), findsOneWidget);
|
|
|
|
|
expect(find.text('Alergias'), findsOneWidget);
|
|
|
|
|
expect(find.text('Infancia'), findsOneWidget);
|
|
|
|
|
|
|
|
|
|
// Find the text field for 'Alergias' and enter custom text
|
|
|
|
|
final alergiasField = find.ancestor(
|
|
|
|
|
of: find.text('Alergias'),
|
|
|
|
|
matching: find.byType(TextField),
|
|
|
|
|
);
|
|
|
|
|
expect(alergiasField, findsOneWidget);
|
|
|
|
|
|
|
|
|
|
await tester.enterText(alergiasField, 'Ibuprofeno y mariscos');
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
expect(store.datAlerg, 'Ibuprofeno y mariscos');
|
|
|
|
|
|
|
|
|
|
// Test clear button specifically for Alergias
|
|
|
|
|
final alergiasClear = find.descendant(
|
|
|
|
|
of: alergiasField,
|
|
|
|
|
matching: find.byTooltip('Limpiar'),
|
|
|
|
|
);
|
|
|
|
|
expect(alergiasClear, findsOneWidget);
|
|
|
|
|
await tester.tap(alergiasClear);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(store.datAlerg, '');
|
|
|
|
|
|
|
|
|
|
// Test opening dropdown menu and selecting an item
|
|
|
|
|
final dropdownArrow = find.descendant(
|
|
|
|
|
of: alergiasField,
|
|
|
|
|
matching: find.byIcon(Icons.arrow_drop_down_rounded),
|
|
|
|
|
);
|
|
|
|
|
expect(dropdownArrow, findsOneWidget);
|
|
|
|
|
await tester.tap(dropdownArrow);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
|
|
// Tap 'Penicilina' from the menu
|
|
|
|
|
await tester.tap(find.text('Penicilina').last);
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(store.datAlerg, 'Penicilina');
|
|
|
|
|
|
|
|
|
|
// Test appending text to the selected option
|
|
|
|
|
await tester.enterText(alergiasField, 'Penicilina (shock anafiláctico)');
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
expect(store.datAlerg, 'Penicilina (shock anafiláctico)');
|
|
|
|
|
});
|
2026-09-21 16:33:51 -04:00
|
|
|
});
|
|
|
|
|
}
|