diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 9803dde4..b67c9085 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -12,6 +12,7 @@ import 'package:go_router/go_router.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; import 'package:hub/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart'; import 'package:hub/features/backend/api_requests/index.dart'; import 'package:hub/features/local/index.dart'; @@ -25,6 +26,8 @@ import 'package:hub/flutter_flow/index.dart'; import 'package:hub/initialization.dart'; import 'package:hub/main.dart'; import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; import 'package:integration_test/integration_test.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:patrol/patrol.dart'; @@ -49,6 +52,7 @@ part 'setting_test.dart'; part 'storage_test.dart'; part 'utils_test.dart'; part 'welcome_test.dart'; +part 'vehicle_test.dart'; late PatrolIntegrationTester $; @@ -76,4 +80,9 @@ void main() { // LocalsTest.setLocal(); // LocalsTest.unlinkLocal(); + + VehicleTest.vehiclePage(); + VehicleTest.historyScreen(); + VehicleTest.registerScreen(); + VehicleTest.updateScreen(); } diff --git a/integration_test/vehicle_test.dart b/integration_test/vehicle_test.dart new file mode 100644 index 00000000..f96e8580 --- /dev/null +++ b/integration_test/vehicle_test.dart @@ -0,0 +1,132 @@ +part of 'app_test.dart'; + +class VehicleTest { + static Future vehiclePage() async { + patrol( + 'Vehicle Page', + (PatrolIntegrationTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Page'); + final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); + + await _loggedWithMultiLocalsAccount($); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + + final String title = MenuEntry.entries // + .where((entry) => entry.key == 'FRE-HUB-VEHICLES') // + .map((entry) => entry.name) + .first; + + final PatrolFinder appBar = await $(AppBar) // + .waitUntilExists(); + final PatrolFinder titleAppBar = await appBar // + .$(title) + .waitUntilVisible(); + expect(titleAppBar, findsOneWidget); + + final PatrolFinder tab1 = await $(#TabView_Tab1) // + .waitUntilExists(); + final PatrolFinder tab2 = await $(#TabView_Tab2) // + .waitUntilExists(); + + await tab2.tap(); + await Future.delayed(const Duration(milliseconds: 500)); + await tab1.tap(); + + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = + await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + final int entriesCount = entriesFinder.evaluate().length; + await $.pumpAndSettle(); + + for (int i = 0; i < entriesCount; i++) { + await $(entriesFinder.at(i)).scrollTo(); + + await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); + + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); + + await $.native.pressBack().then((_) => $.pumpAndSettle()); + } + }, + ); + } + + static Future historyScreen() async { + patrol( + 'historyScreen', + (PatrolIntegrationTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Page'); + final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); + + await _loggedWithMultiLocalsAccount($); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + + final String title = MenuEntry.entries // + .where((entry) => entry.key == 'FRE-HUB-VEHICLES') // + .map((entry) => entry.name) + .first; + + final PatrolFinder appBar = await $(AppBar) // + .waitUntilExists(); + final PatrolFinder titleAppBar = await appBar // + .$(title) + .waitUntilVisible(); + expect(titleAppBar, findsOneWidget); + + final PatrolFinder tab2 = await $(#TabView_Tab2) // + .waitUntilExists(); + + await tab2.tap(); + + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = + await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + final int entriesCount = entriesFinder.evaluate().length; + await $.pumpAndSettle(); + + for (int i = 0; i < entriesCount; i++) { + await $(entriesFinder.at(i)).scrollTo(); + + await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); + + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); + + await $.native.pressBack().then((_) => $.pumpAndSettle()); + } + }, + ); + } + + static Future registerScreen() async {} + static Future updateScreen() async {} +} diff --git a/lib/components/atomic_components/shared_components_atoms/tabview.dart b/lib/components/atomic_components/shared_components_atoms/tabview.dart index 8a62cbf3..8fe92916 100644 --- a/lib/components/atomic_components/shared_components_atoms/tabview.dart +++ b/lib/components/atomic_components/shared_components_atoms/tabview.dart @@ -41,17 +41,18 @@ class TabViewUtil extends StatelessWidget { fontFamily: FlutterFlowTheme.of(context).titleMediumFamily, fontSize: LimitedFontSizeUtil.getBodyFontSize(context), letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).titleMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).titleMediumFamily), ), unselectedLabelStyle: const TextStyle(), indicatorColor: FlutterFlowTheme.of(context).primary, padding: const EdgeInsets.all(4.0), tabs: [ Tab( + key: ValueKey('TabView_Tab1'), text: labelTab1, ), Tab( + key: ValueKey('TabView_Tab2'), text: labelTab2, ), ], diff --git a/lib/features/home/presentation/pages/home_page.dart b/lib/features/home/presentation/pages/home_page.dart index 3963a497..c8571947 100644 --- a/lib/features/home/presentation/pages/home_page.dart +++ b/lib/features/home/presentation/pages/home_page.dart @@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:hub/features/home/presentation/widgets/drawer_widget.dart'; import 'package:hub/features/local/index.dart'; import 'package:hub/features/menu/index.dart'; +import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; @@ -16,8 +17,7 @@ class HomePageWidget extends StatefulWidget { State createState() => _HomePageWidgetState(); } -class _HomePageWidgetState extends State - with WidgetsBindingObserver { +class _HomePageWidgetState extends State with WidgetsBindingObserver { final scaffoldKey = GlobalKey(); @override @@ -25,6 +25,15 @@ class _HomePageWidgetState extends State super.initState(); WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addPostFrameCallback((_) async { + final email = await StorageHelper().get(SecureStorageKey.email.value); + final pass = await StorageHelper().get(SecureStorageKey.password.value); + final cli = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final owner = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); + print('Email: $email'); + print('Password: $pass'); + print('Client: $cli'); + print('Owner: $owner'); + await LocalsRepositoryImpl().check(context); if (widget.update != null) { await widget.update!(context); @@ -97,8 +106,7 @@ class _HomePageWidgetState extends State fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, color: FlutterFlowTheme.of(context).info, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), ), ), ].divide(const SizedBox(width: 8.0)), diff --git a/lib/features/local/data/data_sources/locals_remote_data_source.dart b/lib/features/local/data/data_sources/locals_remote_data_source.dart index fd91b648..0babde3a 100644 --- a/lib/features/local/data/data_sources/locals_remote_data_source.dart +++ b/lib/features/local/data/data_sources/locals_remote_data_source.dart @@ -24,8 +24,7 @@ abstract class LocalsRemoteDataSource { } class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { - static final LocalsRemoteDataSourceImpl _instance = - LocalsRemoteDataSourceImpl._internal(); + static final LocalsRemoteDataSourceImpl _instance = LocalsRemoteDataSourceImpl._internal(); factory LocalsRemoteDataSourceImpl() => _instance; LocalsRemoteDataSourceImpl._internal(); @@ -51,8 +50,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final List locals = response.jsonBody['locais'] ?? []; final bool isEmpty = locals.isEmpty; - final bool isActive = - locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; + final bool isActive = locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; final bool isEnable = !isEmpty && isActive; if (isEnable) { @@ -97,8 +95,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final bool isInactived = await LocalUtil.isInactived(locals); final bool isPending = LocalUtil.isPending(locals); final bool isUnique = locals.length == 1; - final bool isBlocked = - locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; + final bool isBlocked = locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; final bool isEnabled = isUnique && isActive; final bool isDisabled = isUnique && isBlocked; final bool isUnselected = await LocalUtil.isUnselected(); @@ -151,11 +148,11 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { @override Future checkLocals(BuildContext context) async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = - (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; - return cliUUID.isEmpty && cliName.isEmpty; + final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? cliName = await StorageHelper().get(ProfileStorageKey.clientName.key); + final haveCli = cliUUID != null && cliUUID.isNotEmpty; + final haveName = cliName != null && cliName.isNotEmpty; + return haveCli && haveName; } @override @@ -178,8 +175,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { if (isError == true) { final GetLocalsCall callback = PhpGroup.getLocalsCall; response = await callback.call(); - final String errorMsg = - response.jsonBody['error_msg'] ?? 'Local indisponível'; + final String errorMsg = response.jsonBody['error_msg'] ?? 'Local indisponível'; // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); return false; } else { @@ -198,8 +194,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { } @override - Future selectLocal( - BuildContext context, ApiCallResponse? response) async { + Future selectLocal(BuildContext context, ApiCallResponse? response) async { return await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, @@ -229,15 +224,13 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { enText: 'Device unlinked successfully', ptText: 'Dispositivo desvinculado com sucesso', ); - final bool status = - await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { + final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { if (value.jsonBody['error'] == false) { await StorageHelper().set(ProfileStorageKey.clientName.key, ''); await StorageHelper().set(ProfileStorageKey.ownerName.key, ''); await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); context.pop(); - context.go('/homePage', - extra: {'update': LocalsRepositoryImpl().update}); + context.go('/homePage', extra: {'update': LocalsRepositoryImpl().update}); SnackBarUtil.showSnackBar(context, content); return true; } diff --git a/lib/features/local/data/repositories/locals_repository_impl.dart b/lib/features/local/data/repositories/locals_repository_impl.dart index 232e511e..ea37e12e 100644 --- a/lib/features/local/data/repositories/locals_repository_impl.dart +++ b/lib/features/local/data/repositories/locals_repository_impl.dart @@ -49,13 +49,12 @@ class LocalsRepositoryImpl implements LocalsRepository { } Future check(BuildContext context) async { - final String? cliUUID = - await StorageHelper().get(ProfileStorageKey.clientUUID.key); - final String? ownerUUID = - await StorageHelper().get(ProfileStorageKey.ownerUUID.key); + final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? ownerUUID = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); final bool haveCli = cliUUID != null && cliUUID.isNotEmpty; final bool haveOwner = ownerUUID != null && ownerUUID.isNotEmpty; if (!haveCli && !haveOwner) { + log('No client or owner selected'); await update(context); await FirebaseMessagingService().updateDeviceToken(); } @@ -64,7 +63,8 @@ class LocalsRepositoryImpl implements LocalsRepository { Future _handleLocal(BuildContext context) async { bool response = false; final bool isUnselected = await remoteDataSource.checkLocals(context); - if (isUnselected) { + if (!isUnselected) { + log('_handleLocal -> No local selected'); while (!response) { try { response = await remoteDataSource.processLocals(context); @@ -77,6 +77,7 @@ class LocalsRepositoryImpl implements LocalsRepository { } } } else { + log('_handleLocal -> Local selected'); return true; } diff --git a/lib/pages/vehicles_on_the_property/index.dart b/lib/pages/vehicles_on_the_property/index.dart new file mode 100644 index 00000000..f159a317 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/index.dart @@ -0,0 +1,2 @@ +export 'vehicles_on_the_property.dart'; +export 'vehicle_model.dart'; diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index e78b7773..2f087c22 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -78,7 +78,7 @@ class _VehiclePageState extends State with TickerProviderStateMixin Widget _buildBody(BuildContext context) { final vehicleHistoryScreenLabel = - FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'Consult'); + FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'History'); final vehicleRegisterScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'); final vehicleUpdateScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit');