This commit is contained in:
J. A. Messias 2025-01-10 09:38:25 -03:00
parent 8ae8ce849f
commit 08016c53b8
46 changed files with 16739 additions and 191 deletions

View File

@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
android { android {
namespace 'com.freaccess.hub' namespace 'com.freaccess.hub'
compileSdkVersion 34 compileSdkVersion 34
compileSdk 34 compileSdk 35
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
@ -53,8 +53,10 @@ android {
versionName flutterVersionName versionName flutterVersionName
multiDexEnabled true multiDexEnabled true
consumerProguardFiles 'proguard-rules.pro' consumerProguardFiles 'proguard-rules.pro'
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
@ -73,7 +75,7 @@ android {
storePassword keystoreProperties['storePassword'] storePassword keystoreProperties['storePassword']
} }
debug { debug {
} }
} }
@ -106,7 +108,7 @@ dependencies {
implementation 'androidx.window:window:1.0.0' implementation 'androidx.window:window:1.0.0'
implementation 'androidx.window:window-java:1.0.0' implementation 'androidx.window:window-java:1.0.0'
implementation 'com.google.mlkit:face-detection:16.1.7' implementation 'com.google.mlkit:face-detection:16.1.7'
implementation ('com.google.firebase:firebase-messaging:24.0.0') { implementation('com.google.firebase:firebase-messaging:24.0.0') {
exclude group: 'com.google.firebase', module: 'firebase-iid' exclude group: 'com.google.firebase', module: 'firebase-iid'
} }
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'

15496
coverage/lcov.info Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.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/features/backend/api_requests/index.dart';
import 'package:hub/features/menu/index.dart';
import 'package:hub/features/module/data/index.dart';
import 'package:hub/features/module/domain/index.dart';
import 'package:hub/features/storage/enums/index.dart';
import 'package:hub/features/storage/repositories/storage_repository_impl.dart';
import 'package:hub/flutter_flow/index.dart' as ff;
import 'package:hub/initialization.dart';
import 'package:hub/main.dart';
import 'package:integration_test/integration_test.dart';
import 'package:material_symbols_icons/symbols.dart';
part 'auth_test.dart';
part 'home_test.dart';
part 'locals_test.dart';
part 'menu_test.dart';
part 'module_test.dart';
part 'notify_test.dart';
part 'profile_test.dart';
part 'property_test.dart';
part 'setting_test.dart';
part 'storage_test.dart';
part 'utils_test.dart';
part 'welcome_test.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
// WelcomeTest.signInToSignUp();
// WelcomeTest.signUpToSignIn();
//
// AuthenticationTest.signIn();
// AuthenticationTest.signUp();
// AuthenticationTest.signOut();
// ModularizationTest.switchLicense();
// ModularizationTest.containLicense();
//
// MenuTest.navToEntries();
// MenuTest.containEntries();
// MenuTest.labels2AppbarConsistency();
//
// LocalsTest.setLocal();
// LocalsTest.unlinkLocal();
}

View File

@ -0,0 +1,145 @@
part of 'app_test.dart';
class AuthenticationTest {
static Future signIn() async {
_setUpUnlogged();
testWidgets('Sign-In with erro@exemplo.com', //
(WidgetTester tester) async {
await tester.pumpWidget(const App());
tester.printToConsole('AuthenticationTest - Navigate Sign-In');
await _navigateToSignIn(tester);
await _auth({
'emailTextFormField': 'erro@exemplo.com',
'passwordTextFormField': '12345678'
}, tester);
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
_setUpUnlogged();
testWidgets('Sign-In with email_app@exemplo.com',
(WidgetTester tester) async {
await tester.pumpWidget(const App());
tester.printToConsole('AuthenticationTest - Navigate Sign-In');
await _navigateToSignIn(tester);
await _auth({
'emailTextFormField': 'email_app@exemplo.com',
'passwordTextFormField': '12345678'
}, tester);
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
static Future signUp() async {
_setUpUnlogged();
testWidgets('Sign Up - credenciais já registradas',
(WidgetTester tester) async {
var credentials = {
'nameTextFormField': 'app',
'emailTextFormField': 'email_app@exemplo.com',
'passwordTextFormField': '12345678'
};
await tester.pumpWidget(const App());
tester.printToConsole('AuthenticationTest - Navigate Sign-Up');
await _navigateToSignUp(tester);
await _auth(credentials, tester);
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
_setUpUnlogged();
testWidgets('Sign Up - credenciais novas', //
(WidgetTester tester) async {
late Map<String, String> credentials;
var name = ff.randomString(7, 7, true, true, true);
var email = '$name@example.com';
var password = '12345678';
credentials = {
'nameTextFormField': name,
'emailTextFormField': email,
'passwordTextFormField': password
};
await tester.pumpWidget(const App());
tester.printToConsole('AuthenticationTest - Navigate Sign-Up');
await _navigateToSignUp(tester);
await _auth(credentials, tester);
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
static Future signOut() async {
_setUpLogged();
testWidgets('Deslogar da Conta', (WidgetTester tester) async {
await tester.pumpWidget(const App());
final Finder drawerButton = find.byIcon(Icons.menu_rounded);
await tester.pumpAndSettle();
await tester.tap(drawerButton);
await tester.pumpAndSettle();
final Finder signOutButton = find.byIcon(Icons.exit_to_app);
await tester.pumpAndSettle();
await tester.tap(signOutButton);
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
static Future recovery() async {}
}
Future<void> _auth(
Map<String, dynamic> credentials, WidgetTester tester) async {
await _enterCredentials(credentials, tester);
await _submit('SubmitButtonWidget', tester);
}
Future<void> _send(
Map<String, dynamic> credentials, WidgetTester tester) async {
await _enterCredentials(credentials, tester);
await _submit('SendButtonWidget', tester);
}
Future<void> _enterCredentials(
Map<String, dynamic> credentials, WidgetTester tester) async {
await tester.pumpAndSettle();
for (var entry in credentials.entries) {
final Finder field = find.byKey(ValueKey<String>(entry.key));
await tester.pumpAndSettle();
expect(field, findsOneWidget);
await tester.enterText(field, entry.value);
await tester.pumpAndSettle();
}
await tester.pumpAndSettle();
}
Future<void> _submit(String key, WidgetTester tester) async {
await tester.pumpAndSettle();
final Finder submitButton = find.byKey(ValueKey<String>(key));
await tester.pumpAndSettle();
if (submitButton.evaluate().isNotEmpty) {
await tester.tap(submitButton);
}
final Finder throwExceptionWidget =
find.byKey(const ValueKey<String>('ThrowExceptionWidget'));
if (throwExceptionWidget.evaluate().isNotEmpty) {
await tester.pumpAndSettle();
await tester.ensureVisible(throwExceptionWidget);
await tester.tap(throwExceptionWidget);
await tester.pumpAndSettle();
} else {
await _navigateBackUsingSystemGesture();
}
}

View File

@ -0,0 +1,11 @@
part of 'app_test.dart';
class homeTest {
static Future drawer() async {}
static Future header() async {}
static Future feed() async {}
static Future isLogged() async {}
}

View File

@ -0,0 +1,171 @@
part of 'app_test.dart';
class LocalsTest {
static Future setLocal() async {
_setUpLogged();
testWidgets('Selecionar um local disponível', //
(WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
final Finder profileFinder =
find.byKey(const Key('AsyncLocalProfileComponentWidget_InkWell'));
expect(profileFinder, findsOneWidget);
await tester.tap(profileFinder);
await tester.pump(const Duration(seconds: 1));
final Finder bottomSheetFinder =
find.byType(BottomArrowLinkedLocalsComponentWidget);
expect(bottomSheetFinder, findsOneWidget);
await tester.ensureVisible(bottomSheetFinder);
await tester.pump(const Duration(seconds: 1));
final Finder listViewFinder = find.descendant(
of: bottomSheetFinder,
matching: find.byType(ListView),
);
expect(listViewFinder, findsOneWidget);
await tester.ensureVisible(listViewFinder);
await tester.pump(const Duration(seconds: 1));
final Finder entriesFinder = find.descendant(
of: listViewFinder,
matching: find.byType(CardItemTemplateComponentWidget),
);
expect(entriesFinder, findsWidgets);
if (entriesFinder.evaluate().isNotEmpty) {
await tester.ensureVisible(entriesFinder.first);
await tester.tap(entriesFinder.first);
await tester.pumpAndSettle();
}
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
static Future unlinkLocal() async {
_setUpAllLogged();
testWidgets('Desvincular do local selecionado', //
(WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 1));
final Finder gridView = find.byType(GridView);
await tester.ensureVisible(gridView);
final Finder entries = find.descendant(
of: gridView,
matching: find.byType(ButtonMenuItem),
);
await tester.pumpAndSettle();
expect(entries, findsWidgets);
final Finder settings = find.descendant(
of: gridView,
matching: find.byIcon(Icons.settings),
);
expect(settings, findsOneWidget);
await tester.ensureVisible(settings);
await tester.tap(settings);
await tester.pumpAndSettle();
final Finder unlinkButton = find.byIcon(Symbols.digital_out_of_home);
expect(unlinkButton, findsOneWidget);
await tester.ensureVisible(unlinkButton);
await tester.tap(unlinkButton);
await tester.pumpAndSettle();
await tester.tap(find.text('Sim'));
await tester.pump();
await tester.pump(const Duration(seconds: 1));
await tester.pump();
final Finder bottomSheetFinder =
find.byType(BottomArrowLinkedLocalsComponentWidget);
await tester.pump(const Duration(seconds: 1));
expect(bottomSheetFinder, findsOneWidget);
await tester.pump(const Duration(seconds: 1));
await tester.ensureVisible(bottomSheetFinder);
await tester.pump(const Duration(seconds: 1));
final Finder listViewFinder = find.descendant(
of: bottomSheetFinder,
matching: find.byType(ListView),
);
expect(listViewFinder, findsOneWidget);
await tester.ensureVisible(listViewFinder);
await tester.pump(const Duration(seconds: 1));
final Finder entriesFinder = find.descendant(
of: listViewFinder,
matching: find.byType(CardItemTemplateComponentWidget),
);
expect(entriesFinder, findsWidgets);
await Future.delayed(const Duration(milliseconds: 500));
return;
});
testWidgets('Desvincular de um local já desvinculado', //
(WidgetTester tester) async {
await tester.pumpWidget(const App());
try {
await tester.pumpAndSettle(
const Duration(seconds: 2),
EnginePhase.sendSemanticsUpdate,
const Duration(seconds: 2),
);
throw Exception('Local está vinculado');
} catch (e) {
await Future.delayed(const Duration(milliseconds: 500));
return;
}
});
_tearDownAll();
}
static Future attachLocal() async {
_setUpAllLogged();
testWidgets('Selecionar um local disponível', //
(WidgetTester tester) async {
await tester.pumpWidget(const App());
late Map<String, String> credentials;
var name = ff.randomString(7, 7, true, true, true);
var email = '$name@example.com';
var password = '12345678';
credentials = {
'nameTextFormField': name,
'emailTextFormField': email,
'passwordTextFormField': password
};
await tester.pumpWidget(const App());
await _navigateToSignUp(tester);
await _auth(credentials, tester);
credentials = {
'emailTextFormField': email,
'passwordTextFormField': password
};
await _auth(credentials, tester);
await tester.pumpAndSettle();
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '7');
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDownAll();
}
}

View File

@ -0,0 +1,174 @@
part of 'app_test.dart';
class MenuTest {
static Future labels2AppbarConsistency() async {
_setUpAllLogged();
testWidgets('As labels dos menuItems correspondem aos títulos das AppBars?',
(WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
final List<String> routes = MenuEntry.entries
.where((entry) => entry.key != 'FRE-HUB-LOGOUT')
.map((entry) => entry.route)
.toList();
final List<String> titles = MenuEntry.entries
.where((entry) => entry.key != 'FRE-HUB-LOGOUT')
.map((entry) => entry.name)
.toList();
tester.printToConsole(routes.toString());
final LinkedHashMap<String, String> routesTitles =
LinkedHashMap.fromIterables(
routes,
titles,
);
for (final entry in routesTitles.entries) {
final String route = entry.key;
final String title = entry.value;
tester.printToConsole('Start: $title');
if (route == '/petsPage') continue;
if (route == '/fastPassPage') continue;
if (route == '/reservation') continue;
await tester.pumpAndSettle();
ff.navigatorKey.currentContext!.go(route);
await tester.pumpAndSettle();
Future.delayed(const Duration(milliseconds: 500));
final Finder appBar = find.text(title);
await tester.pumpAndSettle();
expect(appBar, findsOneWidget);
await tester.pumpAndSettle();
tester.printToConsole('Finish: $title');
}
await Future.delayed(const Duration(milliseconds: 500));
return;
});
}
static Future containEntries() async {
_setUpAllLogged();
testWidgets('HomeMenu contém seus itens?', (WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
await Future.delayed(const Duration(seconds: 1));
final Finder gridView = find.byType(GridView);
await tester.pumpAndSettle();
await tester.ensureVisible(gridView);
await tester.pumpAndSettle();
final Finder gridEntries = find.descendant(
of: gridView,
matching: find.byType(ButtonMenuItem),
);
await tester.pumpAndSettle();
expect(gridEntries, findsWidgets);
final List<String?> menuKeys = gridEntries
.evaluate()
.map((element) {
final key = element.widget.key;
if (key is ValueKey<String>) {
return key.value;
}
return null;
})
.where((key) => key != null)
.toList();
await tester.pumpAndSettle();
final List<MenuEntry> entries = MenuEntry.entries;
await tester.pumpAndSettle();
final List<String> entriesKey = entries
.where((entry) => entry.types.contains(MenuEntryType.Home))
.map((entry) => entry.key)
.toList();
await tester.pumpAndSettle();
expect(entriesKey, containsAll(menuKeys));
await Future.delayed(const Duration(milliseconds: 500));
return;
});
testWidgets('DrawerMenu contém seus itens?', (WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
await Future.delayed(const Duration(seconds: 1));
final Finder drawerButton = find.byIcon(Icons.menu_rounded);
await tester.pumpAndSettle();
await tester.tap(drawerButton);
await tester.pumpAndSettle();
final Finder gridView = find.byType(ListView);
await tester.pumpAndSettle();
await tester.ensureVisible(gridView);
await tester.pumpAndSettle();
final Finder gridEntries = find.descendant(
of: gridView,
matching: find.byType(CardMenuItem),
);
await tester.pumpAndSettle();
expect(gridEntries, findsWidgets);
final List<String?> menuKeys = gridEntries
.evaluate()
.map((element) {
final key = element.widget.key;
if (key is ValueKey<String>) {
return key.value;
}
return null;
})
.where((key) => key != null)
.toList();
await tester.pumpAndSettle();
final List<MenuEntry> entries = MenuEntry.entries;
await tester.pumpAndSettle();
final List<String> entriesKey = entries
.where((entry) => entry.types.contains(MenuEntryType.Drawer))
.map((entry) => entry.key)
.toList();
await tester.pumpAndSettle();
expect(entriesKey, containsAll(menuKeys));
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDownAll();
}
static Future navToEntries() async {
_setUpAllLogged();
testWidgets('Navegação entre items do Menu', (WidgetTester tester) async {
tester = tester;
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
final Finder gridView = find.byType(GridView);
await tester.ensureVisible(gridView);
final Finder gridEntries = find.descendant(
of: gridView,
matching: find.byType(ButtonMenuItem),
);
await tester.pumpAndSettle();
await Future.delayed(const Duration(seconds: 5));
expect(gridEntries, findsWidgets);
final int gridEntriesCount = gridEntries.evaluate().length;
for (int i = 0; i < gridEntriesCount; i++) {
await Future.delayed(const Duration(seconds: 1));
await tester.tap(gridEntries.at(i));
await tester.pumpAndSettle();
await Future.delayed(const Duration(seconds: 1));
await tester.tap(find.byIcon(Icons.keyboard_arrow_left));
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
}
});
_tearDownAll();
}
}

View File

@ -0,0 +1,50 @@
part of 'app_test.dart';
class ModularizationTest {
static Future containLicense() async {
_setUpLogged();
testWidgets('Os modulos de licença está sendo processados?',
(WidgetTester tester) async {
await tester.pumpWidget(const App());
await tester.pumpAndSettle();
await Future.delayed(const Duration(seconds: 1));
await tester.pumpAndSettle();
final LicenseRepository licenseRepository = LicenseRepositoryImpl();
final List<String> result = await licenseRepository.getLicense();
expect(result, isNotEmpty);
await tester.pumpAndSettle();
final List<MenuEntry> entries = MenuEntry.entries;
await tester.pumpAndSettle();
final List<String> entriesKey = entries
.where((entry) => entry.types.contains(MenuEntryType.Home))
.map((entry) => '{key: ${entry.key}}')
.toList();
await tester.pumpAndSettle();
expect(result, containsAll(entriesKey));
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
static Future switchLicense() async {
_setUpLogged();
testWidgets('Licença está sendo atualizada?', (WidgetTester tester) async {
await tester.pumpWidget(const App());
final Finder profile =
find.byKey(const Key('AsyncLocalProfileComponentWidget_InkWell'));
await tester.pumpAndSettle();
await tester.tap(profile);
await tester.pumpAndSettle();
final Finder local = find.text('FRE ACCESS DEMO');
await tester.pumpAndSettle();
await tester.tap(local);
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDown();
}
}

View File

@ -0,0 +1,3 @@
part of 'app_test.dart';
class notifyTest {}

View File

@ -0,0 +1,2 @@
class PatrolTest {
}

View File

@ -0,0 +1 @@
part of 'app_test.dart';

View File

@ -0,0 +1,3 @@
part of 'app_test.dart';
class propertyTest {}

View File

@ -0,0 +1,3 @@
part of 'app_test.dart';
class settingTest {}

View File

@ -0,0 +1,3 @@
part of 'app_test.dart';
class storageTest {}

View File

@ -0,0 +1,139 @@
part of 'app_test.dart';
Future<void> _setUpLogged() async {
setUp(() async {
await initializeApp();
await StorageHelper() //
.set(SecureStorageKey.isLogged.value, 'true');
await StorageHelper() //
.set(SecureStorageKey.haveLocal.value, 'true');
await StorageHelper() //
.set(ProfileStorageKey.devUUID.key, 'b5c3818753e76d85');
await StorageHelper() //
.set(ProfileStorageKey.userUUID.key, '649c45d7514a28.85876308');
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '7');
await StorageHelper() //
.set(SecureStorageKey.email.value, 'email_app@exemplo.com');
await StorageHelper() //
.set(SecureStorageKey.password.value, '123456');
await StorageHelper() //
.set(LocalsStorageKey.isNewVersion.key, true);
await PhpGroup.resopndeVinculo.call(tarefa: 'A');
await LicenseRepositoryImpl().resetLicense();
});
}
Future<void> _setUpUnlogged() async {
setUp(() async {
await initializeApp();
await StorageHelper() //
.set(SecureStorageKey.isLogged.value, 'false');
await StorageHelper() //
.set(SecureStorageKey.haveLocal.value, 'false');
await StorageHelper() //
.set(ProfileStorageKey.devUUID.key, '');
await StorageHelper() //
.set(ProfileStorageKey.userUUID.key, '');
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '');
await StorageHelper() //
.set(SecureStorageKey.email.value, '');
await StorageHelper() //
.set(SecureStorageKey.password.value, '');
await StorageHelper() //
.set(LocalsStorageKey.isNewVersion.key, true);
});
}
Future<void> _tearDownAll() async {
tearDownAll(() async {
await StorageHelper().clean(Storage.databaseStorage);
await StorageHelper().clean(Storage.secureStorage);
await StorageHelper().clean(Storage.sharedPreferences);
});
}
Future<void> _tearDown() async {
tearDown(() async {
await StorageHelper().clean(Storage.databaseStorage);
await StorageHelper().clean(Storage.secureStorage);
await StorageHelper().clean(Storage.sharedPreferences);
});
}
Future<void> _setUpAllLogged() async {
setUpAll(() async {
await initializeApp().then((_) async {
await StorageHelper() //
.set(SecureStorageKey.isLogged.value, 'true');
await StorageHelper() //
.set(SecureStorageKey.haveLocal.value, 'true');
await StorageHelper() //
.set(ProfileStorageKey.devUUID.key, 'b5c3818753e76d85');
await StorageHelper() //
.set(ProfileStorageKey.userUUID.key, '649c45d7514a28.85876308');
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '7');
await StorageHelper() //
.set(SecureStorageKey.email.value, 'email_app@exemplo.com');
await StorageHelper() //
.set(SecureStorageKey.password.value, '123456');
await StorageHelper() //
.set(LocalsStorageKey.isNewVersion.key, true);
await PhpGroup.resopndeVinculo.call(tarefa: 'A');
});
await LicenseRepositoryImpl().resetLicense();
});
}
Future<void> _setUpAllUnlogged() async {
setUpAll(() async {
await initializeApp().then((_) async {
await StorageHelper() //
.set(SecureStorageKey.isLogged.value, 'false');
await StorageHelper() //
.set(SecureStorageKey.haveLocal.value, 'false');
await StorageHelper() //
.set(ProfileStorageKey.devUUID.key, '');
await StorageHelper() //
.set(ProfileStorageKey.userUUID.key, '');
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '');
await StorageHelper() //
.set(SecureStorageKey.email.value, '');
await StorageHelper() //
.set(SecureStorageKey.password.value, '');
await StorageHelper() //
.set(LocalsStorageKey.isNewVersion.key, true);
});
});
}
Future<void> _navigateToSignIn(WidgetTester tester) async {
await tester.pumpAndSettle();
final Finder navToSignIn =
find.byKey(const ValueKey<String>('toggleSignInPage'));
await tester.pumpAndSettle();
expect(navToSignIn, findsOneWidget);
await tester.pumpAndSettle();
if (navToSignIn.evaluate().isNotEmpty) {
await tester.tap(navToSignIn);
await tester.pumpAndSettle();
}
}
Future<void> _navigateToSignUp(WidgetTester tester) async {
await tester.pumpAndSettle();
final Finder navToSignUp =
find.byKey(const ValueKey<String>('toggleSignUpPage'));
await tester.pumpAndSettle();
if (navToSignUp.evaluate().isNotEmpty) {
await tester.tap(navToSignUp);
await tester.pumpAndSettle();
}
}
Future<void> _navigateBackUsingSystemGesture() async =>
IntegrationTestWidgetsFlutterBinding.instance.keyboard
.isLogicalKeyPressed(LogicalKeyboardKey.escape);

View File

@ -0,0 +1,37 @@
part of 'app_test.dart';
class WelcomeTest {
static Future signInToSignUp() async {
_setUpAllUnlogged();
testWidgets('Sign-In to Sign-Up', (WidgetTester tester) async {
await tester.pumpWidget(const App());
tester.printToConsole('WelcomeTest - Navigate to Sign-Up to Sign-In');
await tester.pumpAndSettle();
tester.printToConsole('WelcomeTest - Navigate Sign-In');
await _navigateToSignIn(tester);
tester.printToConsole('WelcomeTest - Navigate Sign-Up');
await _navigateToSignUp(tester);
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDownAll();
}
static Future signUpToSignIn() async {
_setUpAllUnlogged();
testWidgets('Sign-Up to Sign-In', (WidgetTester tester) async {
await tester.pumpWidget(const App());
tester.printToConsole('WelcomeTest - Navigate to Sign-In to Sign-Up');
await tester.pumpAndSettle();
await _navigateToSignUp(tester);
tester.printToConsole('WelcomeTest - Navigate Sign-Up');
await _navigateToSignIn(tester);
tester.printToConsole('WelcomeTest - Navigate Sign-In');
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500));
return;
});
_tearDownAll();
}
}

View File

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_model.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_model.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
@ -202,7 +204,9 @@ class _BottomArrowLinkedLocalsComponentWidgetState
} }
Widget _item(BuildContext context, dynamic local) { Widget _item(BuildContext context, dynamic local) {
log('local: ${local['CLI_NOME']}');
return CardItemTemplateComponentWidget( return CardItemTemplateComponentWidget(
key: ValueKey<String>(local['CLI_NOME']),
imagePath: _imagePath(local), imagePath: _imagePath(local),
labelsHashMap: _labelsHashMap(local), labelsHashMap: _labelsHashMap(local),
statusHashMap: [_statusHashMap(local)], statusHashMap: [_statusHashMap(local)],

View File

@ -218,6 +218,7 @@ class _CardItemTemplateComponentWidgetState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
key: widget.key,
splashColor: Colors.transparent, splashColor: Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,
hoverColor: Colors.transparent, hoverColor: Colors.transparent,

View File

@ -25,6 +25,9 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource {
Future<String?> get(String key) async { Future<String?> get(String key) async {
final String? local = final String? local =
await StorageHelper().get(ProfileStorageKey.clientUUID.key); await StorageHelper().get(ProfileStorageKey.clientUUID.key);
if (local == null) {
return null;
}
var response = await DatabaseService.database.query( var response = await DatabaseService.database.query(
LocalsConstants.tableLocalsKeychain, LocalsConstants.tableLocalsKeychain,
where: 'key = ? AND local = ?', where: 'key = ? AND local = ?',

View File

@ -38,6 +38,12 @@ class LocalProfileBloc extends Bloc<LocalProfileEvent, LocalProfileState> {
}); });
} }
@override
Future<void> close() {
_completer.cancel();
return super.close();
}
Future<void> _onLocalProfileEvent( Future<void> _onLocalProfileEvent(
LocalProfileEvent event, Emitter<LocalProfileState> emit) async { LocalProfileEvent event, Emitter<LocalProfileState> emit) async {
final cliName = final cliName =

View File

@ -87,6 +87,8 @@ class _LocalProfileComponentWidgetState
child: Padding( child: Padding(
padding: const EdgeInsets.all(2.0), padding: const EdgeInsets.all(2.0),
child: InkWell( child: InkWell(
key: const Key(
'DefaultLocalProfileComponentWidget_InkWell'),
splashColor: Colors.transparent, splashColor: Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,
hoverColor: Colors.transparent, hoverColor: Colors.transparent,
@ -180,6 +182,8 @@ class _LocalProfileComponentWidgetState
child: Padding( child: Padding(
padding: const EdgeInsets.all(2.0), padding: const EdgeInsets.all(2.0),
child: InkWell( child: InkWell(
key: const Key(
'AsyncLocalProfileComponentWidget_InkWell'),
splashColor: Colors.transparent, splashColor: Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,
hoverColor: Colors.transparent, hoverColor: Colors.transparent,

View File

@ -9,29 +9,41 @@ import 'package:hub/shared/extensions/dialog_extensions.dart';
import 'package:hub/shared/utils/path_util.dart'; import 'package:hub/shared/utils/path_util.dart';
abstract class MenuLocalDataSource { abstract class MenuLocalDataSource {
Future<MenuItem?> addMenuEntry(EnumMenuItem item, List<MenuItem?> entries, Future<MenuItem?> addMenuEntry(Key key, EnumMenuItem item,
IconData icon, String text, Function() action); List<MenuItem?> entries, IconData icon, String text, Function() action);
Future<bool> processDisplayDefault( Future<bool> processDisplayDefault(
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries); EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
List<MenuItem?> entries); List<MenuItem?> entries);
Future<bool> processStartDate(String startDate, MenuEntry entry); Future<bool> processStartDate(String startDate, MenuEntry entry);
Future<bool> processExpirationDate(String expirationDate, MenuEntry entry); Future<bool> processExpirationDate(String expirationDate, MenuEntry entry);
} }
class MenuLocalDataSourceImpl implements MenuLocalDataSource { class MenuLocalDataSourceImpl implements MenuLocalDataSource {
static final MenuLocalDataSourceImpl _instance = static final MenuLocalDataSourceImpl _instance =
MenuLocalDataSourceImpl._internal(); MenuLocalDataSourceImpl._internal();
factory MenuLocalDataSourceImpl() => _instance; factory MenuLocalDataSourceImpl() => _instance;
MenuLocalDataSourceImpl._internal(); MenuLocalDataSourceImpl._internal();
@override @override
Future<MenuItem?> addMenuEntry(EnumMenuItem item, List<MenuItem?> entries, Future<MenuItem?> addMenuEntry(
IconData icon, String text, Function() action) async { Key key,
EnumMenuItem item,
List<MenuItem?> entries,
IconData icon,
String text,
Function() action,
) async {
final menuItem = item == EnumMenuItem.button final menuItem = item == EnumMenuItem.button
? ButtonMenuItem(icon: icon, action: action, title: text) ? ButtonMenuItem(key: key, icon: icon, action: action, title: text)
: item == EnumMenuItem.card || item == EnumMenuItem.tile : item == EnumMenuItem.card || item == EnumMenuItem.tile
? CardMenuItem(icon: icon, action: action, title: text) ? CardMenuItem(key: key, icon: icon, action: action, title: text)
: null; : null;
if (menuItem != null) { if (menuItem != null) {
entries.add(menuItem); entries.add(menuItem);
@ -43,7 +55,9 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
Future<bool> processDisplayDefault( Future<bool> processDisplayDefault(
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async { EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
if (opt.key == 'FRE-HUB-LOGOUT') { if (opt.key == 'FRE-HUB-LOGOUT') {
await addMenuEntry(item, entries, opt.icon, opt.name, () async { await addMenuEntry(
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
() async {
await AuthenticationService.signOut(navigatorKey.currentContext!); await AuthenticationService.signOut(navigatorKey.currentContext!);
}); });
return true; return true;
@ -57,12 +71,16 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
try { try {
switch (display.value) { switch (display.value) {
case 'VISIVEL': case 'VISIVEL':
await addMenuEntry(item, entries, opt.icon, opt.name, () async { await addMenuEntry(
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
() async {
await PathUtil.nav(opt.route); await PathUtil.nav(opt.route);
}); });
break; break;
case 'DESABILITADO': case 'DESABILITADO':
await addMenuEntry(item, entries, opt.icon, opt.name, () async { await addMenuEntry(
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
() async {
await DialogUnavailable.unavailableFeature( await DialogUnavailable.unavailableFeature(
navigatorKey.currentContext!); navigatorKey.currentContext!);
}); });

View File

@ -9,18 +9,17 @@ class MenuRepositoryImpl implements MenuRepository {
final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl(); final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl();
@override @override
Future<List<MenuItem?>> generateMenuEntries( Future<List<MenuItem?>> entries2Items(
List<MenuEntry> menuEntries, EnumMenuItem item) async { List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
List<MenuItem?> entries = []; List<MenuItem?> entries = [];
// final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean()); // final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean());
try { try {
for (var entry in menuEntries) { for (var entry in menuEntries) {
final bool isDefault = final bool isDefault = await menuDataSource.processDisplayDefault(
await menuDataSource.processDisplayDefault(item, entry, entries); menuItem, entry, entries);
if (isDefault) continue; if (isDefault) continue;
final licenseValue = final licenseValue = await LicenseRepositoryImpl().getModule(entry.key);
await LicenseRepositoryImpl().getLicense(entry.key);
if (licenseValue != null) { if (licenseValue != null) {
final licenseMap = await stringToMap(licenseValue); final licenseMap = await stringToMap(licenseValue);
final display = EnumDisplay.fromString(licenseMap['display']); final display = EnumDisplay.fromString(licenseMap['display']);
@ -31,17 +30,17 @@ class MenuRepositoryImpl implements MenuRepository {
final isExpired = final isExpired =
await menuDataSource.processExpirationDate(expirationDate, entry); await menuDataSource.processExpirationDate(expirationDate, entry);
if (isStarted && !isExpired) { if (isStarted && !isExpired) {
await menuDataSource.handleMenu(item, display, entry, entries); await menuDataSource.handleMenu(menuItem, display, entry, entries);
} }
if (isExpired) { if (isExpired) {
log('Entry ${entry.key} is expired'); log('Entry ${entry.key} is expired');
await menuDataSource.handleMenu( await menuDataSource.handleMenu(
item, EnumDisplay.inactive, entry, entries); menuItem, EnumDisplay.inactive, entry, entries);
} }
if (!isStarted) { if (!isStarted) {
log('Entry ${entry.key} is not started'); log('Entry ${entry.key} is not started');
await menuDataSource.handleMenu( await menuDataSource.handleMenu(
item, EnumDisplay.inactive, entry, entries); menuItem, EnumDisplay.inactive, entry, entries);
} }
} }
} }

View File

@ -1,6 +1,6 @@
import 'package:hub/features/menu/index.dart'; import 'package:hub/features/menu/index.dart';
abstract class MenuRepository { abstract class MenuRepository {
Future<List<MenuItem?>> generateMenuEntries( Future<List<MenuItem?>> entries2Items(
List<MenuEntry> menuEntries, EnumMenuItem item); List<MenuEntry> menuEntries, EnumMenuItem item);
} }

View File

@ -2,9 +2,9 @@ import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hub/features/backend/index.dart'; import 'package:hub/features/backend/index.dart';
import 'package:hub/features/local/index.dart';
import 'package:hub/features/menu/index.dart'; import 'package:hub/features/menu/index.dart';
import 'package:hub/features/module/index.dart'; import 'package:hub/features/module/index.dart';
import 'package:hub/features/local/index.dart';
class MenuEvent {} class MenuEvent {}
@ -40,7 +40,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
await LicenseRemoteDataSourceImpl(PhpGroup()).waitForSaveCompletion(); await LicenseRemoteDataSourceImpl(PhpGroup()).waitForSaveCompletion();
final List<MenuItem?> newEntries = final List<MenuItem?> newEntries =
await MenuRepositoryImpl().generateMenuEntries(entries, item); await MenuRepositoryImpl().entries2Items(entries, item);
emit(state.copyWith(menuEntries: newEntries)); emit(state.copyWith(menuEntries: newEntries));
} }

View File

@ -7,24 +7,32 @@ import 'package:sqflite/sqflite.dart';
abstract class LicenseLocalDataSource { abstract class LicenseLocalDataSource {
Future<void> init(); Future<void> init();
Future<void> setDisplayByKey(final List<String> key, final String display); Future<void> setDisplayByKey(final List<String> key, final String display);
Future<bool> isNewVersion(); Future<bool> isNewVersion();
Future<String?> get(String key); Future<String?> get(String key);
Future<void> set<T>(String key, T value);
Future<bool> set<T>(String key, T value);
Future<void> del(String key); Future<void> del(String key);
Future<bool> setupLicense(bool isNewVersion); Future<bool> setupLicense(bool isNewVersion);
Future<List<String>> getLicense();
Future<void> clear(); Future<void> clear();
} }
class LicenseLocalDataSourceImpl implements LicenseLocalDataSource { class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
late final Database database; Database? _database;
static final LicenseLocalDataSourceImpl _instance = static final LicenseLocalDataSourceImpl _instance =
LicenseLocalDataSourceImpl._internal(); LicenseLocalDataSourceImpl._internal();
factory LicenseLocalDataSourceImpl(Database database) { factory LicenseLocalDataSourceImpl(Database database) {
_instance.database = database; _instance._database ??= database;
return _instance; return _instance;
} }
@ -92,9 +100,9 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
@override @override
Future<String?> get(String key) async { Future<String?> get(String key) async {
var response = var response = await _instance._database
await database.query(tableLicense, where: 'key = ?', whereArgs: [key]); ?.query(tableLicense, where: 'key = ?', whereArgs: [key]);
if (response.isEmpty) { if (response!.isEmpty) {
return null; return null;
} }
@ -102,12 +110,12 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
} }
@override @override
Future<void> set<T>(String key, T value) async { Future<bool> set<T>(String key, T value) async {
value as Map<String, dynamic>; value as Map<String, dynamic>;
if (value.isEmpty) return; if (value.isEmpty) return false;
if (key == 'null') return; if (key == 'null') return false;
await database.rawInsert( await _instance._database?.rawInsert(
'INSERT OR REPLACE INTO $tableLicense (key, display, expirationDate, startDate, quantity) VALUES (?, ?, ?, ?, ?)', 'INSERT OR REPLACE INTO $tableLicense (key, display, expirationDate, startDate, quantity) VALUES (?, ?, ?, ?, ?)',
[ [
key, key,
@ -117,16 +125,27 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
value['quantity'] value['quantity']
], ],
); );
return; return true;
} }
@override @override
Future<void> del(String key) async { Future<void> del(String key) async {
await database.delete(tableLicense, where: 'key = ?', whereArgs: [key]); await _instance._database
?.delete(tableLicense, where: 'key = ?', whereArgs: [key]);
} }
@override @override
Future<void> clear() async { Future<void> clear() async {
await database.delete(tableLicense); await _instance._database?.delete(tableLicense);
}
@override
Future<List<String>> getLicense() async {
var response =
await _instance._database?.query(tableLicense, columns: ['key']);
if (response!.isEmpty) {
return [];
}
return response.map((e) => e.toString()).toList();
} }
} }

View File

@ -9,18 +9,18 @@ import 'package:hub/features/module/index.dart';
abstract class LicenseRemoteDataSource { abstract class LicenseRemoteDataSource {
Future<bool> fetchLicenses(bool isNewVersion); Future<bool> fetchLicenses(bool isNewVersion);
Future<void> cleanLicense(); Future<bool> cleanLicense();
Future<void> processLicense(); Future<void> processLicense();
} }
class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource { class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
late final Api api; Api? _api;
static final LicenseRemoteDataSourceImpl _instance = static final LicenseRemoteDataSourceImpl _instance =
LicenseRemoteDataSourceImpl._internal(); LicenseRemoteDataSourceImpl._internal();
factory LicenseRemoteDataSourceImpl(Api api) { factory LicenseRemoteDataSourceImpl(Api api) {
_instance.api = api; _instance._api ??= api;
return _instance; return _instance;
} }
@ -30,16 +30,22 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
Future<void> processLicense() async {} Future<void> processLicense() async {}
@override @override
Future<void> cleanLicense() async { Future<bool> cleanLicense() async {
LocalsRepositoryImpl.license.add(false); try {
LocalsRepositoryImpl.license.add(false);
return true;
} catch (e, s) {
log('Erro ao limpar licenças: $e', stackTrace: s);
return false;
}
} }
@override @override
Future<bool> fetchLicenses(bool isNewVersion) async { Future<bool> fetchLicenses(bool isNewVersion) async {
log('Fetching licenses...'); log('Fetching licenses...');
try { try {
final response = await _instance.api.getLicense(); final response = await _instance._api?.getLicense();
final dynamic responseBody = response.jsonBody; final dynamic responseBody = response!.jsonBody;
if (responseBody == []) { if (responseBody == []) {
return true; return true;
@ -78,6 +84,6 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
static Future<void> _saveModule(final dynamic body) async { static Future<void> _saveModule(final dynamic body) async {
if (body is! Map<String, dynamic>) return; if (body is! Map<String, dynamic>) return;
await LicenseRepositoryImpl().setLicense(body['key'], body); await LicenseRepositoryImpl().setModule(body['key'], body);
} }
} }

View File

@ -10,26 +10,25 @@ typedef LicenseStatus = bool;
class LicenseRepositoryImpl implements LicenseRepository { class LicenseRepositoryImpl implements LicenseRepository {
late final Database database; late final Database database;
late final PhpGroup api; late final Api api;
late final LicenseLocalDataSource localDataSource; late final LicenseLocalDataSource localDataSource;
late final LicenseRemoteDataSource remoteDataSource; late final LicenseRemoteDataSource remoteDataSource;
LicenseRepositoryImpl([Database? database, PhpGroup? api]) { LicenseRepositoryImpl([Database? database, Api? api])
if (database != null) { : database = database ?? DatabaseService.database,
this.database = database; api = api ?? PhpGroup() {
} else {
this.database = DatabaseService.database;
}
if (api != null) {
this.api = api;
} else {
this.api = PhpGroup();
}
localDataSource = LicenseLocalDataSourceImpl(this.database); localDataSource = LicenseLocalDataSourceImpl(this.database);
remoteDataSource = LicenseRemoteDataSourceImpl(this.api); remoteDataSource = LicenseRemoteDataSourceImpl(this.api);
} }
@override
Future<bool> resetLicense() async {
bool result = false;
final bool isNewVersion = await localDataSource.isNewVersion();
result = await localDataSource.setupLicense(isNewVersion);
return result;
}
@override @override
Future<bool> updateLicense() async { Future<bool> updateLicense() async {
log('updateLicense'); log('updateLicense');
@ -44,18 +43,23 @@ class LicenseRepositoryImpl implements LicenseRepository {
} }
@override @override
Future<void> cleanLicense() async { Future<bool> cleanLicense() async {
return await remoteDataSource.cleanLicense(); return await remoteDataSource.cleanLicense();
} }
@override @override
Future<String?> getLicense(String key) async { Future<String?> getModule(String key) async {
final response = await localDataSource.get(key); final response = await localDataSource.get(key);
return response; return response;
} }
@override @override
Future<void> setLicense<T>(String key, T value) async { Future<bool> setModule<T>(String key, T value) async {
return await localDataSource.set(key, value); return await localDataSource.set(key, value);
} }
@override
Future<List<String>> getLicense() async {
return await localDataSource.getLicense();
}
} }

View File

@ -1,7 +1,13 @@
abstract class LicenseRepository { abstract class LicenseRepository {
Future<bool> updateLicense(); Future<bool> updateLicense();
Future<void> cleanLicense();
Future<String?> getLicense(String key); Future<bool> cleanLicense();
Future<void> setLicense<T>(String key, T value);
Future<bool> resetLicense();
Future<String?> getModule(String key);
Future<bool> setModule<T>(String key, T value);
Future<List<String>> getLicense();
} }

View File

@ -22,8 +22,11 @@ class DatabaseStorage implements BaseStorage {
} }
@override @override
Future<void> clearAll() => // Future<void> clearAll() async {
throw UnimplementedError(); await ProfileLocalDataSourceImpl().clearAll();
await LocalsLocalDataSourceImpl().clearAll();
}
@override @override
Future<void> delete(String key) async => Future<void> delete(String key) async =>
await getInstanceByKey(key).delete(key); await getInstanceByKey(key).delete(key);

View File

@ -33,6 +33,7 @@ class DatabaseService {
onOpen: _onOpen, onOpen: _onOpen,
onConfigure: _onConfigure, onConfigure: _onConfigure,
); );
print('Database initialized');
await LicenseRepositoryImpl().updateLicense(); await LicenseRepositoryImpl().updateLicense();
isInitialized = true; isInitialized = true;
} }

View File

@ -126,7 +126,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
) )
: const ReceptionPageWidget(); : const ReceptionPageWidget();
} else { } else {
return const WelcomePageWidget(); return const WelcomePage();
} }
}(), }(),
builder: (context, snapshot) { builder: (context, snapshot) {
@ -134,7 +134,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
DialogUtil.error(context, snapshot.error.toString()); DialogUtil.error(context, snapshot.error.toString());
return const WelcomePageWidget(); return const WelcomePage();
} else { } else {
return snapshot.data!; return snapshot.data!;
} }
@ -273,7 +273,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
FFRoute( FFRoute(
name: 'welcomePage', name: 'welcomePage',
path: '/welcomePage', path: '/welcomePage',
builder: (context, params) => const WelcomePageWidget()), builder: (context, params) => const WelcomePage()),
FFRoute( FFRoute(
name: 'qrCodePage', name: 'qrCodePage',
path: '/qrCodePage', path: '/qrCodePage',

View File

@ -23,39 +23,58 @@ Future<void> initializeApp() async {
_initializeUrlStrategy(); _initializeUrlStrategy();
_initializeSystemSettings(); _initializeSystemSettings();
await _initializeFlutterFlow(); await _initializeFlutterFlow();
await _initializeNav();
} }
Future<void> _initializeTracking() async { Future<void> _initializeTracking() async {
print('Requesting tracking authorization...');
await AppTrackingTransparency.requestTrackingAuthorization(); await AppTrackingTransparency.requestTrackingAuthorization();
print('Tracking authorization requested');
} }
Future<void> _initializeFirebase() async { Future<void> _initializeFirebase() async {
print('Initializing Firebase...');
await Firebase.initializeApp(); await Firebase.initializeApp();
print('Firebase initialized');
} }
Future<void> _initializeNotificationService() async { Future<void> _initializeNotificationService() async {
print('Initializing Notification Service...');
await NotificationService.initialize(); await NotificationService.initialize();
print('Notification Service initialized');
} }
void _initializeUrlStrategy() { void _initializeUrlStrategy() {
print('Initializing URL Strategy...');
setUrlStrategy(PathUrlStrategy()); setUrlStrategy(PathUrlStrategy());
print('URL Strategy initialized');
} }
void _initializeSystemSettings() { void _initializeSystemSettings() {
print('Initializing System Settings...');
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (kDebugMode) { if (kDebugMode) {
log("Aplicativo em Debug Mode, crashlytics desabilitado!"); print('Debug mode');
} else { } else {
final crashlyticsInstance = FirebaseCrashlytics.instance; final crashlyticsInstance = FirebaseCrashlytics.instance;
print('Release mode');
if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
FlutterError.onError = crashlyticsInstance.recordFlutterError; FlutterError.onError = crashlyticsInstance.recordFlutterError;
print('Crashlytics enabled');
} }
} }
} }
Future<void> _initializeFlutterFlow() async { Future<void> _initializeFlutterFlow() async {
print('Initializing FlutterFlow...');
await FlutterFlowTheme.initialize(); await FlutterFlowTheme.initialize();
await FFLocalizations.initialize(); await FFLocalizations.initialize();
print('FlutterFlow initialized');
}
Future<void> _initializeNav() async {
print('Initializing Nav...');
GoRouter.optionURLReflectsImperativeAPIs = true; GoRouter.optionURLReflectsImperativeAPIs = true;
usePathUrlStrategy(); usePathUrlStrategy();
print('Nav initialized');
} }

View File

@ -13,6 +13,7 @@ import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/utils/test_util.dart';
import 'package:responsive_framework/responsive_framework.dart'; import 'package:responsive_framework/responsive_framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -179,7 +180,7 @@ class _AppState extends State<App> {
); );
_setupFirebaseMessaging(); _setupFirebaseMessaging();
DeepLinkService().ensureInitialization(); if (TestUtil.isInTest) DeepLinkService().ensureInitialization();
} }
@override @override

View File

@ -1,5 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,7 +12,6 @@ import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/form_field_controller.dart'; import 'package:hub/flutter_flow/form_field_controller.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/pets_page/pets_page_widget.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart';
import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/image_util.dart'; import 'package:hub/shared/utils/image_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/limited_text_size.dart';
@ -110,7 +108,8 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
String? Function(BuildContext, String?)? textControllerObservationValidator; String? Function(BuildContext, String?)? textControllerObservationValidator;
Future<void> initAsync() async { Future<void> initAsync() async {
defaultDropDownText = FFLocalizations.of(buildContext!).getVariableText( defaultDropDownText =
FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
enText: 'Select an option', enText: 'Select an option',
ptText: 'Selecione uma opção', ptText: 'Selecione uma opção',
); );

View File

@ -18,12 +18,9 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/qr_code_page/qr_code_page_model.dart'; import 'package:hub/pages/qr_code_page/qr_code_page_model.dart';
import 'package:hub/shared/utils/biometric_util.dart'; import 'package:hub/shared/utils/biometric_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:percent_indicator/circular_percent_indicator.dart'; import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
class QrCodePageWidget extends StatefulWidget { class QrCodePageWidget extends StatefulWidget {
@ -492,7 +489,10 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
}, },
), ),
title: Text( title: Text(
FFLocalizations.of(context).getText('ku7jqe53'), FFLocalizations.of(context).getVariableText(
ptText: 'QRCode de Acesso',
enText: 'Access QRCode',
),
style: FlutterFlowTheme.of(context).headlineMedium.override( style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText, color: FlutterFlowTheme.of(context).primaryText,

View File

@ -57,8 +57,9 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
}, },
), ),
title: Text( title: Text(
FFLocalizations.of(context).getText( FFLocalizations.of(context).getVariableText(
'megskb6s' /* Cadastrar Visitante */, ptText: 'Cadastrar Visitantes',
enText: 'Register Visitors',
), ),
style: FlutterFlowTheme.of(context).headlineMedium.override( style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,

View File

@ -7,8 +7,8 @@ import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/pages/visits_on_the_property/model.dart'; import 'package:hub/pages/visits_on_the_property/model.dart';
import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/log_util.dart';
class VisitsOnTheProperty extends StatefulWidget { class VisitsOnTheProperty extends StatefulWidget {
const VisitsOnTheProperty({super.key}); const VisitsOnTheProperty({super.key});
@ -135,7 +135,9 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
title: Text( title: Text(
FFLocalizations.of(context).getVariableText( FFLocalizations.of(context).getVariableText(
ptText: 'Visitas em aberto', enText: 'Opened visits'), ptText: 'Visitas Abertas',
enText: 'Opened visits',
),
style: FlutterFlowTheme.of(context).headlineMedium.override( style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText, color: FlutterFlowTheme.of(context).primaryText,

View File

@ -1,9 +1,9 @@
import '/components/templates_components/welcome_template_component/welcome_template_component_widget.dart'; import '/components/templates_components/welcome_template_component/welcome_template_component_widget.dart';
import '/flutter_flow/flutter_flow_util.dart'; import '/flutter_flow/flutter_flow_util.dart';
import 'welcome_page_widget.dart' show WelcomePageWidget; import 'welcome_page_widget.dart' show WelcomePage;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class WelcomePageModel extends FlutterFlowModel<WelcomePageWidget> { class WelcomePageModel extends FlutterFlowModel<WelcomePage> {
/// Local state fields for this page. /// Local state fields for this page.
String toggleIdx = 'welcome'; String toggleIdx = 'welcome';

View File

@ -11,14 +11,14 @@ import 'welcome_page_model.dart';
export 'welcome_page_model.dart'; export 'welcome_page_model.dart';
class WelcomePageWidget extends StatefulWidget with Switcher { class WelcomePage extends StatefulWidget with Switcher {
const WelcomePageWidget({super.key}); const WelcomePage({super.key});
@override @override
State<WelcomePageWidget> createState() => _WelcomePageWidgetState(); State<WelcomePage> createState() => _WelcomePageState();
} }
class _WelcomePageWidgetState extends State<WelcomePageWidget> { class _WelcomePageState extends State<WelcomePage> {
late WelcomePageModel _model; late WelcomePageModel _model;
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();

View File

@ -8,6 +8,7 @@ export 'log_util.dart';
export 'path_util.dart'; export 'path_util.dart';
export 'share_util.dart'; export 'share_util.dart';
export 'snackbar_util.dart'; export 'snackbar_util.dart';
export 'string_util.dart';
export 'text_util.dart'; export 'text_util.dart';
export 'validator_util.dart'; export 'validator_util.dart';
export 'webview_util.dart'; export 'webview_util.dart';

View File

@ -0,0 +1,7 @@
import 'dart:io';
class TestUtil {
static bool get isInTest {
return Platform.environment.containsKey('FLUTTER_TEST');
}
}

View File

@ -34,10 +34,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: app_links name: app_links
sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99 sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.2" version: "6.3.3"
app_links_linux: app_links_linux:
dependency: transitive dependency: transitive
description: description:
@ -66,18 +66,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: app_tracking_transparency name: app_tracking_transparency
sha256: "64d9745931e565790abdea91b518ac8dc3cebe6d0d0aaf7119343271b983259a" sha256: "1f71f4d8402552fbf8b191d4edab301f233c1af794878b7bc56c708470ffd74c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.6" version: "2.0.6+1"
archive: archive:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.1" version: "4.0.2"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -146,50 +146,50 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: build name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
build_config: build_config:
dependency: transitive dependency: transitive
description: description:
name: build_config name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
build_daemon: build_daemon:
dependency: transitive dependency: transitive
description: description:
name: build_daemon name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" sha256: "294a2edaf4814a378725bfe6358210196f5ea37af89ecd81bfa32960113d4948"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.3"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" sha256: "99d3980049739a985cf9b21f30881f46db3ebc62c5b8d5e60e27440876b1ba1e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.4.3"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" sha256: "74691599a5bc750dc96a6b4bfd48f7d9d66453eab04c7f4063134800d6a5c573"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.13" version: "2.4.14"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.3.2" version: "8.0.0"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@ -202,10 +202,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: built_value name: built_value
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.9.2" version: "8.9.3"
cached_network_image: cached_network_image:
dependency: "direct main" dependency: "direct main"
description: description:
@ -286,6 +286,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
coverage:
dependency: transitive
description:
name: coverage
sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43
url: "https://pub.dev"
source: hosted
version: "1.11.1"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -338,10 +346,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: device_info_plus_platform_interface name: device_info_plus_platform_interface
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.1" version: "7.0.2"
dropdown_button2: dropdown_button2:
dependency: "direct main" dependency: "direct main"
description: description:
@ -466,10 +474,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: firebase_core_platform_interface name: firebase_core_platform_interface
sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6 sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.3.1" version: "5.4.0"
firebase_core_web: firebase_core_web:
dependency: transitive dependency: transitive
description: description:
@ -641,10 +649,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.23" version: "2.0.24"
flutter_riverpod: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
@ -657,50 +665,50 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage name: flutter_secure_storage
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0" sha256: c0f1abb088adddc193286ea91eedd71900ec5707ac86503a7ae09d88c9ffc22b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.2.2" version: "10.0.0-beta.2"
flutter_secure_storage_linux: flutter_secure_storage_linux:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage_linux name: flutter_secure_storage_linux
sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b" sha256: b777e220fbf21c149574aa31f9e4ed56dcf025c4ef196664fe90954c265105dc
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "2.0.0"
flutter_secure_storage_macos: flutter_secure_storage_macos:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage_macos name: flutter_secure_storage_macos
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81" sha256: "75894eb6b402ac7f7f5ee5487d651b87855a338e26eb6993f4b2fce33013a615"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "4.0.0"
flutter_secure_storage_platform_interface: flutter_secure_storage_platform_interface:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage_platform_interface name: flutter_secure_storage_platform_interface
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.2" version: "2.0.1"
flutter_secure_storage_web: flutter_secure_storage_web:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage_web name: flutter_secure_storage_web
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 sha256: "4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "2.0.0"
flutter_secure_storage_windows: flutter_secure_storage_windows:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_secure_storage_windows name: flutter_secure_storage_windows
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 sha256: ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "4.0.0"
flutter_shaders: flutter_shaders:
dependency: transitive dependency: transitive
description: description:
@ -808,10 +816,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: go_router name: go_router
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539" sha256: "7c2d40b59890a929824f30d442e810116caf5088482629c894b9e4478c67472d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.6.2" version: "14.6.3"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
@ -864,26 +872,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http_multi_server name: http_multi_server
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.1" version: "3.2.2"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.1.2"
image: image:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: image name: image
sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.0" version: "4.5.2"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -896,10 +904,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_picker_android name: image_picker_android
sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e sha256: aa6f1280b670861ac45220cc95adc59bb6ae130259d36f980ccb62220dc5e59f
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12+18" version: "0.8.12+19"
image_picker_for_web: image_picker_for_web:
dependency: "direct main" dependency: "direct main"
description: description:
@ -912,10 +920,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_picker_ios name: image_picker_ios
sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b" sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12+1" version: "0.8.12+2"
image_picker_linux: image_picker_linux:
dependency: transitive dependency: transitive
description: description:
@ -936,10 +944,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_picker_platform_interface name: image_picker_platform_interface
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.10.0" version: "2.10.1"
image_picker_windows: image_picker_windows:
dependency: transitive dependency: transitive
description: description:
@ -1037,10 +1045,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: lints name: lints
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.0" version: "5.1.1"
local_auth: local_auth:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1061,10 +1069,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: local_auth_darwin name: local_auth_darwin
sha256: "6d2950da311d26d492a89aeb247c72b4653ddc93601ea36a84924a396806d49c" sha256: "5c5127061107278ab4cafa1ac51b3b6760282bf1a2abf011270908a429d1634b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.2"
local_auth_platform_interface: local_auth_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1117,10 +1125,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: material_symbols_icons name: material_symbols_icons
sha256: "64404f47f8e0a9d20478468e5decef867a688660bad7173adcd20418d7f892c9" sha256: "89aac72d25dd49303f71b3b1e70f8374791846729365b25bebc2a2531e5b86cd"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2801.0" version: "4.2801.1"
maybe_just_nothing: maybe_just_nothing:
dependency: transitive dependency: transitive
description: description:
@ -1157,10 +1165,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: mockito name: mockito
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" sha256: f99d8d072e249f719a5531735d146d8cf04c580d93920b04de75bef6dfb2daf6
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.4" version: "5.4.5"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -1169,6 +1177,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
@ -1189,26 +1205,26 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info_plus name: package_info_plus
sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.1.1" version: "8.1.2"
package_info_plus_platform_interface: package_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: package_info_plus_platform_interface name: package_info_plus_platform_interface
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
page_transition: page_transition:
dependency: "direct main" dependency: "direct main"
description: description:
name: page_transition name: page_transition
sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6 sha256: "9d2a780d7d68b53ae82fbcc43e06a16195e6775e9aae40e55dc0cbb593460f9d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.2.1"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -1369,6 +1385,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.5.1" version: "1.5.1"
posix:
dependency: transitive
description:
name: posix
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
url: "https://pub.dev"
source: hosted
version: "6.0.1"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -1397,10 +1421,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pubspec_parse name: pubspec_parse
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.5.0"
qr: qr:
dependency: transitive dependency: transitive
description: description:
@ -1461,34 +1485,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: share_plus_platform_interface name: share_plus_platform_interface
sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48 sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.1" version: "5.0.2"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences name: shared_preferences
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.3" version: "2.3.5"
shared_preferences_android: shared_preferences_android:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences_android name: shared_preferences_android
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549" sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.4" version: "2.4.0"
shared_preferences_foundation: shared_preferences_foundation:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences_foundation name: shared_preferences_foundation
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.3" version: "2.5.4"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
@ -1525,10 +1549,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.2"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
shelf_static:
dependency: transitive
description:
name: shelf_static
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
url: "https://pub.dev"
source: hosted
version: "1.1.3"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
@ -1554,10 +1594,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_helper name: source_helper
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.4" version: "1.3.5"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
url: "https://pub.dev"
source: hosted
version: "2.1.2"
source_maps:
dependency: transitive
description:
name: source_maps
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
url: "https://pub.dev"
source: hosted
version: "0.10.13"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -1602,10 +1658,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite_darwin name: sqflite_darwin
sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474" sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.1+1"
sqflite_platform_interface: sqflite_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1642,10 +1698,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: stream_transform name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@ -1678,6 +1734,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
test:
dependency: "direct dev"
description:
name: test
sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f"
url: "https://pub.dev"
source: hosted
version: "1.25.8"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
@ -1686,6 +1750,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.3" version: "0.7.3"
test_core:
dependency: transitive
description:
name: test_core
sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d"
url: "https://pub.dev"
source: hosted
version: "0.6.5"
timeago: timeago:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1698,10 +1770,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: timing name: timing
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -1794,10 +1866,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics_codec name: vector_graphics_codec
sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb" sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.12" version: "1.1.13"
vector_graphics_compiler: vector_graphics_compiler:
dependency: transitive dependency: transitive
description: description:
@ -1826,10 +1898,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: watcher name: watcher
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
web: web:
dependency: transitive dependency: transitive
description: description:
@ -1862,6 +1934,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.4" version: "3.0.4"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
webview_flutter: webview_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1874,10 +1954,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19" sha256: "3d535126f7244871542b2f0b0fcf94629c9a14883250461f9abe1a6644c1c379"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.0" version: "4.2.0"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1930,10 +2010,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "3.1.3"
sdks: sdks:
dart: ">=3.5.0 <4.0.0" dart: ">=3.6.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.24.0"

View File

@ -37,12 +37,12 @@ dependencies:
# flutter_plugin_android_lifecycle: ^2.0.23 # flutter_plugin_android_lifecycle: ^2.0.23
share_plus: ^10.0.0 share_plus: ^10.0.0
# connectivity_plus: ^6.0.5 # connectivity_plus: ^6.0.5
flutter_secure_storage: 9.2.2 flutter_secure_storage: ^10.0.0-beta.2
flutter_secure_storage_linux: 1.2.1 flutter_secure_storage_linux: ^2.0.0
flutter_secure_storage_macos: 3.1.2 flutter_secure_storage_macos: ^4.0.0
flutter_secure_storage_platform_interface: 1.1.2 flutter_secure_storage_platform_interface: ^2.0.1
flutter_secure_storage_web: 1.2.1 flutter_secure_storage_web: ^2.0.0
flutter_secure_storage_windows: 3.1.2 flutter_secure_storage_windows: ^4.0.0
flutter_spinkit: 5.2.1 flutter_spinkit: 5.2.1
flutter_staggered_grid_view: 0.7.0 flutter_staggered_grid_view: 0.7.0
flutter_svg: ^2.0.15 flutter_svg: ^2.0.15
@ -56,13 +56,13 @@ dependencies:
image_picker_for_web: ^3.0.5 image_picker_for_web: ^3.0.5
persistent_bottom_nav_bar: ^6.2.1 persistent_bottom_nav_bar: ^6.2.1
image_picker_ios: ^0.8.12+1 image_picker_ios: ^0.8.12+1
image_picker_platform_interface: 2.10.0 image_picker_platform_interface: ^2.10.1
local_auth: ^2.2.0 local_auth: ^2.2.0
intl: ^0.19.0 intl: ^0.19.0
# camera: ^0.11.0+2 # camera: ^0.11.0+2
json_path: ^0.7.4 json_path: ^0.7.4
mime_type: ^1.0.1 mime_type: ^1.0.1
page_transition: 2.1.0 page_transition: ^2.2.1
path_provider: ^2.1.4 path_provider: ^2.1.4
path_provider_android: ^2.2.12 path_provider_android: ^2.2.12
google_mlkit_face_detection: ^0.12.0 google_mlkit_face_detection: ^0.12.0
@ -124,6 +124,7 @@ dev_dependencies:
build_runner: ^2.4.13 build_runner: ^2.4.13
freezed: ^2.5.7 freezed: ^2.5.7
json_serializable: ^6.9.0 json_serializable: ^6.9.0
test: ^1.25.8
flutter_launcher_icons: flutter_launcher_icons:
android: "launcher_icon" android: "launcher_icon"
@ -157,3 +158,4 @@ fonts:
- family: Menu - family: Menu
fonts: fonts:
- asset: assets/fonts/menu.ttf - asset: assets/fonts/menu.ttf

View File

@ -0,0 +1,70 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:hub/features/backend/index.dart';
import 'package:hub/features/menu/index.dart';
import 'package:hub/features/module/index.dart';
import 'package:hub/features/storage/index.dart';
import 'package:hub/initialization.dart';
import 'package:integration_test/integration_test.dart';
class ApiImpl implements Api {
@override
var getLicense = LicenseApi() as GetLicense;
}
class LicenseApi extends GetLicense {
@override
Future<ApiCallResponse> call() async => ApiCallResponse(
{
'error_msg': 'error',
},
{
'Content-Type': 'application/x-www-form-urlencoded',
},
200,
);
}
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() async {
await initializeApp();
});
group('Test', () {
late LicenseRepository repo = LicenseRepositoryImpl(
DatabaseService.database,
ApiImpl(),
);
List<MenuEntry> menuEntries = MenuEntry.entries;
test('update license', () async {
late bool result;
result = await repo.updateLicense();
expect(result, true);
});
test('get module', () async {
late String? result;
for (var entry in menuEntries) {
result = await repo.getModule(entry.key);
expect(result, isNotNull);
}
});
test('set module', () async {
late bool? result;
for (var entry in menuEntries) {
result = await repo.setModule(entry.key, '');
expect(result, true);
}
});
test('clean license', () async {
late bool result;
result = await repo.cleanLicense();
expect(result, true);
});
});
}