fix: navigation is more consistant
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
|
extension AppNavigation on BuildContext {
|
||||||
|
void popOrGo(String fallbackLocation) {
|
||||||
|
if (canPop()) {
|
||||||
|
pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
go(fallbackLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,13 +53,13 @@ class _BarScreenViewState extends State<BarScreenView> {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: l10n.manageProducts,
|
tooltip: l10n.manageProducts,
|
||||||
onPressed: () => context.go('/products'),
|
onPressed: () => context.push('/products'),
|
||||||
icon: const Icon(Icons.inventory_2_outlined),
|
icon: const Icon(Icons.inventory_2_outlined),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: l10n.tabHistory,
|
tooltip: l10n.tabHistory,
|
||||||
onPressed: () => context.go('/history'),
|
onPressed: () => context.push('/history'),
|
||||||
icon: const Icon(Icons.history_rounded),
|
icon: const Icon(Icons.history_rounded),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
@@ -71,7 +71,7 @@ class _BarScreenViewState extends State<BarScreenView> {
|
|||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: l10n.settings,
|
tooltip: l10n.settings,
|
||||||
onPressed: () => context.go('/settings'),
|
onPressed: () => context.push('/settings'),
|
||||||
icon: const Icon(Icons.settings),
|
icon: const Icon(Icons.settings),
|
||||||
),
|
),
|
||||||
if (context.watch<PinLockViewModel>().isPinSet) ...[
|
if (context.watch<PinLockViewModel>().isPinSet) ...[
|
||||||
@@ -230,7 +230,7 @@ class _ProductGrid extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
onPressed: () => context.go('/products/new'),
|
onPressed: () => context.push('/products/new'),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: Text(l10n.addProduct),
|
label: Text(l10n.addProduct),
|
||||||
),
|
),
|
||||||
@@ -324,7 +324,7 @@ class _ProductGrid extends StatelessWidget {
|
|||||||
enabled: hasSelectedTab,
|
enabled: hasSelectedTab,
|
||||||
onTap: () => onProductTap(product),
|
onTap: () => onProductTap(product),
|
||||||
onLongPress: () =>
|
onLongPress: () =>
|
||||||
context.go('/products/${product.id}/edit'),
|
context.push('/products/${product.id}/edit'),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../utils/app_update_util.dart';
|
import '../utils/app_update_util.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
import '../viewmodels/dev_menu_view_model.dart';
|
import '../viewmodels/dev_menu_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../l10n/app_localizations_helpers.dart';
|
import '../l10n/app_localizations_helpers.dart';
|
||||||
@@ -58,7 +59,7 @@ class _DevMenuViewState extends State<DevMenuView> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
onPressed: () => context.pop(),
|
onPressed: () => context.popOrGo('/bar'),
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
),
|
),
|
||||||
title: Text(l10n.devMenu),
|
title: Text(l10n.devMenu),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
|
|
||||||
class ErrorScreenView extends StatelessWidget {
|
class ErrorScreenView extends StatelessWidget {
|
||||||
const ErrorScreenView({super.key});
|
const ErrorScreenView({super.key});
|
||||||
@@ -14,7 +15,7 @@ class ErrorScreenView extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
onPressed: () => context.pop(),
|
onPressed: () => context.popOrGo('/bar'),
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
),
|
),
|
||||||
title: Text(l10n.errorScreen),
|
title: Text(l10n.errorScreen),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:kooltab2/views/widgets/closed_tab_card.dart';
|
import 'package:kooltab2/views/widgets/closed_tab_card.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../app/router.dart';
|
import '../app/router.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
import '../viewmodels/history_view_model.dart';
|
import '../viewmodels/history_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../l10n/app_localizations_helpers.dart';
|
import '../l10n/app_localizations_helpers.dart';
|
||||||
@@ -61,16 +61,11 @@ class _HistoryScreenViewState extends State<HistoryScreenView> with RouteAware {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Row(
|
leading: IconButton(
|
||||||
children: [
|
onPressed: () => context.popOrGo('/bar'),
|
||||||
IconButton(
|
icon: const Icon(Icons.arrow_back),
|
||||||
onPressed: () => context.go('/bar'),
|
|
||||||
icon: const Icon(Icons.arrow_back),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
Text(l10n.tabHistory),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
title: Text(l10n.tabHistory),
|
||||||
actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
|
actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@@ -12,6 +11,7 @@ import '../models/product.dart';
|
|||||||
import '../viewmodels/product_list_view_model.dart';
|
import '../viewmodels/product_list_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../l10n/app_localizations_helpers.dart';
|
import '../l10n/app_localizations_helpers.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
|
|
||||||
class ProductFormView extends StatefulWidget {
|
class ProductFormView extends StatefulWidget {
|
||||||
final String? productId;
|
final String? productId;
|
||||||
@@ -70,7 +70,7 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
context,
|
context,
|
||||||
).showSnackBar(SnackBar(content: Text(l10n.productNotFound)));
|
).showSnackBar(SnackBar(content: Text(l10n.productNotFound)));
|
||||||
|
|
||||||
context.go('/products');
|
_leaveProductForm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,10 +90,14 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(
|
||||||
context,
|
context,
|
||||||
).showSnackBar(SnackBar(content: Text(l10n.couldNotLoadProduct)));
|
).showSnackBar(SnackBar(content: Text(l10n.couldNotLoadProduct)));
|
||||||
context.go('/products');
|
_leaveProductForm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _leaveProductForm() {
|
||||||
|
context.popOrGo('/products');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
@@ -214,7 +218,7 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
setState(() => _isSaving = false);
|
setState(() => _isSaving = false);
|
||||||
context.go('/products');
|
_leaveProductForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _delete() async {
|
Future<void> _delete() async {
|
||||||
@@ -241,7 +245,7 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (confirmed != true) return;
|
if (confirmed != true || !mounted) return;
|
||||||
|
|
||||||
final viewModel = context.read<ProductListViewModel>();
|
final viewModel = context.read<ProductListViewModel>();
|
||||||
|
|
||||||
@@ -258,7 +262,7 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
context.go('/products');
|
_leaveProductForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildImagePicker(BuildContext context) {
|
Widget _buildImagePicker(BuildContext context) {
|
||||||
@@ -328,7 +332,7 @@ class _ProductFormViewState extends State<ProductFormView> {
|
|||||||
title: Text(title),
|
title: Text(title),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
onPressed: () => context.go('/products'),
|
onPressed: _leaveProductForm,
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
if (widget.isEditing)
|
if (widget.isEditing)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
|
|||||||
import '../viewmodels/product_list_view_model.dart';
|
import '../viewmodels/product_list_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../l10n/app_localizations_helpers.dart';
|
import '../l10n/app_localizations_helpers.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
|
|
||||||
class ProductListView extends StatefulWidget {
|
class ProductListView extends StatefulWidget {
|
||||||
const ProductListView({super.key});
|
const ProductListView({super.key});
|
||||||
@@ -32,20 +33,15 @@ class _ProductListViewState extends State<ProductListView> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Row(
|
leading: IconButton(
|
||||||
children: [
|
onPressed: () => context.popOrGo('/bar'),
|
||||||
IconButton(
|
icon: const Icon(Icons.arrow_back),
|
||||||
onPressed: () => context.go('/bar'),
|
|
||||||
icon: const Icon(Icons.arrow_back),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(l10n.products),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
title: Text(l10n.products),
|
||||||
),
|
),
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
onPressed: () => context.go('/products/new'),
|
onPressed: () => context.push('/products/new'),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: Text(l10n.addProduct),
|
label: Text(l10n.addProduct),
|
||||||
),
|
),
|
||||||
@@ -102,7 +98,7 @@ class _ProductListViewState extends State<ProductListView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
onTap: () => context.go('/products/${product.id}/edit'),
|
onTap: () => context.push('/products/${product.id}/edit'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:sentry_flutter/sentry_flutter.dart';
|
|||||||
|
|
||||||
import '../models/settings.dart';
|
import '../models/settings.dart';
|
||||||
import '../utils/app_update_util.dart';
|
import '../utils/app_update_util.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
import '../viewmodels/pin_lock_view_model.dart';
|
import '../viewmodels/pin_lock_view_model.dart';
|
||||||
import '../viewmodels/settings_view_model.dart';
|
import '../viewmodels/settings_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
@@ -197,16 +198,11 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Row(
|
leading: IconButton(
|
||||||
children: [
|
onPressed: () => context.popOrGo('/bar'),
|
||||||
IconButton(
|
icon: const Icon(Icons.arrow_back),
|
||||||
onPressed: () => context.go('/bar'),
|
|
||||||
icon: const Icon(Icons.arrow_back),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
Text(l10n.settingsTitle),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
title: Text(l10n.settingsTitle),
|
||||||
),
|
),
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
|
|
||||||
import '../utils/app_update_util.dart';
|
import '../utils/app_update_util.dart';
|
||||||
|
import '../utils/navigation.dart';
|
||||||
import '../viewmodels/update_progress_view_model.dart';
|
import '../viewmodels/update_progress_view_model.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../l10n/app_localizations_helpers.dart';
|
import '../l10n/app_localizations_helpers.dart';
|
||||||
@@ -60,7 +60,7 @@ class _UpdateProgressViewState extends State<UpdateProgressView> {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
this.context.go('/bar');
|
this.context.popOrGo('/bar');
|
||||||
},
|
},
|
||||||
child: Text(l10n.later),
|
child: Text(l10n.later),
|
||||||
),
|
),
|
||||||
@@ -104,40 +104,46 @@ class _UpdateProgressViewState extends State<UpdateProgressView> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = AppLocalizations.of(context);
|
final l10n = AppLocalizations.of(context);
|
||||||
|
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
appBar: AppBar(
|
canPop: false,
|
||||||
leading: IconButton(
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
icon: const Icon(Icons.close),
|
if (!didPop) _showCancelDialog();
|
||||||
onPressed: () => _showCancelDialog(),
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Icons.close),
|
||||||
|
onPressed: () => _showCancelDialog(),
|
||||||
|
),
|
||||||
|
title: Text(l10n.updating),
|
||||||
|
centerTitle: true,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
),
|
),
|
||||||
title: Text(l10n.updating),
|
body: ListenableBuilder(
|
||||||
centerTitle: true,
|
listenable: _vm,
|
||||||
automaticallyImplyLeading: false,
|
builder: (context, child) {
|
||||||
),
|
return Center(
|
||||||
body: ListenableBuilder(
|
child: ConstrainedBox(
|
||||||
listenable: _vm,
|
constraints: const BoxConstraints(maxWidth: 480),
|
||||||
builder: (context, child) {
|
child: Padding(
|
||||||
return Center(
|
padding: const EdgeInsets.all(32),
|
||||||
child: ConstrainedBox(
|
child: Column(
|
||||||
constraints: const BoxConstraints(maxWidth: 480),
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: Padding(
|
children: [
|
||||||
padding: const EdgeInsets.all(32),
|
_buildHeader(),
|
||||||
child: Column(
|
const SizedBox(height: 40),
|
||||||
mainAxisSize: MainAxisSize.min,
|
_buildProgress(_vm),
|
||||||
children: [
|
const SizedBox(height: 24),
|
||||||
_buildHeader(),
|
_buildStatus(_vm),
|
||||||
const SizedBox(height: 40),
|
const Spacer(),
|
||||||
_buildProgress(_vm),
|
_buildVersionInfo(_vm),
|
||||||
const SizedBox(height: 24),
|
],
|
||||||
_buildStatus(_vm),
|
),
|
||||||
const Spacer(),
|
|
||||||
_buildVersionInfo(_vm),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -298,7 +304,7 @@ class _UpdateProgressViewState extends State<UpdateProgressView> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
_vm.cancel();
|
_vm.cancel();
|
||||||
this.context.go('/bar');
|
this.context.popOrGo('/bar');
|
||||||
},
|
},
|
||||||
child: Text(l10n.cancelUpdateAction),
|
child: Text(l10n.cancelUpdateAction),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:kooltab2/l10n/app_localizations.dart';
|
||||||
|
import 'package:kooltab2/models/product.dart';
|
||||||
|
import 'package:kooltab2/views/widgets/product_tile.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('long-pressing a product tile returns to the bar after edit', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
final product = Product(
|
||||||
|
id: 'product-1',
|
||||||
|
name: 'Cola',
|
||||||
|
category: 'Drinks',
|
||||||
|
stockQuantity: 5,
|
||||||
|
lowStockThreshold: 1,
|
||||||
|
priceInCents: 250,
|
||||||
|
);
|
||||||
|
|
||||||
|
final router = GoRouter(
|
||||||
|
initialLocation: '/bar',
|
||||||
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: '/bar',
|
||||||
|
builder: (context, state) => Scaffold(
|
||||||
|
body: ProductTile(
|
||||||
|
product: product,
|
||||||
|
enabled: false,
|
||||||
|
onTap: () {},
|
||||||
|
onLongPress: () => context.push('/products/${product.id}/edit'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/products',
|
||||||
|
builder: (context, state) => const Scaffold(body: Text('Products')),
|
||||||
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: ':id/edit',
|
||||||
|
builder: (context, state) =>
|
||||||
|
const Scaffold(body: Text('Edit product')),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp.router(
|
||||||
|
routerConfig: router,
|
||||||
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
await tester.longPress(find.byType(ProductTile));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.text('Edit product'), findsOneWidget);
|
||||||
|
|
||||||
|
router.pop();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byType(ProductTile), findsOneWidget);
|
||||||
|
expect(find.text('Edit product'), findsNothing);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user