// Author: fruit.com.cn import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/config/app_config.dart'; import 'package:fruitshorts/core/theme/app_colors.dart'; import 'package:fruitshorts/core/widgets/catalog_endpoint_editor.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/home/widgets/home_failure_view.dart'; void main() { tearDown(AppConfig.clearRuntimeBaseUrl); testWidgets('should_show_endpoint_and_raw_error_in_debug_failure', ( tester, ) async { AppConfig.applyRuntimeBaseUrl('http://probe.test:8081'); await tester.pumpWidget( MaterialApp( locale: const Locale('en'), supportedLocales: AppLocalizations.supportedLocales, localizationsDelegates: AppLocalizations.localizationsDelegates, home: Scaffold( body: HomeFailureView( error: 'SocketException: Connection refused', onRetry: () {}, onEditEndpoint: () {}, ), ), ), ); final endpoint = tester.widget( find.byKey(const Key('catalog-debug-endpoint')), ); expect(endpoint.data, '服务地址:http://probe.test:8081'); expect(endpoint.style?.fontSize, 12); expect(endpoint.style?.color, AppColors.subtle); expect(endpoint.maxLines, 2); final error = tester.widget( find.byKey(const Key('catalog-debug-error')), ); expect(error.data, '错误:SocketException: Connection refused'); expect(error.style?.fontSize, 12); expect(error.style?.color, AppColors.subtle); expect(error.maxLines, 2); expect( find.byKey(const Key('catalog-debug-endpoint-edit')), findsOneWidget, ); }); testWidgets('should_save_and_reload_after_valid_endpoint', (tester) async { AppConfig.applyRuntimeBaseUrl('http://127.0.0.1:8081'); final steps = []; await _pumpEndpointEditor( tester, save: (value) async { steps.add('save:$value'); return true; }, reload: () async => steps.add('load'), ); expect( tester .widget( find.byKey(const Key('catalog-debug-endpoint-input')), ) .controller ?.text, 'http://127.0.0.1:8081', ); expect( find.byKey(const Key('catalog-debug-endpoint-hint')), findsOneWidget, ); await tester.enterText( find.byKey(const Key('catalog-debug-endpoint-input')), 'http://10.0.0.8:8081///', ); await tester.tap(find.byKey(const Key('catalog-debug-endpoint-save'))); await tester.pumpAndSettle(); expect(steps, ['save:http://10.0.0.8:8081', 'load']); }); testWidgets('should_reject_invalid_endpoint_without_saving', (tester) async { var saves = 0; var loads = 0; await _pumpEndpointEditor( tester, save: (_) async { saves++; return true; }, reload: () async => loads++, ); await tester.enterText( find.byKey(const Key('catalog-debug-endpoint-input')), 'not a valid url', ); await tester.tap(find.byKey(const Key('catalog-debug-endpoint-save'))); await tester.pump(); expect( find.byKey(const Key('catalog-debug-endpoint-error')), findsOneWidget, ); expect( find.byKey(const Key('catalog-debug-endpoint-input')), findsOneWidget, ); expect(saves, 0); expect(loads, 0); }); } Future _pumpEndpointEditor( WidgetTester tester, { required Future Function(String value) save, required Future Function() reload, }) async { await tester.pumpWidget( MaterialApp( home: Builder( builder: (context) => Scaffold( body: TextButton( key: const Key('open-endpoint-editor'), onPressed: () => unawaited( showCatalogEndpointEditor(context, save: save, reload: reload), ), child: const Text('open'), ), ), ), ), ); await tester.tap(find.byKey(const Key('open-endpoint-editor'))); await tester.pumpAndSettle(); }