Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[go_router_builder]: Handle invaild params #8405

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2.7.4

- Fixes an issue when navigate to router with invalid params

## 2.7.3

Expand Down
36 changes: 36 additions & 0 deletions packages/go_router_builder/example/lib/all_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'shared/data.dart';
part 'all_types.g.dart';

@TypedGoRoute<AllTypesBaseRoute>(path: '/', routes: <TypedGoRoute<GoRouteData>>[
TypedGoRoute<InvalidPageRoute>(path: 'invalid-page'),
CaoGiaHieu-dev marked this conversation as resolved.
Show resolved Hide resolved
TypedGoRoute<BigIntRoute>(path: 'big-int-route/:requiredBigIntField'),
TypedGoRoute<BoolRoute>(path: 'bool-route/:requiredBoolField'),
TypedGoRoute<DateTimeRoute>(path: 'date-time-route/:requiredDateTimeField'),
Expand Down Expand Up @@ -39,6 +40,22 @@ class AllTypesBaseRoute extends GoRouteData {
);
}

class InvalidPageRoute extends GoRouteData {
InvalidPageRoute();

@override
Widget build(BuildContext context, GoRouterState state) => InvalidPage(
dataTitle: 'InvalidPage',
queryParamWithDefaultValue: state.uri.queryParameters,
);

Widget drawerTile(BuildContext context) => ListTile(
title: const Text('InvalidPage'),
onTap: () => go(context),
selected: GoRouterState.of(context).uri.path == location,
);
}

class BigIntRoute extends GoRouteData {
BigIntRoute({
required this.requiredBigIntField,
Expand Down Expand Up @@ -629,3 +646,22 @@ class IterablePage extends StatelessWidget {
);
}
}

class InvalidPage extends StatelessWidget {
const InvalidPage({
super.key,
required this.dataTitle,
this.queryParamWithDefaultValue,
});

final String dataTitle;
final Map<String, dynamic>? queryParamWithDefaultValue;

@override
Widget build(BuildContext context) {
return BasePage<String>(
dataTitle: dataTitle,
queryParamWithDefaultValue: queryParamWithDefaultValue.toString(),
);
}
}
312 changes: 202 additions & 110 deletions packages/go_router_builder/example/lib/all_types.g.dart

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions packages/go_router_builder/example/lib/main.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions packages/go_router_builder/example/lib/simple_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ class FamilyRoute extends GoRouteData {
final String familyId;

@override
Widget build(BuildContext context, GoRouterState state) =>
FamilyScreen(family: familyById(familyId));
Widget build(BuildContext context, GoRouterState state) {
return FamilyScreen(family: familyById(familyId));
}
}

class HomeScreen extends StatelessWidget {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 71 additions & 0 deletions packages/go_router_builder/example/test/all_types_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_builder_example/all_types.dart';
import 'package:go_router_builder_example/shared/data.dart';

Expand Down Expand Up @@ -221,4 +222,74 @@ void main() {
);
expect(find.text('/iterable-route-with-default-values'), findsOneWidget);
});

testWidgets(
'Test navigation with invalid query and path parameters using Uri.parse',
(WidgetTester tester) async {
await tester.pumpWidget(AllTypesApp());

final ScaffoldState scaffoldState =
tester.firstState(find.byType(Scaffold));

// Test invalid BigInt parameter
scaffoldState.context
.go(Uri.parse('/big-int-route/4?bigIntField=invalid').toString());
await tester.pumpAndSettle();
expect(find.text('BigIntRoute'), findsOneWidget);
expect(find.text('Param: 4'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);

// Test invalid DateTime parameter
scaffoldState.context.go(Uri.parse(
'/date-time-route/2021-01-01T00:00:00.000?dateTimeField=invalid-date')
.toString());
await tester.pumpAndSettle();
expect(find.text('DateTimeRoute'), findsOneWidget);
expect(find.text('Param: 2021-01-01 00:00:00.000'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);

// Test invalid Double parameter
scaffoldState.context
.go(Uri.parse('/double-route/3.14?doubleField=invalid').toString());
await tester.pumpAndSettle();
expect(find.text('DoubleRoute'), findsOneWidget);
expect(find.text('Param: 3.14'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);
expect(find.text('Query param with default value: 1.0'), findsOneWidget);

// Test invalid Int parameter
scaffoldState.context
.go(Uri.parse('/int-route/65?intField=invalid').toString());
await tester.pumpAndSettle();
expect(find.text('IntRoute'), findsOneWidget);
expect(find.text('Param: 65'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);
expect(find.text('Query param with default value: 1'), findsOneWidget);

// Test invalid Uri parameter
scaffoldState.context.go(
Uri.parse('/uri-route/https%3A%2F%2Fdart.dev?uriField=invalid-uri')
.toString());
await tester.pumpAndSettle();
expect(find.text('UriRoute'), findsOneWidget);
expect(find.text('Param: https://dart.dev'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);

// Test invalid Enum parameter
scaffoldState.context.go(
Uri.parse('/enum-route/favorite-food?enum-field=invalid').toString());
await tester.pumpAndSettle();
expect(find.text('EnumRoute'), findsOneWidget);
expect(find.text('Query param: null'), findsOneWidget);
expect(
find.text('Query param with default value: PersonDetails.favoriteFood'),
findsOneWidget);

// Test invalid Iterable parameter
scaffoldState.context
.go(Uri.parse('/iterable-route?intListField=invalid').toString());
await tester.pumpAndSettle();
expect(find.text('IterableRoute'), findsOneWidget);
expect(find.text('/iterable-route'), findsOneWidget);
});
}
6 changes: 3 additions & 3 deletions packages/go_router_builder/lib/src/route_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ const String _convertMapValueHelper = '''
T? $convertMapValueHelperName<T>(
String key,
Map<String, String> map,
T Function(String) converter,
T? Function(String) converter,
) {
final value = map[key];
return value == null ? null : converter(value);
Expand All @@ -762,6 +762,6 @@ bool $boolConverterHelperName(String value) {

const String _enumConverterHelper = '''
extension<T extends Enum> on Map<T, String> {
T $enumExtensionHelperName(String value) =>
entries.singleWhere((element) => element.value == value).key;
T? $enumExtensionHelperName(String value) =>
entries.where((element) => element.value == value).firstOrNull?.key;
}''';
Loading
Loading