diff --git a/backend/tests/integration/test_comprobante.py b/backend/tests/integration/test_comprobante.py index fff95e5..cca63c4 100644 --- a/backend/tests/integration/test_comprobante.py +++ b/backend/tests/integration/test_comprobante.py @@ -98,3 +98,28 @@ def test_comprobante_errores(client, url, cabeceras, status): def test_numero_de_factura(): assert numero_factura(7) == "KEC-00000007" + + +# ---------------------------------------------------------------- asientos en la factura + + +def _con_asientos(*asientos): + base = _detalle() + return ReservaDetalle(base.reserva, base.vuelo, tuple(asientos)) + + +def test_la_factura_lista_los_asientos_de_la_reserva(): + datos = armar_datos_factura(_con_asientos("1A", "2B"), ANA) + assert datos["detalles"][0]["asientos"] == "1A, 2B" + raiz = ElementTree.fromstring(generar_factura_xml(datos).encode("utf-8")) + producto = raiz.find("Detalle/producto") + assert [c.tag for c in producto] == ["Nombre", "Asientos", "Cantidad", "PrecioUnitario", "Subtotal"] + assert producto.findtext("Asientos") == "1A, 2B" + + +def test_los_caracteres_especiales_del_cliente_no_rompen_el_xml(): + cliente = un_usuario(id=1, nombre="Ana & Co'); + }); + + test('los montos se leen en centavos exactos, sin decimales flotantes', () { + final f = Factura.desdeXml(facturaXml(unitario: '0.10', subtotal: '0.30', iva: '0.05', total: '0.35', cantidad: '3')); + expect((f.precioUnitarioCentavos, f.subtotalCentavos, f.ivaCentavos, f.totalCentavos), (10, 30, 5, 35)); + }); + + test('todo lo que no sea una factura válida es InvalidResponseFailure', () { + for (final malo in [ + '', + 'esto no es xml', + '', + '', + '', + '{"json": true}', + facturaXml(total: 'mucho'), + facturaXml(cantidad: 'dos'), + facturaXml(fecha: '11/11/2026'), + facturaXml(porcentaje: '1500'), + facturaXml(numero: ''), + facturaXml(correo: ''), + facturaXml().replaceAll('Confirmada', ''), + facturaXml().replaceAll('', '').replaceAll('', ''), + ']>&e;', + ]) { + expect(() => Factura.desdeXml(malo), throwsA(isA()), reason: malo.length > 60 ? malo.substring(0, 60) : malo); + } + }); + + test('un XML enorme no rompe el lector', () { + final grande = facturaXml(descripcion: 'Pasaje ${'x' * 200000}'); + expect(Factura.desdeXml(grande).descripcion.length, greaterThan(200000)); + }); + }); +} diff --git a/frontend/test/pages/admin_y_paginacion_test.dart b/frontend/test/pages/admin_y_paginacion_test.dart index 066920d..12870a8 100644 --- a/frontend/test/pages/admin_y_paginacion_test.dart +++ b/frontend/test/pages/admin_y_paginacion_test.dart @@ -152,7 +152,7 @@ void main() { group('panel de administración', () { testWidgets('el cliente no ve el botón del panel y la ruta lo devuelve a la lista', (tester) async { await _abrir(tester, {'GET /vuelos': sinVuelos}); - expect(find.byTooltip('Panel de administración'), findsNothing); + expect(find.text('Administración'), findsNothing); _irA(tester, AppRoutes.admin); await tester.pumpAndSettle(); @@ -163,7 +163,7 @@ void main() { testWidgets('el administrador abre el panel y ve el IVA vigente y el historial', (tester) async { await _abrir(tester, {'GET /vuelos': sinVuelos, 'GET /iva': respuestaIva}, usuario: usuarioAdmin); - await tester.tap(find.byTooltip('Panel de administración')); + await tester.tap(find.text('Administración')); await tester.pumpAndSettle(); expect(find.byType(AdminPage), findsOneWidget); diff --git a/frontend/test/pages/comprobante_test.dart b/frontend/test/pages/comprobante_test.dart new file mode 100644 index 0000000..bfbba52 --- /dev/null +++ b/frontend/test/pages/comprobante_test.dart @@ -0,0 +1,184 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vuelos_app/config/app_router.dart'; +import 'package:vuelos_app/pages/comprobante_page.dart'; +import 'package:vuelos_app/pages/login_page.dart'; +import 'package:vuelos_app/pages/vuelos_page.dart'; +import 'package:vuelos_app/services/api_exception.dart'; + +import '../helpers/app_helper.dart'; +import '../helpers/fakes.dart'; + +Future _abrir(WidgetTester tester, Map rutas, {Object usuario = usuarioAna}) async { + final client = RouteFakeRestClient({ + 'GET /auth/perfil': {'usuario': usuario}, + 'GET /vuelos': respuestaVuelos, + 'GET /iva': respuestaIva, + 'GET /reservas/58': reservaJson(), + ...rutas, + }); + await abrirApp(tester, client: client, tokens: InMemoryTokenStorage('jwt')); + return client; +} + +Future _ir(WidgetTester tester, String ruta) async { + ProviderScope.containerOf(tester.element(find.byType(MaterialApp))).read(appRouterProvider).push(ruta); + await tester.pumpAndSettle(); +} + +void main() { + group('desde la reserva', () { + testWidgets('el botón "Ver comprobante" abre la factura', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml()}); + await _ir(tester, AppRoutes.reserva(58)); + + await tester.tap(find.text('Ver comprobante (factura XML)')); + await tester.pumpAndSettle(); + + expect(find.byType(ComprobantePage), findsOneWidget); + }); + + testWidgets('también se ofrece en una reserva cancelada (queda como anulada)', (tester) async { + await _abrir(tester, { + 'GET /reservas/58': reservaJson(estado: 'cancelada'), + 'GET /reservas/58/comprobante': facturaXml(estado: 'Cancelada'), + }); + await _ir(tester, AppRoutes.reserva(58)); + await tester.tap(find.text('Ver comprobante (factura XML)')); + await tester.pumpAndSettle(); + + expect(find.text('Anulada'), findsOneWidget); + }); + }); + + group('la factura', () { + testWidgets('muestra número, fecha, cliente, asientos, montos e IVA', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml()}); + await _ir(tester, AppRoutes.comprobante(58)); + + expect(find.text('Factura KEC-00000058'), findsOneWidget); + expect(find.textContaining('Emitida el'), findsOneWidget); + expect(find.text('Ana Torres'), findsOneWidget); + expect(find.text('ana@correo.com'), findsOneWidget); + expect(find.textContaining('Pasaje KT101'), findsOneWidget); + expect(find.text('Asiento 1A'), findsOneWidget); + expect(find.text('Asiento 1B'), findsOneWidget); + expect(find.text(r'2 × $89.00'), findsOneWidget); + expect(find.text(r'$178.00'), findsWidgets); + expect(find.text('IVA (15 %)'), findsOneWidget); + expect(find.text(r'$26.70'), findsOneWidget); + expect(find.text(r'$204.70'), findsOneWidget); + expect(find.text('Confirmada'), findsOneWidget); + }); + + testWidgets('pide el comprobante a la ruta correcta', (tester) async { + final api = await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml()}); + await _ir(tester, AppRoutes.comprobante(58)); + expect(api.rutasSolicitadas, contains('GET /reservas/58/comprobante')); + }); + + testWidgets('un nombre con caracteres raros se ve como texto, sin interpretarse', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml(nombre: 'Ana <b>Negrita</b> & Co')}); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.text('Ana Negrita & Co'), findsOneWidget); + }); + }); + + group('el panel Factura XML', () { + testWidgets('muestra el XML tal como lo entrega el servidor', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml()}); + await _ir(tester, AppRoutes.comprobante(58)); + + await tester.tap(find.text('Factura XML')); + await tester.pumpAndSettle(); + + expect(find.textContaining('', findRichText: true), findsOneWidget); + expect(find.textContaining('KEC-00000058', findRichText: true), findsOneWidget); + expect(find.text('Copiar XML'), findsOneWidget); + expect(find.text('Factura KEC-00000058'), findsNothing); // la vista legible ya no está + }); + + testWidgets('Copiar XML lo deja en el portapapeles y avisa', (tester) async { + String? copiado; + tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (llamada) async { + if (llamada.method == 'Clipboard.setData') copiado = (llamada.arguments as Map)['text'] as String?; + return null; + }); + addTearDown(() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null)); + final xml = facturaXml(); + await _abrir(tester, {'GET /reservas/58/comprobante': xml}); + await _ir(tester, AppRoutes.comprobante(58)); + await tester.tap(find.text('Factura XML')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Copiar XML')); + await tester.pump(); + + expect(copiado, xml); + expect(find.text('XML copiado al portapapeles.'), findsOneWidget); + }); + + testWidgets('se puede volver a la vista de la factura', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': facturaXml()}); + await _ir(tester, AppRoutes.comprobante(58)); + await tester.tap(find.text('Factura XML')); + await tester.pumpAndSettle(); + await tester.tap(find.text('Factura').first); + await tester.pumpAndSettle(); + expect(find.text('Factura KEC-00000058'), findsOneWidget); + }); + }); + + group('cuando algo falla', () { + testWidgets('reserva ajena o inexistente (404): muestra el mensaje y permite reintentar', (tester) async { + var intento = 0; + await _abrir(tester, { + 'GET /reservas/58/comprobante': (_) => ++intento == 1 ? throw const ServerFailure('La reserva solicitada no existe.', statusCode: 404) : facturaXml(), + }); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.text('La reserva solicitada no existe.'), findsOneWidget); + + await tester.tap(find.text('Reintentar')); + await tester.pumpAndSettle(); + expect(find.text('Factura KEC-00000058'), findsOneWidget); + }); + + testWidgets('sin conexión: avisa y permite reintentar', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': const NetworkFailure()}); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.text('No se pudo conectar con el servidor.'), findsOneWidget); + expect(find.text('Reintentar'), findsOneWidget); + }); + + testWidgets('si el servidor manda algo que no es una factura, lo dice sin romperse', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': 'error de un proxy'}); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.text('El servidor envió una respuesta no válida.'), findsOneWidget); + expect(tester.takeException(), isNull); + }); + + testWidgets('un 401 cierra la sesión y lleva al login', (tester) async { + await _abrir(tester, {'GET /reservas/58/comprobante': const UnauthorizedFailure()}); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.byType(LoginPage), findsOneWidget); + }); + + testWidgets('el administrador no tiene comprobantes: vuelve a la lista', (tester) async { + final api = await _abrir(tester, {}, usuario: usuarioAdmin); + await _ir(tester, AppRoutes.comprobante(58)); + expect(find.byType(VuelosPage), findsOneWidget); + expect(api.rutasSolicitadas.where((r) => r.contains('comprobante')), isEmpty); + }); + + testWidgets('ids absurdos en la URL no llegan al servidor', (tester) async { + final api = await _abrir(tester, {}); + for (final id in ['0', 'abc', '99999999999999999999', '-1']) { + await _ir(tester, '/reservas/$id/comprobante'); + expect(find.byType(ComprobantePage), findsNothing, reason: id); + } + expect(api.rutasSolicitadas.where((r) => r.contains('comprobante')), isEmpty); + }); + }); +} diff --git a/frontend/test/pages/navegacion_test.dart b/frontend/test/pages/navegacion_test.dart new file mode 100644 index 0000000..34e42a6 --- /dev/null +++ b/frontend/test/pages/navegacion_test.dart @@ -0,0 +1,261 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:vuelos_app/config/app_router.dart'; +import 'package:vuelos_app/pages/admin_page.dart'; +import 'package:vuelos_app/pages/estado_api_page.dart'; +import 'package:vuelos_app/pages/login_page.dart'; +import 'package:vuelos_app/pages/reserva_detalle_page.dart'; +import 'package:vuelos_app/pages/reservas_page.dart'; +import 'package:vuelos_app/pages/seleccion_asientos_page.dart'; +import 'package:vuelos_app/pages/vuelo_detalle_page.dart'; +import 'package:vuelos_app/pages/vuelos_page.dart'; +import 'package:vuelos_app/widgets/migas.dart'; + +import '../helpers/app_helper.dart'; +import '../helpers/fakes.dart'; + +Future _abrir(WidgetTester tester, {Object usuario = usuarioAna, Map rutas = const {}}) async { + final client = RouteFakeRestClient({ + 'GET /auth/perfil': {'usuario': usuario}, + 'GET /vuelos': respuestaVuelos, + 'GET /vuelos/3': vueloQuitoGuayaquil, + 'GET /vuelos/3/asientos': mapaJson(), + 'GET /iva': respuestaIva, + 'GET /reservas': paginaDeReservas(total: 1, pagina: 1), + 'GET /reservas/58': reservaJson(), + 'GET /health': healthOk, + ...rutas, + }); + await abrirApp(tester, client: client, tokens: InMemoryTokenStorage('jwt')); + return client; +} + +Future _ir(WidgetTester tester, String ruta) async { + ProviderScope.containerOf(tester.element(find.byType(MaterialApp))).read(appRouterProvider).push(ruta); + await tester.pumpAndSettle(); +} + +Finder get _barraInferior => find.byType(NavigationBar); + +void main() { + group('barra de navegación inferior', () { + testWidgets('el cliente ve Vuelos y Mis reservas (y no Administración)', (tester) async { + await _abrir(tester); + expect(find.descendant(of: _barraInferior, matching: find.text('Vuelos')), findsOneWidget); + expect(find.descendant(of: _barraInferior, matching: find.text('Mis reservas')), findsOneWidget); + expect(find.descendant(of: _barraInferior, matching: find.text('Administración')), findsNothing); + }); + + testWidgets('el administrador ve Vuelos y Administración (y no Mis reservas)', (tester) async { + await _abrir(tester, usuario: usuarioAdmin); + expect(find.descendant(of: _barraInferior, matching: find.text('Vuelos')), findsOneWidget); + expect(find.descendant(of: _barraInferior, matching: find.text('Administración')), findsOneWidget); + expect(find.descendant(of: _barraInferior, matching: find.text('Mis reservas')), findsNothing); + }); + + testWidgets('resalta la sección en la que está el usuario', (tester) async { + await _abrir(tester); + expect(tester.widget(_barraInferior).selectedIndex, 0); + await _ir(tester, AppRoutes.reserva(58)); + expect(tester.widget(_barraInferior).selectedIndex, 1); // el detalle de una reserva es de "Mis reservas" + }); + + testWidgets('desde un detalle profundo se llega a cualquier sección con un toque', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.reserva(58)); + expect(find.byType(ReservaDetallePage), findsOneWidget); + + await tester.tap(find.descendant(of: _barraInferior, matching: find.text('Vuelos'))); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + + await tester.tap(find.descendant(of: _barraInferior, matching: find.text('Mis reservas'))); + await tester.pumpAndSettle(); + expect(find.byType(ReservasPage), findsOneWidget); + }); + + testWidgets('el administrador va a su panel desde la barra', (tester) async { + await _abrir(tester, usuario: usuarioAdmin); + await tester.tap(find.descendant(of: _barraInferior, matching: find.text('Administración'))); + await tester.pumpAndSettle(); + expect(find.byType(AdminPage), findsOneWidget); + }); + + testWidgets('el mapa de asientos NO tiene barra inferior (es un paso a medio camino, con su propio resumen)', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + expect(find.byType(SeleccionAsientosPage), findsOneWidget); + expect(_barraInferior, findsNothing); + }); + }); + + group('inicio desde cualquier parte', () { + testWidgets('tocar el logo lleva al inicio', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.reserva(58)); + expect(find.byType(VuelosPage), findsNothing); + + await tester.tap(find.byTooltip('Ir al inicio')); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + }); + + testWidgets('también desde el mapa de asientos', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + await tester.tap(find.byTooltip('Ir al inicio')); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + }); + + testWidgets('el botón Volver regresa a la pantalla anterior', (tester) async { + await _abrir(tester); + await tester.tap(find.text('KT101')); + await tester.pumpAndSettle(); + expect(find.byType(VueloDetallePage), findsOneWidget); + + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + }); + }); + + group('migas de pan', () { + testWidgets('en el detalle del vuelo: Vuelos › KT101, y "Vuelos" regresa', (tester) async { + await _abrir(tester); + await tester.tap(find.text('KT101')); + await tester.pumpAndSettle(); + expect(find.byType(Migas), findsOneWidget); + expect(find.descendant(of: find.byType(Migas), matching: find.text('KT101')), findsOneWidget); + + await tester.tap(find.descendant(of: find.byType(Migas), matching: find.text('Vuelos'))); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + }); + + testWidgets('en una reserva: Mis reservas › KEC-…, y "Mis reservas" regresa', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.reserva(58)); + expect(find.descendant(of: find.byType(Migas), matching: find.text('KEC-00000058')), findsOneWidget); + + await tester.tap(find.descendant(of: find.byType(Migas), matching: find.text('Mis reservas'))); + await tester.pumpAndSettle(); + expect(find.byType(ReservasPage), findsOneWidget); + }); + + testWidgets('en el mapa de asientos se puede volver al vuelo desde las migas', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + await tester.tap(find.descendant(of: find.byType(Migas), matching: find.text('KT101'))); + await tester.pumpAndSettle(); + expect(find.byType(VueloDetallePage), findsOneWidget); + }); + }); + + group('menú de cuenta', () { + testWidgets('muestra quién está conectado y su rol', (tester) async { + await _abrir(tester); + await tester.tap(find.byWidgetPredicate((w) => w is PopupMenuButton)); + await tester.pumpAndSettle(); + expect(find.text('Ana Torres'), findsOneWidget); + expect(find.text('ana@correo.com'), findsOneWidget); + expect(find.text('Cliente'), findsOneWidget); + }); + + testWidgets('el administrador figura como Administrador', (tester) async { + await _abrir(tester, usuario: usuarioAdmin); + await tester.tap(find.byWidgetPredicate((w) => w is PopupMenuButton)); + await tester.pumpAndSettle(); + expect(find.text('Administrador'), findsOneWidget); + }); + + testWidgets('lleva al estado del servicio', (tester) async { + await _abrir(tester); + await tester.tap(find.byWidgetPredicate((w) => w is PopupMenuButton)); + await tester.pumpAndSettle(); + await tester.tap(find.text('Estado del servicio')); + await tester.pumpAndSettle(); + expect(find.byType(EstadoApiPage), findsOneWidget); + }); + + testWidgets('cerrar sesión pide confirmación: "Seguir conectado" la conserva', (tester) async { + final api = await _abrir(tester); + await tester.tap(find.byWidgetPredicate((w) => w is PopupMenuButton)); + await tester.pumpAndSettle(); + await tester.tap(find.text('Cerrar sesión')); + await tester.pumpAndSettle(); + expect(find.text('¿Cerrar sesión?'), findsOneWidget); + + await tester.tap(find.text('Seguir conectado')); + await tester.pumpAndSettle(); + expect(find.byType(VuelosPage), findsOneWidget); + expect(api.llamadas.where((l) => l.ruta == '/auth/logout'), isEmpty); + }); + }); + + group('salir del mapa de asientos con cambios', () { + Future elegir(WidgetTester tester, String asiento) async { + await tester.tap(find.text(asiento)); + await tester.pump(); + } + + testWidgets('sin asientos elegidos, "Volver" sale sin preguntar', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + expect(find.byType(SeleccionAsientosPage), findsNothing); + expect(find.text('¿Salir sin guardar?'), findsNothing); + }); + + testWidgets('con asientos elegidos pregunta antes de salir; "Seguir eligiendo" los conserva', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + await elegir(tester, '1A'); + + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + expect(find.text('¿Salir sin guardar?'), findsOneWidget); + + await tester.tap(find.text('Seguir eligiendo')); + await tester.pumpAndSettle(); + expect(find.byType(SeleccionAsientosPage), findsOneWidget); + expect(find.text('Asientos (1 de 10): 1A'), findsOneWidget); + }); + + testWidgets('con asientos elegidos, "Salir" abandona la selección', (tester) async { + await _abrir(tester); + await _ir(tester, AppRoutes.asientosDelVuelo(3)); + await elegir(tester, '1A'); + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + await tester.tap(find.text('Salir')); + await tester.pumpAndSettle(); + expect(find.byType(SeleccionAsientosPage), findsNothing); + }); + + testWidgets('al cambiar los asientos de una reserva también avisa si hay cambios sin guardar', (tester) async { + await _abrir(tester, rutas: {'GET /vuelos/3/asientos': mapaJson(ocupados: ['1A', '1B'])}); + await _ir(tester, AppRoutes.asientosDeLaReserva(58)); + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + expect(find.text('¿Salir sin guardar?'), findsNothing); // sin cambios: sale directo + + await _ir(tester, AppRoutes.asientosDeLaReserva(58)); + await elegir(tester, '2A'); + await tester.tap(find.byTooltip('Volver')); + await tester.pumpAndSettle(); + expect(find.text('¿Salir sin guardar?'), findsOneWidget); + expect(find.text('Los cambios en sus asientos no se guardarán.'), findsOneWidget); + }); + }); + + testWidgets('sin sesión no hay barra de navegación ni menú (login)', (tester) async { + final client = RouteFakeRestClient({}); + await abrirApp(tester, client: client); + expect(find.byType(LoginPage), findsOneWidget); + expect(_barraInferior, findsNothing); + expect(find.byWidgetPredicate((w) => w is PopupMenuButton), findsNothing); + }); +} diff --git a/frontend/test/pages/seleccion_asientos_test.dart b/frontend/test/pages/seleccion_asientos_test.dart index cad3b27..6b17a98 100644 --- a/frontend/test/pages/seleccion_asientos_test.dart +++ b/frontend/test/pages/seleccion_asientos_test.dart @@ -43,7 +43,7 @@ void main() { await _ir(tester, AppRoutes.asientosDelVuelo(3)); expect(find.byType(SeleccionAsientosPage), findsOneWidget); - expect(find.text('KT101'), findsOneWidget); + expect(find.text('KT101'), findsWidgets); // en las migas y en la cabecera expect(find.text('Disponible'), findsOneWidget); expect(find.text('Seleccionado'), findsOneWidget); expect(find.text('Ocupado'), findsOneWidget); diff --git a/frontend/test/pages/vuelos_page_test.dart b/frontend/test/pages/vuelos_page_test.dart index 7194809..be609f9 100644 --- a/frontend/test/pages/vuelos_page_test.dart +++ b/frontend/test/pages/vuelos_page_test.dart @@ -137,7 +137,7 @@ void main() { expect(find.text('42 libres de 80'), findsOneWidget); expect(find.text('Precio por persona'), findsOneWidget); - await tester.tap(find.byTooltip('Volver a los vuelos')); + await tester.tap(find.byTooltip('Volver')); await tester.pumpAndSettle(); expect(find.byType(VuelosPage), findsOneWidget); });