|
2 | 2 | // Use of this source code is governed by a BSD-style license that can be
|
3 | 3 | // found in the LICENSE file.
|
4 | 4 |
|
5 |
| -import 'dart:async'; |
6 |
| - |
7 | 5 | import 'package:flutter/material.dart';
|
8 | 6 | import 'package:flutter_test/flutter_test.dart';
|
9 | 7 | import 'package:go_router/go_router.dart';
|
@@ -332,307 +330,4 @@ void main() {
|
332 | 330 | expect(hasError, isTrue);
|
333 | 331 | });
|
334 | 332 | });
|
335 |
| - group('GoRouter onEnter navigation control tests', () { |
336 |
| - late GoRouter router; |
337 |
| - |
338 |
| - tearDown(() async { |
339 |
| - router.dispose(); |
340 |
| - }); |
341 |
| - |
342 |
| - testWidgets( |
343 |
| - 'Initial route calls onEnter and sets current/next state correctly', |
344 |
| - (WidgetTester tester) async { |
345 |
| - GoRouterState? capturedCurrentState; |
346 |
| - GoRouterState? capturedNextState; |
347 |
| - int onEnterCallCount = 0; |
348 |
| - |
349 |
| - router = GoRouter( |
350 |
| - initialLocation: '/', |
351 |
| - onEnter: ( |
352 |
| - BuildContext context, |
353 |
| - GoRouterState current, |
354 |
| - GoRouterState next, |
355 |
| - GoRouter goRouter, |
356 |
| - ) async { |
357 |
| - onEnterCallCount++; |
358 |
| - capturedCurrentState = current; |
359 |
| - capturedNextState = next; |
360 |
| - return true; |
361 |
| - }, |
362 |
| - routes: <RouteBase>[ |
363 |
| - GoRoute( |
364 |
| - path: '/', |
365 |
| - builder: (_, __) => const Placeholder(), |
366 |
| - routes: <GoRoute>[ |
367 |
| - GoRoute( |
368 |
| - path: 'allowed', |
369 |
| - builder: (_, __) => const Placeholder(), |
370 |
| - ), |
371 |
| - GoRoute( |
372 |
| - path: 'blocked', |
373 |
| - builder: (_, __) => const Placeholder(), |
374 |
| - ), |
375 |
| - ], |
376 |
| - ), |
377 |
| - ], |
378 |
| - ); |
379 |
| - |
380 |
| - await tester.pumpWidget(MaterialApp.router(routerConfig: router)); |
381 |
| - await tester.pumpAndSettle(); |
382 |
| - |
383 |
| - expect(onEnterCallCount, equals(1)); |
384 |
| - expect( |
385 |
| - capturedCurrentState?.uri.path, |
386 |
| - capturedNextState?.uri.path, |
387 |
| - ); |
388 |
| - }, |
389 |
| - ); |
390 |
| - |
391 |
| - testWidgets( |
392 |
| - 'Navigation is blocked correctly when onEnter returns false', |
393 |
| - (WidgetTester tester) async { |
394 |
| - final List<String> navigationAttempts = <String>[]; |
395 |
| - String currentPath = '/'; |
396 |
| - |
397 |
| - router = GoRouter( |
398 |
| - initialLocation: '/', |
399 |
| - onEnter: ( |
400 |
| - BuildContext context, |
401 |
| - GoRouterState current, |
402 |
| - GoRouterState next, |
403 |
| - GoRouter goRouter, |
404 |
| - ) async { |
405 |
| - navigationAttempts.add(next.uri.path); |
406 |
| - currentPath = current.uri.path; |
407 |
| - return !next.uri.path.contains('blocked'); |
408 |
| - }, |
409 |
| - routes: <RouteBase>[ |
410 |
| - GoRoute( |
411 |
| - path: '/', |
412 |
| - builder: (_, __) => const Placeholder(), |
413 |
| - routes: <GoRoute>[ |
414 |
| - GoRoute( |
415 |
| - path: 'blocked', |
416 |
| - builder: (_, __) => const Placeholder(), |
417 |
| - ), |
418 |
| - GoRoute( |
419 |
| - path: 'allowed', |
420 |
| - builder: (_, __) => const Placeholder(), |
421 |
| - ), |
422 |
| - ], |
423 |
| - ), |
424 |
| - ], |
425 |
| - ); |
426 |
| - |
427 |
| - await tester.pumpWidget(MaterialApp.router(routerConfig: router)); |
428 |
| - await tester.pumpAndSettle(); |
429 |
| - |
430 |
| - final BuildContext context = |
431 |
| - tester.element(find.byType(Router<Object>)); |
432 |
| - final GoRouteInformationParser parser = router.routeInformationParser; |
433 |
| - final RouteMatchList beforeBlockedNav = |
434 |
| - router.routerDelegate.currentConfiguration; |
435 |
| - |
436 |
| - // Try blocked route |
437 |
| - final RouteMatchList blockedMatch = |
438 |
| - await parser.parseRouteInformationWithDependencies( |
439 |
| - RouteInformation( |
440 |
| - uri: Uri.parse('/blocked'), |
441 |
| - state: RouteInformationState<void>(type: NavigatingType.go), |
442 |
| - ), |
443 |
| - context, |
444 |
| - ); |
445 |
| - await tester.pumpAndSettle(); |
446 |
| - |
447 |
| - expect(blockedMatch.uri.toString(), |
448 |
| - equals(beforeBlockedNav.uri.toString())); |
449 |
| - expect(currentPath, equals('/')); |
450 |
| - expect(navigationAttempts, contains('/blocked')); |
451 |
| - |
452 |
| - // Try allowed route |
453 |
| - final RouteMatchList allowedMatch = |
454 |
| - await parser.parseRouteInformationWithDependencies( |
455 |
| - RouteInformation( |
456 |
| - uri: Uri.parse('/allowed'), |
457 |
| - state: RouteInformationState<void>(type: NavigatingType.go), |
458 |
| - ), |
459 |
| - context, |
460 |
| - ); |
461 |
| - expect(allowedMatch.uri.path, equals('/allowed')); |
462 |
| - expect(navigationAttempts, contains('/allowed')); |
463 |
| - await tester.pumpAndSettle(); |
464 |
| - }, |
465 |
| - ); |
466 |
| - }); |
467 |
| - |
468 |
| - group('onEnter redirection tests', () { |
469 |
| - late GoRouter router; |
470 |
| - |
471 |
| - tearDown(() async { |
472 |
| - router.dispose(); |
473 |
| - }); |
474 |
| - |
475 |
| - testWidgets('allows navigation when onEnter does not exceed limit', |
476 |
| - (WidgetTester tester) async { |
477 |
| - int onEnterCallCount = 0; |
478 |
| - |
479 |
| - router = GoRouter( |
480 |
| - initialLocation: '/home', |
481 |
| - onEnter: ( |
482 |
| - BuildContext context, |
483 |
| - GoRouterState current, |
484 |
| - GoRouterState next, |
485 |
| - GoRouter goRouter, |
486 |
| - ) async { |
487 |
| - onEnterCallCount++; |
488 |
| - return !next.uri.path.contains('block'); |
489 |
| - }, |
490 |
| - routes: <RouteBase>[ |
491 |
| - GoRoute( |
492 |
| - path: '/home', |
493 |
| - builder: (_, __) => |
494 |
| - const Scaffold(body: Center(child: Text('Home'))), |
495 |
| - routes: <GoRoute>[ |
496 |
| - GoRoute( |
497 |
| - path: 'allowed', |
498 |
| - builder: (_, __) => |
499 |
| - const Scaffold(body: Center(child: Text('Allowed'))), |
500 |
| - ), |
501 |
| - GoRoute( |
502 |
| - path: 'block', |
503 |
| - builder: (_, __) => |
504 |
| - const Scaffold(body: Center(child: Text('Blocked'))), |
505 |
| - ), |
506 |
| - ], |
507 |
| - ), |
508 |
| - ], |
509 |
| - redirectLimit: 3, |
510 |
| - ); |
511 |
| - |
512 |
| - await tester.pumpWidget(MaterialApp.router(routerConfig: router)); |
513 |
| - await tester.pumpAndSettle(); |
514 |
| - |
515 |
| - final BuildContext context = tester.element(find.byType(Scaffold)); |
516 |
| - final RouteMatchList matchList = await router.routeInformationParser |
517 |
| - .parseRouteInformationWithDependencies( |
518 |
| - RouteInformation( |
519 |
| - uri: Uri.parse('/home/allowed'), |
520 |
| - state: RouteInformationState<void>(type: NavigatingType.go), |
521 |
| - ), |
522 |
| - context, |
523 |
| - ); |
524 |
| - |
525 |
| - expect(matchList.uri.path, equals('/home/allowed')); |
526 |
| - expect(onEnterCallCount, greaterThan(0)); |
527 |
| - }); |
528 |
| - |
529 |
| - testWidgets( |
530 |
| - 'recursive onEnter limit triggers onException and resets navigation', |
531 |
| - (WidgetTester tester) async { |
532 |
| - final Completer<void> completer = Completer<void>(); |
533 |
| - Object? capturedError; |
534 |
| - |
535 |
| - router = GoRouter( |
536 |
| - initialLocation: '/start', |
537 |
| - redirectLimit: 2, |
538 |
| - onException: |
539 |
| - (BuildContext context, GoRouterState state, GoRouter goRouter) { |
540 |
| - capturedError = state.error; |
541 |
| - goRouter.go('/fallback'); |
542 |
| - completer.complete(); |
543 |
| - }, |
544 |
| - onEnter: (BuildContext context, GoRouterState current, |
545 |
| - GoRouterState next, GoRouter goRouter) async { |
546 |
| - if (next.uri.path == '/recursive') { |
547 |
| - goRouter.push('/recursive'); |
548 |
| - return false; |
549 |
| - } |
550 |
| - return true; |
551 |
| - }, |
552 |
| - routes: <RouteBase>[ |
553 |
| - GoRoute( |
554 |
| - path: '/start', |
555 |
| - builder: (_, __) => |
556 |
| - const Scaffold(body: Center(child: Text('Start'))), |
557 |
| - ), |
558 |
| - GoRoute( |
559 |
| - path: '/recursive', |
560 |
| - builder: (_, __) => |
561 |
| - const Scaffold(body: Center(child: Text('Recursive'))), |
562 |
| - ), |
563 |
| - GoRoute( |
564 |
| - path: '/fallback', |
565 |
| - builder: (_, __) => |
566 |
| - const Scaffold(body: Center(child: Text('Fallback'))), |
567 |
| - ), |
568 |
| - ], |
569 |
| - ); |
570 |
| - |
571 |
| - await tester.pumpWidget(MaterialApp.router(routerConfig: router)); |
572 |
| - await tester.pumpAndSettle(); |
573 |
| - |
574 |
| - router.go('/recursive'); |
575 |
| - await completer.future; |
576 |
| - await tester.pumpAndSettle(); |
577 |
| - |
578 |
| - expect(capturedError, isNotNull); |
579 |
| - expect(capturedError.toString(), |
580 |
| - contains('Too many onEnter calls detected')); |
581 |
| - expect(find.text('Fallback'), findsOneWidget); |
582 |
| - }); |
583 |
| - testWidgets( |
584 |
| - 'recursive onEnter limit triggers onException and resets navigation', |
585 |
| - (WidgetTester tester) async { |
586 |
| - final Completer<void> completer = Completer<void>(); |
587 |
| - Object? capturedError; |
588 |
| - |
589 |
| - router = GoRouter( |
590 |
| - initialLocation: '/start', |
591 |
| - redirectLimit: 2, |
592 |
| - onException: |
593 |
| - (BuildContext context, GoRouterState state, GoRouter goRouter) { |
594 |
| - capturedError = state.error; |
595 |
| - goRouter.go('/fallback'); |
596 |
| - completer.complete(); |
597 |
| - }, |
598 |
| - onEnter: (BuildContext context, GoRouterState current, |
599 |
| - GoRouterState next, GoRouter goRouter) async { |
600 |
| - if (next.uri.path == '/recursive') { |
601 |
| - goRouter.push('/recursive'); |
602 |
| - return false; |
603 |
| - } |
604 |
| - return true; |
605 |
| - }, |
606 |
| - routes: <RouteBase>[ |
607 |
| - GoRoute( |
608 |
| - path: '/start', |
609 |
| - builder: (_, __) => |
610 |
| - const Scaffold(body: Center(child: Text('Start'))), |
611 |
| - ), |
612 |
| - GoRoute( |
613 |
| - path: '/recursive', |
614 |
| - builder: (_, __) => |
615 |
| - const Scaffold(body: Center(child: Text('Recursive'))), |
616 |
| - ), |
617 |
| - GoRoute( |
618 |
| - path: '/fallback', |
619 |
| - builder: (_, __) => |
620 |
| - const Scaffold(body: Center(child: Text('Fallback'))), |
621 |
| - ), |
622 |
| - ], |
623 |
| - ); |
624 |
| - |
625 |
| - await tester.pumpWidget(MaterialApp.router(routerConfig: router)); |
626 |
| - await tester.pumpAndSettle(); |
627 |
| - |
628 |
| - router.go('/recursive'); |
629 |
| - await completer.future; |
630 |
| - await tester.pumpAndSettle(); |
631 |
| - |
632 |
| - expect(capturedError, isNotNull); |
633 |
| - expect(capturedError.toString(), |
634 |
| - contains('Too many onEnter calls detected')); |
635 |
| - expect(find.text('Fallback'), findsOneWidget); |
636 |
| - }); |
637 |
| - }); |
638 | 333 | }
|
0 commit comments