Merge pull request #84 from FRE-Informatica/debit/fd-1038
DEBIT/FD-1038 - Escritas de Testes para o App
This commit is contained in:
commit
069b46e927
|
@ -1,2 +1,2 @@
|
|||
gradle 8.10.2
|
||||
kotlin 2.0.20
|
||||
kotlin 1.8.22
|
||||
|
|
|
@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
|
|||
android {
|
||||
namespace 'com.freaccess.hub'
|
||||
compileSdkVersion 34
|
||||
compileSdk 34
|
||||
compileSdk 35
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
|
@ -53,8 +53,16 @@ android {
|
|||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
consumerProguardFiles 'proguard-rules.pro'
|
||||
testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"
|
||||
testInstrumentationRunnerArguments clearPackageData: "true"
|
||||
|
||||
}
|
||||
|
||||
testOptions {
|
||||
execution "ANDROIDX_TEST_ORCHESTRATOR"
|
||||
}
|
||||
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
|
@ -73,7 +81,7 @@ android {
|
|||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
debug {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -92,6 +100,8 @@ android {
|
|||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,11 +116,16 @@ dependencies {
|
|||
implementation 'androidx.window:window:1.0.0'
|
||||
implementation 'androidx.window:window-java:1.0.0'
|
||||
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'
|
||||
}
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||
|
||||
androidTestUtil "androidx.test:orchestrator:1.5.1"
|
||||
// androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
// androidTestImplementation 'androidx.test:rules:1.4.0'
|
||||
|
||||
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
|
@ -0,0 +1,36 @@
|
|||
package com.freaccess.hub;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import pl.leancode.patrol.PatrolJUnitRunner;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class MainActivityTest {
|
||||
private final String dartTestName;
|
||||
|
||||
public MainActivityTest(String dartTestName) {
|
||||
this.dartTestName = dartTestName;
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Object[] testCases() {
|
||||
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
|
||||
// replace "MainActivity.class" with "io.flutter.embedding.android.FlutterActivity.class"
|
||||
// if in AndroidManifest.xml in manifest/application/activity you have
|
||||
// android:name="io.flutter.embedding.android.FlutterActivity"
|
||||
instrumentation.setUp(MainActivity.class);
|
||||
instrumentation.waitForPatrolAppService();
|
||||
return instrumentation.listDartTests();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runDartTest() {
|
||||
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
|
||||
instrumentation.runDartTest(dartTestName);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.0.20' // Replace with the latest version
|
||||
ext.kotlin_version = '1.8.22'
|
||||
ext.gradle_version = '8.6.0' // Replace with the latest version
|
||||
ext.google_services_version = '4.4.2' // Replace with the latest version
|
||||
repositories {
|
||||
|
@ -8,12 +8,14 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:$gradle_version" // Use a versão do Gradle que corresponde à sua configuração
|
||||
classpath "com.android.tools.build:gradle:$gradle_version"
|
||||
// Use a versão do Gradle que corresponde à sua configuração
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.google.gms:google-services:$google_services_version" // Google Services plugin
|
||||
}
|
||||
classpath "com.google.gms:google-services:$google_services_version"
|
||||
// Google Services plugin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
|
|
|
@ -20,7 +20,7 @@ plugins {
|
|||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id 'com.android.application' version '8.6.0' apply false
|
||||
id 'com.android.library' version '8.6.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '2.0.20' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
|
||||
|
||||
|
||||
// START: FlutterFire Configuration
|
||||
|
@ -29,8 +29,7 @@ plugins {
|
|||
// id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
||||
// id "org.jetbrains.kotlin.android" version "1.8.10" apply false
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
include ":app"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
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/features/backend/api_requests/index.dart';
|
||||
import 'package:hub/features/local/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/index.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';
|
||||
import 'package:patrol_finders/patrol_finders.dart';
|
||||
|
||||
import 'fuzzer/fuzzer.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';
|
||||
|
||||
late PatrolTester $;
|
||||
|
||||
void main() {
|
||||
//init integration test
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() async {});
|
||||
tearDown(() async {});
|
||||
|
||||
// WelcomeTest.signInToSignUp();
|
||||
// WelcomeTest.signUpToSignIn();
|
||||
|
||||
// AuthenticationTest.signIn();
|
||||
AuthenticationTest.signUp();
|
||||
// AuthenticationTest.signOut();
|
||||
//
|
||||
// ModularizationTest.switchLicense();
|
||||
// ModularizationTest.containLicense();
|
||||
//
|
||||
// MenuTest.navToEntries();
|
||||
// MenuTest.containEntries();
|
||||
// MenuTest.labels2AppbarConsistency();
|
||||
//
|
||||
// LocalsTest.setLocal();
|
||||
// LocalsTest.unlinkLocal();
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class AuthenticationTest {
|
||||
static Future<void> signIn() async {
|
||||
patrolWidgetTest(
|
||||
'Sign-In with fuzzed emails',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester
|
||||
.printToConsole('Authentication Test - Sign-In with fuzzed emails');
|
||||
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
|
||||
|
||||
final Fuzzer fuzzer = Fuzzer(
|
||||
configs: [
|
||||
FuzzConfig(
|
||||
label: 'username',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
FuzzConfig(
|
||||
label: 'domain',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
FuzzConfig(
|
||||
label: 'password',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
],
|
||||
iterations: 10,
|
||||
);
|
||||
Map<String, String> concat(
|
||||
String username, String domain, String password) {
|
||||
return {
|
||||
'emailTextFormField': '${username}@${domain}.com',
|
||||
'passwordTextFormField': password,
|
||||
};
|
||||
}
|
||||
|
||||
final credentials = fuzzer.fuzz(concat);
|
||||
|
||||
await _unlogged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await _navigateToSignIn($);
|
||||
|
||||
for (var credential in credentials) {
|
||||
print('Função: ${credential.functionName}');
|
||||
print('Entradas: ${credential.inputs}');
|
||||
print('Saída: ${credential.output}');
|
||||
print('Mensagem: ${credential.message}');
|
||||
print('---');
|
||||
|
||||
await _auth(credential.output, $, throwsException);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
patrolWidgetTest(
|
||||
'Sign-In with email_app@exemplo.com',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole(
|
||||
'Authentication Test - Sign-In with email_app@exemplo.com');
|
||||
|
||||
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
|
||||
final Map<String, String> credentials = {
|
||||
'emailTextFormField': 'email_app@exemplo.com',
|
||||
'passwordTextFormField': '12345678',
|
||||
};
|
||||
|
||||
await _unlogged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await _navigateToSignIn($);
|
||||
await _auth(credentials, $, throwsException);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> signUp() async {
|
||||
patrolWidgetTest(
|
||||
'Sign Up - credenciais já registradas',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole(
|
||||
'Authentication Test - Sign-Up: credenciais já registradas');
|
||||
|
||||
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
|
||||
final Map<String, String> credentials = {
|
||||
'nameTextFormField': 'app',
|
||||
'emailTextFormField': 'email_app@exemplo.com',
|
||||
'passwordTextFormField': '12345678',
|
||||
};
|
||||
await _unlogged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await _navigateToSignUp($);
|
||||
await _auth(credentials, $, throwsException);
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
},
|
||||
);
|
||||
|
||||
patrolWidgetTest(
|
||||
'Sign Up - credenciais novas',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester
|
||||
.printToConsole('Authentication Test - Sign-Up: credenciais novas');
|
||||
|
||||
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
|
||||
|
||||
final Fuzzer fuzzer = Fuzzer(
|
||||
configs: [
|
||||
FuzzConfig(
|
||||
label: 'name',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
FuzzConfig(
|
||||
label: 'username',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
FuzzConfig(
|
||||
label: 'domain',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 5,
|
||||
maxLength: 10,
|
||||
),
|
||||
FuzzConfig(
|
||||
label: 'password',
|
||||
type: AcceptedTypes.string,
|
||||
minLength: 8,
|
||||
maxLength: 10,
|
||||
),
|
||||
],
|
||||
iterations: 10,
|
||||
);
|
||||
Map<String, String> concat(
|
||||
String name, String username, String domain, String password) {
|
||||
return {
|
||||
'nameTextFormField': name,
|
||||
'emailTextFormField': '${username}@${domain}.test',
|
||||
'passwordTextFormField': password,
|
||||
};
|
||||
}
|
||||
|
||||
final credentials = fuzzer.fuzz(concat);
|
||||
|
||||
await _unlogged();
|
||||
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
|
||||
for (var credential in credentials) {
|
||||
print('Função: ${credential.functionName}');
|
||||
print('Entradas: ${credential.inputs}');
|
||||
print('Saída: ${credential.output}');
|
||||
print('Mensagem: ${credential.message}');
|
||||
print('---');
|
||||
|
||||
await _navigateToSignUp($);
|
||||
await _auth(credential.output, $, throwsException);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> signOut() async {
|
||||
patrolWidgetTest(
|
||||
'Deslogar da Conta',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole(
|
||||
'Authentication Test - Sign-Out: Deslogar da Conta');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidget(const App());
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
await $(Icons.menu_rounded) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
|
||||
await $.waitUntilVisible($(MenuListView));
|
||||
|
||||
await $(Icons.exit_to_app)
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.trySettle);
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> recovery() async {}
|
||||
}
|
||||
|
||||
Future<void> _auth(
|
||||
Map<String, String> credentials,
|
||||
PatrolTester $,
|
||||
PatrolFinder throwsException,
|
||||
) async {
|
||||
await _enterCredentials(credentials, $);
|
||||
await _submit('SubmitButtonWidget', $, throwsException);
|
||||
}
|
||||
|
||||
Future<void> _enterCredentials(
|
||||
Map<String, String> credentials,
|
||||
PatrolTester $,
|
||||
) async {
|
||||
for (var entry in credentials.entries) {
|
||||
await $(ValueKey(entry.key)) //
|
||||
.waitUntilVisible()
|
||||
.enterText(entry.value);
|
||||
await $.pumpAndSettle();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _submit(
|
||||
String key, PatrolTester $, PatrolFinder throwsException) async {
|
||||
await $(ValueKey(key)) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
if ($(ValueKey('ThrowExceptionWidget')).exists) {
|
||||
// expect(throwsException, findsOneWidget);
|
||||
await $(ValueKey('ThrowExceptionWidget')) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
} else {
|
||||
_navigateBackUsingSystemGesture();
|
||||
}
|
||||
}
|
||||
|
||||
String _generateRandomString(int length) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
final rand = Random();
|
||||
return List.generate(length, (index) => chars[rand.nextInt(chars.length)])
|
||||
.join();
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
import 'dart:math';
|
||||
|
||||
enum AcceptedTypes {
|
||||
string,
|
||||
integer,
|
||||
float,
|
||||
stringList,
|
||||
integerList,
|
||||
floatList,
|
||||
}
|
||||
|
||||
class FuzzConfig {
|
||||
final String label;
|
||||
final AcceptedTypes type;
|
||||
final int minLength;
|
||||
final int maxLength;
|
||||
final num minValue;
|
||||
final num maxValue;
|
||||
|
||||
FuzzConfig({
|
||||
required this.label,
|
||||
required this.type,
|
||||
this.minLength = 1,
|
||||
this.maxLength = 10,
|
||||
this.minValue = 0,
|
||||
this.maxValue = 100,
|
||||
});
|
||||
}
|
||||
|
||||
class FuzzerResult {
|
||||
final String functionName;
|
||||
final List<dynamic> inputs;
|
||||
final dynamic output;
|
||||
final String message;
|
||||
|
||||
FuzzerResult({
|
||||
required this.functionName,
|
||||
required this.inputs,
|
||||
this.output,
|
||||
required this.message,
|
||||
});
|
||||
}
|
||||
|
||||
class Fuzzer {
|
||||
final List<FuzzConfig> configs;
|
||||
final int iterations;
|
||||
final Random _random = Random();
|
||||
|
||||
Fuzzer({
|
||||
required this.configs,
|
||||
this.iterations = 100,
|
||||
});
|
||||
|
||||
List<FuzzerResult> fuzz(Function fn) {
|
||||
final results = <FuzzerResult>[];
|
||||
final parameterCount = configs.length;
|
||||
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
final inputs = _generateInputs(parameterCount);
|
||||
try {
|
||||
final output = Function.apply(fn, inputs);
|
||||
results.add(FuzzerResult(
|
||||
functionName: fn.toString(),
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
message: 'Execução bem-sucedida.',
|
||||
));
|
||||
} catch (e) {
|
||||
results.add(FuzzerResult(
|
||||
functionName: fn.toString(),
|
||||
inputs: inputs,
|
||||
message: 'Erro: $e',
|
||||
));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
List<dynamic> _generateInputs(int count) {
|
||||
return List.generate(count, (index) {
|
||||
final config = configs[index];
|
||||
return _generateValue(config);
|
||||
});
|
||||
}
|
||||
|
||||
dynamic _generateValue(FuzzConfig config) {
|
||||
switch (config.type) {
|
||||
case AcceptedTypes.string:
|
||||
final length =
|
||||
_random.nextInt(config.maxLength - config.minLength + 1) +
|
||||
config.minLength;
|
||||
return _generateRandomString(length);
|
||||
case AcceptedTypes.integer:
|
||||
return _random.nextInt(
|
||||
config.maxValue.toInt() - config.minValue.toInt() + 1) +
|
||||
config.minValue.toInt();
|
||||
case AcceptedTypes.float:
|
||||
return _random.nextDouble() * (config.maxValue - config.minValue) +
|
||||
config.minValue;
|
||||
case AcceptedTypes.stringList:
|
||||
final length =
|
||||
_random.nextInt(config.maxLength - config.minLength + 1) +
|
||||
config.minLength;
|
||||
return List.generate(
|
||||
length, (_) => _generateRandomString(_random.nextInt(10) + 1));
|
||||
case AcceptedTypes.integerList:
|
||||
final length =
|
||||
_random.nextInt(config.maxLength - config.minLength + 1) +
|
||||
config.minLength;
|
||||
return List.generate(
|
||||
length,
|
||||
(_) =>
|
||||
_random.nextInt(
|
||||
config.maxValue.toInt() - config.minValue.toInt() + 1) +
|
||||
config.minValue.toInt());
|
||||
case AcceptedTypes.floatList:
|
||||
final length =
|
||||
_random.nextInt(config.maxLength - config.minLength + 1) +
|
||||
config.minLength;
|
||||
return List.generate(
|
||||
length,
|
||||
(_) =>
|
||||
_random.nextDouble() * (config.maxValue - config.minValue) +
|
||||
config.minValue);
|
||||
}
|
||||
}
|
||||
|
||||
String _generateRandomString(int length) {
|
||||
const chars =
|
||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
return String.fromCharCodes(
|
||||
Iterable.generate(
|
||||
length,
|
||||
(_) => chars.codeUnitAt(_random.nextInt(chars.length)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 {}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class LocalsTest {
|
||||
static Future setLocal() async {
|
||||
patrolWidgetTest(
|
||||
'Selecionar um local disponível', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Locals Test - Selecionar um local disponível');
|
||||
|
||||
await _logged(false);
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
await $.waitUntilVisible($(LocalProfileComponentWidget));
|
||||
|
||||
final PatrolFinder profileFinder =
|
||||
$(#AsyncLocalProfileComponentWidget_InkWell);
|
||||
expect(profileFinder, findsOneWidget);
|
||||
|
||||
await $(profileFinder) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
|
||||
final PatrolFinder bottomSheetFinder =
|
||||
await $(BottomArrowLinkedLocalsComponentWidget) //
|
||||
.waitUntilVisible();
|
||||
expect(bottomSheetFinder, findsOneWidget);
|
||||
|
||||
final PatrolFinder listViewFinder = await $(bottomSheetFinder) //
|
||||
.$(ListView)
|
||||
.waitUntilVisible();
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
|
||||
await $.pump(const Duration(milliseconds: 500));
|
||||
|
||||
final PatrolFinder entriesFinder = await $(listViewFinder) //
|
||||
.$(CardItemTemplateComponentWidget)
|
||||
.waitUntilVisible();
|
||||
expect(entriesFinder, findsWidgets);
|
||||
|
||||
if (entriesFinder.evaluate().isNotEmpty) {
|
||||
await $(entriesFinder.first) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
await $.pumpAndSettle();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future unlinkLocal() async {
|
||||
patrolWidgetTest('Desvincular do local selecionado', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Locals Test - Desvincular do local selecionado');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
final PatrolFinder gridView = await $(GridView) //
|
||||
.waitUntilVisible();
|
||||
final PatrolFinder entries = await $(gridView)
|
||||
.$(ButtonMenuItem) //
|
||||
.waitUntilVisible();
|
||||
|
||||
await $.pumpAndSettle();
|
||||
expect(entries, findsWidgets);
|
||||
final PatrolFinder settings = await $(gridView) //
|
||||
.$(Icons.settings)
|
||||
.waitUntilVisible();
|
||||
expect(settings, findsOneWidget);
|
||||
|
||||
await $(settings).tap();
|
||||
|
||||
final PatrolFinder unlinkButton = await $(Symbols.digital_out_of_home) //
|
||||
.waitUntilVisible();
|
||||
expect(unlinkButton, findsOneWidget);
|
||||
await $(unlinkButton) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
|
||||
final PatrolFinder alertDialog = await $(#AlertDialogKey) //
|
||||
.waitUntilVisible();
|
||||
await alertDialog
|
||||
.$(#AcceptOptionKey) //
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
|
||||
await $.pump();
|
||||
await $.pump(const Duration(seconds: 1));
|
||||
await $.pump();
|
||||
|
||||
final PatrolFinder bottomSheetFinder =
|
||||
await $(BottomArrowLinkedLocalsComponentWidget) //
|
||||
.waitUntilVisible();
|
||||
|
||||
expect(bottomSheetFinder, findsOneWidget);
|
||||
|
||||
final PatrolFinder listViewFinder = await $(bottomSheetFinder) //
|
||||
.$(ListView)
|
||||
.waitUntilVisible();
|
||||
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
|
||||
final PatrolFinder entriesFinder = await $(listViewFinder)
|
||||
.$(CardItemTemplateComponentWidget)
|
||||
.waitUntilVisible();
|
||||
|
||||
expect(entriesFinder, findsWidgets);
|
||||
});
|
||||
|
||||
patrolWidgetTest(
|
||||
'Vincular um local desvinculado', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Locals Test - Vincular um local desvinculado');
|
||||
|
||||
await _logged(false);
|
||||
await $.pumpWidget(const App());
|
||||
|
||||
final PatrolFinder bottomSheetFinder =
|
||||
await $(BottomArrowLinkedLocalsComponentWidget) //
|
||||
.waitUntilVisible();
|
||||
expect(bottomSheetFinder, findsOneWidget);
|
||||
|
||||
await $.pump(const Duration(milliseconds: 500));
|
||||
|
||||
final PatrolFinder listViewFinder = $(bottomSheetFinder) //
|
||||
.$(ListView);
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
|
||||
await $.pump(const Duration(milliseconds: 500));
|
||||
|
||||
final PatrolFinder entriesFinder = $(listViewFinder) //
|
||||
.$(CardItemTemplateComponentWidget);
|
||||
expect(entriesFinder, findsWidgets);
|
||||
|
||||
if (entriesFinder.evaluate().isNotEmpty) {
|
||||
await $(entriesFinder.first).waitUntilVisible().tap();
|
||||
|
||||
final PatrolFinder alertDialog = await $(#AlertDialogKey) //
|
||||
.waitUntilVisible();
|
||||
await alertDialog
|
||||
.$(#AcceptOptionKey) //
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// try {
|
||||
// await $.pumpAndSettle(
|
||||
// duration: const Duration(seconds: 2),
|
||||
// phase: EnginePhase.sendSemanticsUpdate,
|
||||
// timeout: const Duration(seconds: 2),
|
||||
// );
|
||||
// throw Exception('Local está vinculado');
|
||||
// } catch (e) {
|
||||
// await Future.delayed(const Duration(milliseconds: 500));
|
||||
// return;
|
||||
// }
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future attachLocal() async {
|
||||
patrolWidgetTest(
|
||||
'Selecionar um local disponível', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
await _logged();
|
||||
await $.pumpWidget(const App());
|
||||
late Map<String, String> credentials;
|
||||
final PatrolFinder throwsException = $('');
|
||||
|
||||
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 $.pumpWidget(const App());
|
||||
await _navigateToSignUp($);
|
||||
await _auth(credentials, $, throwsException);
|
||||
credentials = {
|
||||
'emailTextFormField': email,
|
||||
'passwordTextFormField': password
|
||||
};
|
||||
await _auth(credentials, $, throwsException);
|
||||
|
||||
await $.pumpAndSettle();
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await $.pumpAndSettle();
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
return;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class MenuTest {
|
||||
static Future labels2AppbarConsistency() async {
|
||||
patrolWidgetTest(
|
||||
'As labels dos menuItems correspondem aos títulos das AppBars?', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole(
|
||||
'Menu Test - As labels dos menuItems correspondem aos títulos das AppBars?');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
await $.waitUntilVisible($(LocalProfileComponentWidget));
|
||||
|
||||
final PatrolFinder profileFinder =
|
||||
await $(#AsyncLocalProfileComponentWidget_InkWell)
|
||||
.waitUntilVisible();
|
||||
expect(profileFinder, findsOneWidget);
|
||||
|
||||
await $(profileFinder) //
|
||||
.waitUntilVisible()
|
||||
.tap();
|
||||
|
||||
final PatrolFinder bottomSheetFinder =
|
||||
await $(BottomArrowLinkedLocalsComponentWidget) //
|
||||
.waitUntilVisible();
|
||||
expect(bottomSheetFinder, findsOneWidget);
|
||||
|
||||
final PatrolFinder listViewFinder = await $(bottomSheetFinder) //
|
||||
.$(ListView)
|
||||
.waitUntilVisible();
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
|
||||
final PatrolFinder entriesFinder = await $(listViewFinder) //
|
||||
.$(CardItemTemplateComponentWidget)
|
||||
.waitUntilVisible();
|
||||
expect(entriesFinder, findsWidgets);
|
||||
|
||||
if (entriesFinder.evaluate().isNotEmpty) {
|
||||
await $(entriesFinder.first) //
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
}
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
await $.waitUntilVisible($(LocalProfileComponentWidget));
|
||||
|
||||
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();
|
||||
|
||||
final LinkedHashMap<String, String> routesTitles = LinkedHashMap //
|
||||
.fromIterables(routes, titles);
|
||||
|
||||
late String route;
|
||||
late String title;
|
||||
|
||||
for (final entry in routesTitles.entries) {
|
||||
route = entry.key;
|
||||
title = entry.value;
|
||||
|
||||
print('route: $route');
|
||||
print('title: $title');
|
||||
|
||||
if (route == '/petsPage') continue;
|
||||
if (route == '/fastPassPage') continue;
|
||||
if (route == '/reservation') continue;
|
||||
if (route == '/petsOnThePropertyPage') continue;
|
||||
if (route == '/registerVisitorPage') continue;
|
||||
if (route == '/messageHistoryPage') continue;
|
||||
if (route == '/packageOrder') continue;
|
||||
if (route == '/provisionalHistoryPage') continue;
|
||||
if (route == '/scheduleCompleteVisitPage') continue;
|
||||
if (route == '/preferencesSettings') continue;
|
||||
|
||||
ff.navigatorKey.currentContext!.go(route);
|
||||
|
||||
final PatrolFinder appBar = await $(AppBar) //
|
||||
.waitUntilExists();
|
||||
final PatrolFinder titleAppBar = await appBar //
|
||||
.$(title)
|
||||
.waitUntilVisible();
|
||||
expect(titleAppBar, findsOneWidget);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future containEntries() async {
|
||||
patrolWidgetTest(
|
||||
'HomeMenu contém seus itens?', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Menu Test - HomeMenu contém seus itens?');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
await $.waitUntilVisible($(GridView));
|
||||
final PatrolFinder gridEntries = await $(GridView) //
|
||||
.$(ButtonMenuItem)
|
||||
.waitUntilVisible();
|
||||
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 $.pumpAndSettle();
|
||||
final List<MenuEntry> entries = MenuEntry.entries;
|
||||
await $.pumpAndSettle();
|
||||
final List<String> entriesKey = entries
|
||||
.where((entry) => entry.types.contains(MenuEntryType.Home))
|
||||
.map((entry) => entry.key)
|
||||
.toList();
|
||||
await $.pumpAndSettle();
|
||||
expect(entriesKey, containsAll(menuKeys));
|
||||
},
|
||||
);
|
||||
|
||||
patrolWidgetTest(
|
||||
'DrawerMenu contém seus itens?', //
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Menu Test - DrawerMenu contém seus itens?');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
await $.waitUntilVisible($(GridView));
|
||||
final PatrolFinder gridEntries = await $(GridView) //
|
||||
.$(ButtonMenuItem)
|
||||
.waitUntilVisible();
|
||||
expect(gridEntries, findsWidgets);
|
||||
|
||||
await $(Icons.menu_rounded).waitUntilVisible().tap();
|
||||
await $.waitUntilVisible($(ListView));
|
||||
final PatrolFinder listEntries = await $(ListView) //
|
||||
.$(CardMenuItem)
|
||||
.waitUntilVisible();
|
||||
expect(listEntries, findsWidgets);
|
||||
|
||||
final List<String?> menuKeys = listEntries
|
||||
.evaluate()
|
||||
.map((element) {
|
||||
final key = element.widget.key;
|
||||
if (key is ValueKey<String>) {
|
||||
return key.value;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.where((key) => key != null)
|
||||
.toList();
|
||||
|
||||
await $.pumpAndSettle();
|
||||
final List<MenuEntry> entries = MenuEntry.entries;
|
||||
await $.pumpAndSettle();
|
||||
final List<String> entriesKey = entries
|
||||
.where((entry) => entry.types.contains(MenuEntryType.Drawer))
|
||||
.map((entry) => entry.key)
|
||||
.toList();
|
||||
await $.pumpAndSettle();
|
||||
expect(entriesKey, containsAll(menuKeys));
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future navToEntries() async {
|
||||
patrolWidgetTest(
|
||||
'Navegação entre items do Menu',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Menu Test - Navegação entre items do Menu');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
final PatrolFinder profile =
|
||||
$(const Key('AsyncLocalProfileComponentWidget_InkWell'));
|
||||
await $(profile)
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
await $.waitUntilVisible($(BottomArrowLinkedLocalsComponentWidget));
|
||||
|
||||
final PatrolFinder local = $('FRE ACCESS DEMO');
|
||||
await $(local)
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
final Finder gridView = find.byType(GridView);
|
||||
await $.waitUntilVisible(gridView);
|
||||
final Finder gridEntries = find.descendant(
|
||||
of: gridView,
|
||||
matching: find.byType(ButtonMenuItem),
|
||||
);
|
||||
await $.pumpAndSettle();
|
||||
expect(gridEntries, findsWidgets);
|
||||
final int gridEntriesCount = gridEntries.evaluate().length;
|
||||
await $.pumpAndSettle();
|
||||
|
||||
for (int i = 0; i < gridEntriesCount; i++) {
|
||||
await $.waitUntilVisible(
|
||||
$(MenuStaggeredView),
|
||||
timeout: Duration(seconds: 1),
|
||||
);
|
||||
await $.waitUntilVisible(
|
||||
gridView,
|
||||
timeout: Duration(seconds: 1),
|
||||
);
|
||||
await $.waitUntilVisible(
|
||||
gridEntries.at(i),
|
||||
timeout: Duration(seconds: 1),
|
||||
);
|
||||
|
||||
final ButtonMenuItem entry =
|
||||
$.tester.widget<ButtonMenuItem>(gridEntries.at(i));
|
||||
final Key? widgetKey = entry.key;
|
||||
expect(widgetKey, isNotNull);
|
||||
|
||||
print('WIDGETKEY = $widgetKey');
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-FASTPASS')) continue;
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-QRCODE')) continue;
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-RESERVATIONS')) continue;
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-SETTINGS')) continue;
|
||||
|
||||
await $(gridEntries.at(i))
|
||||
.waitUntilVisible(timeout: const Duration(seconds: 1))
|
||||
.tap(
|
||||
settleTimeout: const Duration(seconds: 1),
|
||||
settlePolicy: SettlePolicy.noSettle,
|
||||
);
|
||||
|
||||
await $.pumpAndSettle(duration: Duration(milliseconds: 500));
|
||||
|
||||
await $(Icons.keyboard_arrow_left)
|
||||
.waitUntilVisible(timeout: const Duration(seconds: 1))
|
||||
.tap(
|
||||
settleTimeout: const Duration(seconds: 1),
|
||||
settlePolicy: SettlePolicy.noSettle,
|
||||
);
|
||||
|
||||
await $.pumpAndSettle(duration: Duration(milliseconds: 500));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class ModularizationTest {
|
||||
static Future containLicense() async {
|
||||
patrolWidgetTest('Os modulos de licença está sendo processados?',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole(
|
||||
'Modularization Test - Os modulos de licença está sendo processados?');
|
||||
|
||||
await _logged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
final LicenseRepository licenseRepository = LicenseRepositoryImpl();
|
||||
final List<String> result = await licenseRepository.getLicense();
|
||||
expect(result, isNotEmpty);
|
||||
|
||||
await $.pumpAndSettle();
|
||||
|
||||
final List<MenuEntry> entries = MenuEntry.entries;
|
||||
final List<String> entriesKey = entries
|
||||
.where((entry) => entry.types.contains(MenuEntryType.Home))
|
||||
.map((entry) => '{key: ${entry.key}}')
|
||||
.toList();
|
||||
expect(result, containsAll(entriesKey));
|
||||
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
static Future switchLicense() async {
|
||||
patrolWidgetTest(
|
||||
'Licença está sendo atualizada?',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Licença está sendo atualizada?');
|
||||
|
||||
await _logged();
|
||||
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await $.waitUntilVisible($(MenuStaggeredView));
|
||||
|
||||
final PatrolFinder profile =
|
||||
$(const Key('AsyncLocalProfileComponentWidget_InkWell'));
|
||||
await $(profile)
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.noSettle);
|
||||
await $.waitUntilVisible($(BottomArrowLinkedLocalsComponentWidget));
|
||||
|
||||
final PatrolFinder local = $('FRE ACCESS DEMO');
|
||||
await $(local)
|
||||
.waitUntilVisible()
|
||||
.tap(settlePolicy: SettlePolicy.trySettle);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class notifyTest {}
|
|
@ -0,0 +1,27 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:patrol/patrol.dart';
|
||||
|
||||
void main() {
|
||||
patrolTest(
|
||||
'counter state is the same after going to home and switching apps',
|
||||
($) async {
|
||||
// Replace later with your app's main widget
|
||||
await $.pumpWidgetAndSettle(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('app')),
|
||||
backgroundColor: Colors.blue,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect($('app'), findsOneWidget);
|
||||
if (!Platform.isMacOS) {
|
||||
await $.native.pressHome();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
part of 'app_test.dart';
|
|
@ -0,0 +1,3 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class propertyTest {}
|
|
@ -0,0 +1,3 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class settingTest {}
|
|
@ -0,0 +1,3 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class storageTest {}
|
|
@ -0,0 +1,86 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND AND DO NOT COMMIT TO VERSION CONTROL
|
||||
// ignore_for_file: type=lint, invalid_use_of_internal_member
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:patrol/patrol.dart';
|
||||
import 'package:patrol/src/native/contracts/contracts.dart';
|
||||
import 'package:test_api/src/backend/invoker.dart';
|
||||
|
||||
// START: GENERATED TEST IMPORTS
|
||||
import 'app_test.dart' as app_test;
|
||||
// END: GENERATED TEST IMPORTS
|
||||
|
||||
Future<void> main() async {
|
||||
// This is the entrypoint of the bundled Dart test.
|
||||
//
|
||||
// Its responsibilies are:
|
||||
// * Running a special Dart test that runs before all the other tests and
|
||||
// explores the hierarchy of groups and tests.
|
||||
// * Hosting a PatrolAppService, which the native side of Patrol uses to get
|
||||
// the Dart tests, and to request execution of a specific Dart test.
|
||||
//
|
||||
// When running on Android, the Android Test Orchestrator, before running the
|
||||
// tests, makes an initial run to gather the tests that it will later run. The
|
||||
// native side of Patrol (specifically: PatrolJUnitRunner class) is hooked
|
||||
// into the Android Test Orchestrator lifecycle and knows when that initial
|
||||
// run happens. When it does, PatrolJUnitRunner makes an RPC call to
|
||||
// PatrolAppService and asks it for Dart tests.
|
||||
//
|
||||
// When running on iOS, the native side of Patrol (specifically: the
|
||||
// PATROL_INTEGRATION_TEST_IOS_RUNNER macro) makes an initial run to gather
|
||||
// the tests that it will later run (same as the Android). During that initial
|
||||
// run, it makes an RPC call to PatrolAppSevice and asks it for Dart tests.
|
||||
//
|
||||
// Once the native runner has the list of Dart tests, it dynamically creates
|
||||
// native test cases from them. On Android, this is done using the
|
||||
// Parametrized JUnit runner. On iOS, new test case methods are swizzled into
|
||||
// the RunnerUITests class, taking advantage of the very dynamic nature of
|
||||
// Objective-C runtime.
|
||||
//
|
||||
// Execution of these dynamically created native test cases is then fully
|
||||
// managed by the underlying native test framework (JUnit on Android, XCTest
|
||||
// on iOS). The native test cases do only one thing - request execution of the
|
||||
// Dart test (out of which they had been created) and wait for it to complete.
|
||||
// The result of running the Dart test is the result of the native test case.
|
||||
|
||||
final nativeAutomator = NativeAutomator(config: NativeAutomatorConfig());
|
||||
await nativeAutomator.initialize();
|
||||
final binding = PatrolBinding.ensureInitialized(NativeAutomatorConfig());
|
||||
final testExplorationCompleter = Completer<DartGroupEntry>();
|
||||
|
||||
// A special test to explore the hierarchy of groups and tests. This is a hack
|
||||
// around https://github.com/dart-lang/test/issues/1998.
|
||||
//
|
||||
// This test must be the first to run. If not, the native side likely won't
|
||||
// receive any tests, and everything will fall apart.
|
||||
test('patrol_test_explorer', () {
|
||||
// Maybe somewhat counterintuitively, this callback runs *after* the calls
|
||||
// to group() below.
|
||||
final topLevelGroup = Invoker.current!.liveTest.groups.first;
|
||||
final dartTestGroup = createDartTestGroup(topLevelGroup,
|
||||
tags: null,
|
||||
excludeTags: null,
|
||||
);
|
||||
testExplorationCompleter.complete(dartTestGroup);
|
||||
print('patrol_test_explorer: obtained Dart-side test hierarchy:');
|
||||
reportGroupStructure(dartTestGroup);
|
||||
});
|
||||
|
||||
// START: GENERATED TEST GROUPS
|
||||
group('app_test', app_test.main);
|
||||
// END: GENERATED TEST GROUPS
|
||||
|
||||
final dartTestGroup = await testExplorationCompleter.future;
|
||||
final appService = PatrolAppService(topLevelDartTestGroup: dartTestGroup);
|
||||
binding.patrolAppService = appService;
|
||||
await runAppService(appService);
|
||||
|
||||
// Until now, the native test runner was waiting for us, the Dart side, to
|
||||
// come alive. Now that we did, let's tell it that we're ready to be asked
|
||||
// about Dart tests.
|
||||
await nativeAutomator.markPatrolAppServiceReady();
|
||||
|
||||
await appService.testExecutionCompleted;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
Future<void> _logged([bool forceLinkedLocal = true]) 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(SecureStorageKey.email.value, 'email_app@exemplo.com');
|
||||
await StorageHelper() //
|
||||
.set(SecureStorageKey.password.value, '123456');
|
||||
await StorageHelper() //
|
||||
.set(LocalsStorageKey.isNewVersion.key, true);
|
||||
if (forceLinkedLocal == true) {
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await PhpGroup //
|
||||
.resopndeVinculo
|
||||
.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl() //
|
||||
.resetLicense();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _unlogged() 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> _navigateToSignIn(PatrolTester $) async {
|
||||
final signInButton = $(#toggleSignInPage).waitUntilVisible();
|
||||
await signInButton.tap();
|
||||
}
|
||||
|
||||
Future<void> _navigateToSignUp(PatrolTester $) async {
|
||||
final signUpButton = $(#toggleSignUpPage).waitUntilVisible();
|
||||
await signUpButton.tap();
|
||||
}
|
||||
|
||||
Future<void> _navigateBackUsingSystemGesture() async =>
|
||||
IntegrationTestWidgetsFlutterBinding.instance.keyboard
|
||||
.isLogicalKeyPressed(LogicalKeyboardKey.escape);
|
|
@ -0,0 +1,31 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
class WelcomeTest {
|
||||
static Future signInToSignUp() async {
|
||||
patrolWidgetTest(
|
||||
'Sign-In to Sign-Up',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Welcome Test - Sign-In to Sign-Up');
|
||||
await _unlogged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await _navigateToSignIn($);
|
||||
await _navigateToSignUp($);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Future signUpToSignIn() async {
|
||||
patrolWidgetTest(
|
||||
'Sign-Up to Sign-In',
|
||||
(PatrolTester tester) async {
|
||||
$ = tester;
|
||||
$.tester.printToConsole('Welcome Test - Sign-Up to Sign-In');
|
||||
await _unlogged();
|
||||
await $.pumpWidgetAndSettle(const App());
|
||||
await _navigateToSignUp($);
|
||||
await _navigateToSignIn($);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,9 +7,11 @@ class AppBarUtil extends StatelessWidget implements PreferredSizeWidget {
|
|||
final String title;
|
||||
final VoidCallback? onBackButtonPressed;
|
||||
final Widget? actionButton;
|
||||
final Key appBarKey;
|
||||
|
||||
const AppBarUtil({
|
||||
super.key,
|
||||
required this.appBarKey,
|
||||
required this.title,
|
||||
this.onBackButtonPressed,
|
||||
this.actionButton,
|
||||
|
@ -18,6 +20,7 @@ class AppBarUtil extends StatelessWidget implements PreferredSizeWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
key: appBarKey,
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
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/templates_components/card_item_template_component/card_item_template_component_widget.dart';
|
||||
|
@ -202,7 +204,9 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
}
|
||||
|
||||
Widget _item(BuildContext context, dynamic local) {
|
||||
log('local: ${local['CLI_NOME']}');
|
||||
return CardItemTemplateComponentWidget(
|
||||
key: ValueKey<String>(local['CLI_NOME']),
|
||||
imagePath: _imagePath(local),
|
||||
labelsHashMap: _labelsHashMap(local),
|
||||
statusHashMap: [_statusHashMap(local)],
|
||||
|
|
|
@ -218,6 +218,7 @@ class _CardItemTemplateComponentWidgetState
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
key: widget.key,
|
||||
splashColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
|
||||
import '/flutter_flow/flutter_flow_theme.dart';
|
||||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
import '/flutter_flow/flutter_flow_widgets.dart';
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'qr_code_pass_key_template_component_model.dart';
|
||||
|
||||
export 'qr_code_pass_key_template_component_model.dart';
|
||||
|
||||
class QrCodePassKeyTemplateComponentWidget extends StatefulWidget {
|
||||
|
|
|
@ -7,11 +7,14 @@ import 'sign_in_template_component_widget.dart'
|
|||
class SignInTemplateComponentModel
|
||||
extends FlutterFlowModel<SignInTemplateComponentWidget> {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
|
||||
final unfocusNode = FocusNode();
|
||||
FocusNode? emailAddressFocusNode;
|
||||
TextEditingController? emailAddressTextController;
|
||||
String? Function(BuildContext, String?)? emailAddressTextControllerValidator;
|
||||
|
||||
SignInTemplateComponentModel();
|
||||
|
||||
String? _emailAddressTextControllerValidator(
|
||||
BuildContext context, String? val) {
|
||||
if (val == null || val.isEmpty) {
|
||||
|
@ -32,6 +35,7 @@ class SignInTemplateComponentModel
|
|||
TextEditingController? passwordTextController;
|
||||
late bool passwordVisibility;
|
||||
String? Function(BuildContext, String?)? passwordTextControllerValidator;
|
||||
|
||||
String? _passwordTextControllerValidator(BuildContext context, String? val) {
|
||||
if (val == null || val.isEmpty) {
|
||||
return FFLocalizations.of(context).getText(
|
||||
|
|
|
@ -148,6 +148,7 @@ class AuthenticationService {
|
|||
|
||||
await StorageHelper().clean(Storage.databaseStorage);
|
||||
await StorageHelper().clean(Storage.secureStorage);
|
||||
|
||||
DatabaseService.isInitialized = false;
|
||||
await DatabaseService.instance.init();
|
||||
|
||||
|
|
|
@ -18,7 +18,11 @@ const _kPrivateApiFunctionName = 'ffPrivateApiCall';
|
|||
|
||||
/// Start PHP Group Code
|
||||
|
||||
class PhpGroup {
|
||||
abstract class Api {
|
||||
GetLicense getLicense = GetLicense();
|
||||
}
|
||||
|
||||
class PhpGroup extends Api {
|
||||
static String getBaseUrl() => 'https://freaccess.com.br/freaccess';
|
||||
static Map<String, String> headers = {};
|
||||
static LoginCall loginCall = LoginCall();
|
||||
|
@ -62,7 +66,7 @@ class PhpGroup {
|
|||
static GetResidentsByProperty getResidentsByProperty =
|
||||
GetResidentsByProperty();
|
||||
static GetOpenedVisits getOpenedVisits = GetOpenedVisits();
|
||||
static GetLicense getLicense = GetLicense();
|
||||
GetLicense getLicense = GetLicense();
|
||||
static GetProvSchedules getProvSchedules = GetProvSchedules();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
|||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
import 'package:hub/shared/utils/snackbar_util.dart';
|
||||
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
@immutable
|
||||
|
@ -92,6 +91,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -11,11 +11,18 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||
|
||||
HomeBloc() : super(HomeState()) {
|
||||
on<HomeEvent>(_onHomeEvent);
|
||||
|
||||
_completer = LocalsRepositoryImpl.license.stream.listen((v) {
|
||||
add(HomeEvent());
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_completer.cancel();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
Future<void> _onHomeEvent(HomeEvent event, Emitter<HomeState> emit) async {
|
||||
final devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
|
|
@ -2,12 +2,11 @@ import 'package:flutter/gestures.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
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/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';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
|
||||
class HomePageWidget extends StatefulWidget {
|
||||
const HomePageWidget(this.update, {super.key});
|
||||
|
|
|
@ -25,6 +25,9 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource {
|
|||
Future<String?> get(String key) async {
|
||||
final String? local =
|
||||
await StorageHelper().get(ProfileStorageKey.clientUUID.key);
|
||||
if (local == null) {
|
||||
return null;
|
||||
}
|
||||
var response = await DatabaseService.database.query(
|
||||
LocalsConstants.tableLocalsKeychain,
|
||||
where: 'key = ? AND local = ?',
|
||||
|
|
|
@ -38,6 +38,12 @@ class LocalProfileBloc extends Bloc<LocalProfileEvent, LocalProfileState> {
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_completer.cancel();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
Future<void> _onLocalProfileEvent(
|
||||
LocalProfileEvent event, Emitter<LocalProfileState> emit) async {
|
||||
final cliName =
|
||||
|
|
|
@ -87,6 +87,8 @@ class _LocalProfileComponentWidgetState
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: InkWell(
|
||||
key: const Key(
|
||||
'DefaultLocalProfileComponentWidget_InkWell'),
|
||||
splashColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
@ -180,6 +182,8 @@ class _LocalProfileComponentWidgetState
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: InkWell(
|
||||
key: const Key(
|
||||
'AsyncLocalProfileComponentWidget_InkWell'),
|
||||
splashColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
|
|
@ -9,29 +9,41 @@ import 'package:hub/shared/extensions/dialog_extensions.dart';
|
|||
import 'package:hub/shared/utils/path_util.dart';
|
||||
|
||||
abstract class MenuLocalDataSource {
|
||||
Future<MenuItem?> addMenuEntry(EnumMenuItem item, List<MenuItem?> entries,
|
||||
IconData icon, String text, Function() action);
|
||||
Future<MenuItem?> addMenuEntry(Key key, EnumMenuItem item,
|
||||
List<MenuItem?> entries, IconData icon, String text, Function() action);
|
||||
|
||||
Future<bool> processDisplayDefault(
|
||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
|
||||
|
||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
|
||||
List<MenuItem?> entries);
|
||||
|
||||
Future<bool> processStartDate(String startDate, MenuEntry entry);
|
||||
|
||||
Future<bool> processExpirationDate(String expirationDate, MenuEntry entry);
|
||||
}
|
||||
|
||||
class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||
static final MenuLocalDataSourceImpl _instance =
|
||||
MenuLocalDataSourceImpl._internal();
|
||||
|
||||
factory MenuLocalDataSourceImpl() => _instance;
|
||||
|
||||
MenuLocalDataSourceImpl._internal();
|
||||
|
||||
@override
|
||||
Future<MenuItem?> addMenuEntry(EnumMenuItem item, List<MenuItem?> entries,
|
||||
IconData icon, String text, Function() action) async {
|
||||
Future<MenuItem?> addMenuEntry(
|
||||
Key key,
|
||||
EnumMenuItem item,
|
||||
List<MenuItem?> entries,
|
||||
IconData icon,
|
||||
String text,
|
||||
Function() action,
|
||||
) async {
|
||||
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
|
||||
? CardMenuItem(icon: icon, action: action, title: text)
|
||||
? CardMenuItem(key: key, icon: icon, action: action, title: text)
|
||||
: null;
|
||||
if (menuItem != null) {
|
||||
entries.add(menuItem);
|
||||
|
@ -43,7 +55,9 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
|||
Future<bool> processDisplayDefault(
|
||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
|
||||
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!);
|
||||
});
|
||||
return true;
|
||||
|
@ -57,12 +71,16 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
|||
try {
|
||||
switch (display.value) {
|
||||
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);
|
||||
});
|
||||
break;
|
||||
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(
|
||||
navigatorKey.currentContext!);
|
||||
});
|
||||
|
|
|
@ -2,24 +2,24 @@ import 'dart:developer';
|
|||
|
||||
import 'package:hub/features/menu/index.dart';
|
||||
import 'package:hub/features/module/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/flutter_flow/custom_functions.dart';
|
||||
|
||||
class MenuRepositoryImpl implements MenuRepository {
|
||||
final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl();
|
||||
|
||||
@override
|
||||
Future<List<MenuItem?>> generateMenuEntries(
|
||||
List<MenuEntry> menuEntries, EnumMenuItem item) async {
|
||||
Future<List<MenuItem?>> entries2Items(
|
||||
List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
|
||||
List<MenuItem?> entries = [];
|
||||
// final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean());
|
||||
|
||||
try {
|
||||
for (var entry in menuEntries) {
|
||||
final bool isDefault =
|
||||
await menuDataSource.processDisplayDefault(item, entry, entries);
|
||||
final bool isDefault = await menuDataSource.processDisplayDefault(
|
||||
menuItem, entry, entries);
|
||||
if (isDefault) continue;
|
||||
final licenseValue =
|
||||
await LicenseRepositoryImpl().getLicense(entry.key);
|
||||
final licenseValue = await LicenseRepositoryImpl().getModule(entry.key);
|
||||
if (licenseValue != null) {
|
||||
final licenseMap = await stringToMap(licenseValue);
|
||||
final display = EnumDisplay.fromString(licenseMap['display']);
|
||||
|
@ -30,17 +30,17 @@ class MenuRepositoryImpl implements MenuRepository {
|
|||
final isExpired =
|
||||
await menuDataSource.processExpirationDate(expirationDate, entry);
|
||||
if (isStarted && !isExpired) {
|
||||
await menuDataSource.handleMenu(item, display, entry, entries);
|
||||
await menuDataSource.handleMenu(menuItem, display, entry, entries);
|
||||
}
|
||||
if (isExpired) {
|
||||
log('Entry ${entry.key} is expired');
|
||||
await menuDataSource.handleMenu(
|
||||
item, EnumDisplay.inactive, entry, entries);
|
||||
menuItem, EnumDisplay.inactive, entry, entries);
|
||||
}
|
||||
if (!isStarted) {
|
||||
log('Entry ${entry.key} is not started');
|
||||
await menuDataSource.handleMenu(
|
||||
item, EnumDisplay.inactive, entry, entries);
|
||||
menuItem, EnumDisplay.inactive, entry, entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class MenuRepositoryImpl implements MenuRepository {
|
|||
if (await _shouldUpdateDisplay(module, isNewVersion)) {
|
||||
final displayValue =
|
||||
module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL';
|
||||
await LicenseLocalDataSourceImpl()
|
||||
await LicenseLocalDataSourceImpl(DatabaseService.database)
|
||||
.setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue);
|
||||
return EnumDisplay.fromString(displayValue);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:hub/features/menu/index.dart';
|
||||
|
||||
abstract class MenuRepository {
|
||||
Future<List<MenuItem?>> generateMenuEntries(
|
||||
Future<List<MenuItem?>> entries2Items(
|
||||
List<MenuEntry> menuEntries, EnumMenuItem item);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.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/module/index.dart';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
|
||||
class MenuEvent {}
|
||||
|
||||
|
@ -36,10 +37,10 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||
}
|
||||
|
||||
Future<void> _onMenuEvent(MenuEvent event, Emitter<MenuState> emit) async {
|
||||
await LicenseRemoteDataSourceImpl().waitForSaveCompletion();
|
||||
await LicenseRemoteDataSourceImpl(PhpGroup()).waitForSaveCompletion();
|
||||
|
||||
final List<MenuItem?> newEntries =
|
||||
await MenuRepositoryImpl().generateMenuEntries(entries, item);
|
||||
await MenuRepositoryImpl().entries2Items(entries, item);
|
||||
emit(state.copyWith(menuEntries: newEntries));
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class MenuEntry implements BaseModule {
|
|||
icon: Icons.sports_motorsports_outlined,
|
||||
name: FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
|
||||
ptText: 'Agendar Entregas',
|
||||
enText: 'Schedule Delivery',
|
||||
enText: 'Delivery Schedule',
|
||||
),
|
||||
route: '/deliverySchedule',
|
||||
types: [MenuEntryType.Home, MenuEntryType.Drawer],
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/features/menu/index.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||
|
||||
class CardMenuItem extends MenuItem {
|
||||
const CardMenuItem({
|
||||
|
@ -35,11 +36,11 @@ class _MenuCardItemState extends State<CardMenuItem> {
|
|||
onTap: _isProcessing
|
||||
? null
|
||||
: () async {
|
||||
setState(() {
|
||||
safeSetState(() {
|
||||
_isProcessing = true;
|
||||
});
|
||||
await widget.action.call();
|
||||
setState(() {
|
||||
safeSetState(() {
|
||||
_isProcessing = false;
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,21 +1,41 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:hub/features/module/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/shared/extensions/string_extensions.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
abstract class LicenseLocalDataSource {
|
||||
Future<void> init();
|
||||
|
||||
Future<void> setDisplayByKey(final List<String> key, final String display);
|
||||
|
||||
Future<bool> isNewVersion();
|
||||
|
||||
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<bool> setupLicense(bool isNewVersion);
|
||||
|
||||
Future<List<String>> getLicense();
|
||||
|
||||
Future<void> clear();
|
||||
}
|
||||
|
||||
class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
|
||||
Database? _database;
|
||||
|
||||
static final LicenseLocalDataSourceImpl _instance =
|
||||
LicenseLocalDataSourceImpl._internal();
|
||||
factory LicenseLocalDataSourceImpl() => _instance;
|
||||
|
||||
factory LicenseLocalDataSourceImpl(Database database) {
|
||||
_instance._database ??= database;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
LicenseLocalDataSourceImpl._internal();
|
||||
|
||||
@override
|
||||
|
@ -23,6 +43,38 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
|
|||
await DatabaseService.instance.init();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> setupLicense(bool isNewVersion) async {
|
||||
log('Setting up license...');
|
||||
try {
|
||||
final License license = await License.getLicense(isNewVersion);
|
||||
|
||||
final List<String> inactiveModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.inactive.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
final List<String> activeModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.active.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
final List<String> disabledModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.disabled.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
await setDisplayByKey(inactiveModuleKey, 'INVISIVEL');
|
||||
await setDisplayByKey(activeModuleKey, 'VISIVEL');
|
||||
await setDisplayByKey(disabledModuleKey, 'DESABILITADO');
|
||||
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
log('Erro ao configurar licenças: $e', stackTrace: s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setDisplayByKey(
|
||||
final List<String> keys, final String display) async {
|
||||
|
@ -48,9 +100,9 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
|
|||
|
||||
@override
|
||||
Future<String?> get(String key) async {
|
||||
var response = await DatabaseService.database
|
||||
.query(tableLicense, where: 'key = ?', whereArgs: [key]);
|
||||
if (response.isEmpty) {
|
||||
var response = await _instance._database
|
||||
?.query(tableLicense, where: 'key = ?', whereArgs: [key]);
|
||||
if (response!.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -58,12 +110,12 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> set<T>(String key, T value) async {
|
||||
Future<bool> set<T>(String key, T value) async {
|
||||
value as Map<String, dynamic>;
|
||||
if (value.isEmpty) return;
|
||||
if (key == 'null') return;
|
||||
if (value.isEmpty) return false;
|
||||
if (key == 'null') return false;
|
||||
|
||||
await DatabaseService.database.rawInsert(
|
||||
await _instance._database?.rawInsert(
|
||||
'INSERT OR REPLACE INTO $tableLicense (key, display, expirationDate, startDate, quantity) VALUES (?, ?, ?, ?, ?)',
|
||||
[
|
||||
key,
|
||||
|
@ -73,17 +125,27 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource {
|
|||
value['quantity']
|
||||
],
|
||||
);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> del(String key) async {
|
||||
await DatabaseService.database
|
||||
.delete(tableLicense, where: 'key = ?', whereArgs: [key]);
|
||||
await _instance._database
|
||||
?.delete(tableLicense, where: 'key = ?', whereArgs: [key]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clear() async {
|
||||
await DatabaseService.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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,60 +6,36 @@ import 'dart:developer';
|
|||
import 'package:hub/features/backend/index.dart';
|
||||
import 'package:hub/features/local/data/repositories/locals_repository_impl.dart';
|
||||
import 'package:hub/features/module/index.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
abstract class LicenseRemoteDataSource {
|
||||
Future<bool> fetchLicenses(bool isNewVersion);
|
||||
Future<void> cleanLicense();
|
||||
Future<bool> cleanLicense();
|
||||
Future<void> processLicense();
|
||||
Future<bool> setupLicense(Database database, bool isNewVersion);
|
||||
}
|
||||
|
||||
class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
Api? _api;
|
||||
|
||||
static final LicenseRemoteDataSourceImpl _instance =
|
||||
LicenseRemoteDataSourceImpl._internal();
|
||||
factory LicenseRemoteDataSourceImpl() => _instance;
|
||||
|
||||
factory LicenseRemoteDataSourceImpl(Api api) {
|
||||
_instance._api ??= api;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
LicenseRemoteDataSourceImpl._internal();
|
||||
|
||||
@override
|
||||
Future<void> processLicense() async {}
|
||||
|
||||
@override
|
||||
Future<void> cleanLicense() async {
|
||||
LocalsRepositoryImpl.license.add(false);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> setupLicense(Database database, bool isNewVersion) async {
|
||||
log('Setting up license...');
|
||||
Future<bool> cleanLicense() async {
|
||||
try {
|
||||
final License license = await License.getLicense(isNewVersion);
|
||||
|
||||
final List<String> inactiveModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.inactive.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
final List<String> activeModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.active.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
final List<String> disabledModuleKey = license.modules
|
||||
.where((module) => module.display == ModuleStatus.disabled.key)
|
||||
.map((module) => module.key)
|
||||
.toList();
|
||||
|
||||
await LicenseLocalDataSourceImpl()
|
||||
.setDisplayByKey(inactiveModuleKey, 'INVISIVEL');
|
||||
await LicenseLocalDataSourceImpl()
|
||||
.setDisplayByKey(activeModuleKey, 'VISIVEL');
|
||||
await LicenseLocalDataSourceImpl()
|
||||
.setDisplayByKey(disabledModuleKey, 'DESABILITADO');
|
||||
|
||||
LocalsRepositoryImpl.license.add(false);
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
log('Erro ao configurar licenças: $e', stackTrace: s);
|
||||
log('Erro ao limpar licenças: $e', stackTrace: s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -68,8 +44,8 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
|||
Future<bool> fetchLicenses(bool isNewVersion) async {
|
||||
log('Fetching licenses...');
|
||||
try {
|
||||
final response = await PhpGroup.getLicense();
|
||||
final dynamic responseBody = response.jsonBody;
|
||||
final response = await _instance._api?.getLicense();
|
||||
final dynamic responseBody = response!.jsonBody;
|
||||
|
||||
if (responseBody == []) {
|
||||
return true;
|
||||
|
@ -108,6 +84,6 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
|||
|
||||
static Future<void> _saveModule(final dynamic body) async {
|
||||
if (body is! Map<String, dynamic>) return;
|
||||
await LicenseRepositoryImpl().setLicense(body['key'], body);
|
||||
await LicenseRepositoryImpl().setModule(body['key'], body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,44 +5,65 @@ import 'package:hub/features/module/domain/index.dart';
|
|||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
import '../../../backend/index.dart';
|
||||
|
||||
typedef LicenseStatus = bool;
|
||||
|
||||
class LicenseRepositoryImpl implements LicenseRepository {
|
||||
final LicenseLocalDataSource localDataSource = LicenseLocalDataSourceImpl();
|
||||
final LicenseRemoteDataSource remoteDataSource =
|
||||
LicenseRemoteDataSourceImpl();
|
||||
final Database database = DatabaseService.database;
|
||||
late final Database database;
|
||||
late final Api api;
|
||||
late final LicenseLocalDataSource localDataSource;
|
||||
late final LicenseRemoteDataSource remoteDataSource;
|
||||
|
||||
LicenseRepositoryImpl();
|
||||
LicenseRepositoryImpl([Database? database, Api? api])
|
||||
: database = database ?? DatabaseService.database,
|
||||
api = api ?? PhpGroup() {
|
||||
localDataSource = LicenseLocalDataSourceImpl(this.database);
|
||||
remoteDataSource = LicenseRemoteDataSourceImpl(this.api);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> updateLicense() async {
|
||||
log('updateLicense');
|
||||
bool result = false;
|
||||
final bool isNewVersion = await localDataSource.isNewVersion();
|
||||
|
||||
if (isNewVersion) {
|
||||
await remoteDataSource.setupLicense(database, isNewVersion);
|
||||
await localDataSource.setupLicense(isNewVersion);
|
||||
result = await remoteDataSource.fetchLicenses(isNewVersion);
|
||||
} else {
|
||||
result = await remoteDataSource.setupLicense(database, isNewVersion);
|
||||
result = await localDataSource.setupLicense(isNewVersion);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> cleanLicense() async {
|
||||
Future<bool> cleanLicense() async {
|
||||
return await remoteDataSource.cleanLicense();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String?> getLicense(String key) async {
|
||||
Future<String?> getModule(String key) async {
|
||||
final response = await localDataSource.get(key);
|
||||
return response;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getLicense() async {
|
||||
return await localDataSource.getLicense();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> resetLicense() async {
|
||||
bool result = false;
|
||||
final bool isNewVersion = await localDataSource.isNewVersion();
|
||||
result = await localDataSource.setupLicense(isNewVersion);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
abstract class LicenseRepository {
|
||||
Future<bool> updateLicense();
|
||||
Future<void> cleanLicense();
|
||||
|
||||
Future<String?> getLicense(String key);
|
||||
Future<void> setLicense<T>(String key, T value);
|
||||
Future<bool> cleanLicense();
|
||||
|
||||
Future<bool> resetLicense();
|
||||
|
||||
Future<String?> getModule(String key);
|
||||
|
||||
Future<bool> setModule<T>(String key, T value);
|
||||
|
||||
Future<List<String>> getLicense();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/components/atomic_components/shared_components_atoms/appbar.dart';
|
||||
import 'package:hub/features/menu/index.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_model.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
|
@ -71,6 +70,8 @@ class _AboutPropertyPageState extends State<AboutPropertyPage>
|
|||
final String title = FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Sobre a Propriedade", enText: "About the Property");
|
||||
return AppBarUtil(
|
||||
key: UniqueKey(),
|
||||
appBarKey: ValueKey<String>('BackNavigationAppBar'),
|
||||
title: title,
|
||||
onBackButtonPressed: () => context.pop(),
|
||||
);
|
||||
|
|
|
@ -33,6 +33,7 @@ class DatabaseService {
|
|||
onOpen: _onOpen,
|
||||
onConfigure: _onConfigure,
|
||||
);
|
||||
print('Database initialized');
|
||||
await LicenseRepositoryImpl().updateLicense();
|
||||
isInitialized = true;
|
||||
}
|
||||
|
|
|
@ -390,6 +390,7 @@ String formatNumber(
|
|||
}
|
||||
|
||||
DateTime get getCurrentTimestamp => DateTime.now();
|
||||
|
||||
DateTime dateTimeFromSecondsSinceEpoch(int seconds) {
|
||||
return DateTime.fromMillisecondsSinceEpoch(seconds * 1000);
|
||||
}
|
||||
|
@ -400,8 +401,11 @@ extension DateTimeConversionExtension on DateTime {
|
|||
|
||||
extension DateTimeComparisonOperators on DateTime {
|
||||
bool operator <(DateTime other) => isBefore(other);
|
||||
|
||||
bool operator >(DateTime other) => isAfter(other);
|
||||
|
||||
bool operator <=(DateTime other) => this < other || isAtSameMomentAs(other);
|
||||
|
||||
bool operator >=(DateTime other) => this > other || isAtSameMomentAs(other);
|
||||
}
|
||||
|
||||
|
@ -457,14 +461,18 @@ Rect? getWidgetBoundingBox(BuildContext context) {
|
|||
}
|
||||
|
||||
bool get isAndroid => !kIsWeb && Platform.isAndroid;
|
||||
|
||||
bool get isiOS => !kIsWeb && Platform.isIOS;
|
||||
|
||||
bool get isWeb => kIsWeb;
|
||||
|
||||
const kBreakpointSmall = 479.0;
|
||||
const kBreakpointMedium = 767.0;
|
||||
const kBreakpointLarge = 991.0;
|
||||
|
||||
bool isMobileWidth(BuildContext context) =>
|
||||
MediaQuery.sizeOf(context).width < kBreakpointSmall;
|
||||
|
||||
bool responsiveVisibility({
|
||||
required BuildContext context,
|
||||
bool phone = true,
|
||||
|
@ -493,6 +501,7 @@ const kTextValidatorWebsiteRegex =
|
|||
|
||||
extension FFTextEditingControllerExt on TextEditingController? {
|
||||
String get text => this == null ? '' : this!.text;
|
||||
|
||||
set text(String newText) => this?.text = newText;
|
||||
}
|
||||
|
||||
|
@ -574,6 +583,7 @@ void showAlertDialog(BuildContext context, String title, String content,
|
|||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
key: ValueKey<String>('AlertDialogKey'),
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
title: Text(title,
|
||||
style: TextStyle(
|
||||
|
@ -593,6 +603,7 @@ void showAlertDialog(BuildContext context, String title, String content,
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
FFButtonWidget(
|
||||
key: ValueKey<String>('RejectOptionKey'),
|
||||
onPressed: () => context.pop(), //Navigator.pop(context),
|
||||
options: FFButtonOptions(
|
||||
width: MediaQuery.of(context).size.width * 0.3,
|
||||
|
@ -615,6 +626,7 @@ void showAlertDialog(BuildContext context, String title, String content,
|
|||
),
|
||||
),
|
||||
FFButtonWidget(
|
||||
key: ValueKey<String>('AcceptOptionKey'),
|
||||
onPressed: () async {
|
||||
action();
|
||||
},
|
||||
|
@ -707,6 +719,7 @@ extension StatefulWidgetExtensions on State<StatefulWidget> {
|
|||
// For iOS 16 and below, set the status bar color to match the app's theme.
|
||||
// https://github.com/flutter/flutter/issues/41067
|
||||
Brightness? _lastBrightness;
|
||||
|
||||
void fixStatusBarOniOS16AndBelow(BuildContext context) {
|
||||
if (!isiOS) {
|
||||
return;
|
||||
|
|
|
@ -15,20 +15,25 @@ class FFLocalizations {
|
|||
static List<String> languages() => ['pt', 'en'];
|
||||
|
||||
static late SharedPreferences _prefs;
|
||||
|
||||
static Future initialize() async =>
|
||||
_prefs = await SharedPreferences.getInstance();
|
||||
|
||||
static Future storeLocale(String locale) =>
|
||||
_prefs.setString(_kLocaleStorageKey, locale);
|
||||
|
||||
static Locale? getStoredLocale() {
|
||||
final locale = _prefs.getString(_kLocaleStorageKey);
|
||||
return locale != null && locale.isNotEmpty ? createLocale(locale) : null;
|
||||
}
|
||||
|
||||
String get languageCode => locale.toString();
|
||||
|
||||
String? get languageShortCode =>
|
||||
_languagesWithShortCode.contains(locale.toString())
|
||||
? '${locale.toString()}_short'
|
||||
: null;
|
||||
|
||||
int get languageIndex => languages().contains(languageCode)
|
||||
? languages().indexOf(languageCode)
|
||||
: 0;
|
||||
|
@ -443,7 +448,7 @@ final kTranslationsMap = <Map<String, Map<String, String>>>[
|
|||
},
|
||||
'784f83pc': {
|
||||
'pt': 'Consultar Liberações',
|
||||
'en': 'Liberation History',
|
||||
'en': 'Liberations History',
|
||||
},
|
||||
'1skj43ye': {
|
||||
'pt': 'Home',
|
||||
|
|
|
@ -126,7 +126,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
)
|
||||
: const ReceptionPageWidget();
|
||||
} else {
|
||||
return const WelcomePageWidget();
|
||||
return const WelcomePage();
|
||||
}
|
||||
}(),
|
||||
builder: (context, snapshot) {
|
||||
|
@ -134,7 +134,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (snapshot.hasError) {
|
||||
DialogUtil.error(context, snapshot.error.toString());
|
||||
return const WelcomePageWidget();
|
||||
return const WelcomePage();
|
||||
} else {
|
||||
return snapshot.data!;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
FFRoute(
|
||||
name: 'welcomePage',
|
||||
path: '/welcomePage',
|
||||
builder: (context, params) => const WelcomePageWidget()),
|
||||
builder: (context, params) => const WelcomePage()),
|
||||
FFRoute(
|
||||
name: 'qrCodePage',
|
||||
path: '/qrCodePage',
|
||||
|
|
|
@ -23,39 +23,58 @@ Future<void> initializeApp() async {
|
|||
_initializeUrlStrategy();
|
||||
_initializeSystemSettings();
|
||||
await _initializeFlutterFlow();
|
||||
await _initializeNav();
|
||||
}
|
||||
|
||||
Future<void> _initializeTracking() async {
|
||||
print('Requesting tracking authorization...');
|
||||
await AppTrackingTransparency.requestTrackingAuthorization();
|
||||
print('Tracking authorization requested');
|
||||
}
|
||||
|
||||
Future<void> _initializeFirebase() async {
|
||||
print('Initializing Firebase...');
|
||||
await Firebase.initializeApp();
|
||||
print('Firebase initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeNotificationService() async {
|
||||
print('Initializing Notification Service...');
|
||||
await NotificationService.initialize();
|
||||
print('Notification Service initialized');
|
||||
}
|
||||
|
||||
void _initializeUrlStrategy() {
|
||||
print('Initializing URL Strategy...');
|
||||
setUrlStrategy(PathUrlStrategy());
|
||||
print('URL Strategy initialized');
|
||||
}
|
||||
|
||||
void _initializeSystemSettings() {
|
||||
print('Initializing System Settings...');
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
if (kDebugMode) {
|
||||
log("Aplicativo em Debug Mode, crashlytics desabilitado!");
|
||||
print('Debug mode');
|
||||
} else {
|
||||
final crashlyticsInstance = FirebaseCrashlytics.instance;
|
||||
print('Release mode');
|
||||
if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
|
||||
FlutterError.onError = crashlyticsInstance.recordFlutterError;
|
||||
print('Crashlytics enabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initializeFlutterFlow() async {
|
||||
print('Initializing FlutterFlow...');
|
||||
await FlutterFlowTheme.initialize();
|
||||
await FFLocalizations.initialize();
|
||||
print('FlutterFlow initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeNav() async {
|
||||
print('Initializing Nav...');
|
||||
GoRouter.optionURLReflectsImperativeAPIs = true;
|
||||
usePathUrlStrategy();
|
||||
print('Nav initialized');
|
||||
}
|
||||
|
|
|
@ -8,14 +8,14 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
|||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hub/features/notification/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||
import 'package:hub/flutter_flow/internationalization.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:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'initialization.dart';
|
||||
|
||||
|
@ -175,11 +175,13 @@ class _AppState extends State<App> {
|
|||
_router = createRouter(_appStateNotifier);
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 1000),
|
||||
() => setState(() => _appStateNotifier.stopShowingSplashImage()),
|
||||
() => mounted
|
||||
? setState(() => _appStateNotifier.stopShowingSplashImage())
|
||||
: null,
|
||||
);
|
||||
|
||||
_setupFirebaseMessaging();
|
||||
DeepLinkService().ensureInitialization();
|
||||
if (TestUtil.isInTest) DeepLinkService().ensureInitialization();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -36,6 +36,7 @@ class _DeliveryScheduleState extends State<DeliverySchedule> {
|
|||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -13,7 +13,6 @@ import 'package:hub/shared/utils/dialog_util.dart';
|
|||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
import 'package:hub/shared/utils/snackbar_util.dart';
|
||||
|
||||
import 'package:hub/shared/utils/validator_util.dart';
|
||||
|
||||
class LiberationHistoryWidget extends StatefulWidget {
|
||||
|
@ -104,6 +103,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
@ -332,13 +332,13 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
|
||||
Future<ApiCallResponse?> _fetchRequests() async {
|
||||
try {
|
||||
setState(() => _loading = true);
|
||||
safeSetState(() => _loading = true);
|
||||
var response = await PhpGroup.getLiberationsCall.call().first;
|
||||
|
||||
final List<dynamic> requests = response.jsonBody['solicitacoes'] ?? [];
|
||||
|
||||
if (requests.isNotEmpty) {
|
||||
setState(() {
|
||||
safeSetState(() {
|
||||
_requestWrap.addAll(requests);
|
||||
_hasData = true;
|
||||
_loading = false;
|
||||
|
@ -349,7 +349,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
|
||||
_showNoMoreDataSnackBar(context);
|
||||
|
||||
setState(() {
|
||||
safeSetState(() {
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
@ -359,7 +359,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
await DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Solicitações", e, s);
|
||||
setState(() {
|
||||
safeSetState(() {
|
||||
_hasData = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
|
|
@ -146,6 +146,7 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
|
|||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -10,11 +10,9 @@ 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';
|
||||
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
|
||||
import 'package:hub/shared/utils/validator_util.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
|
@ -145,6 +143,7 @@ class _PackageOrderPage extends State<PackageOrderPage> {
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -47,6 +47,7 @@ class _PeopleOnThePropertyPageState extends State<PeopleOnThePropertyPage> {
|
|||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
|
||||
import 'package:hub/features/backend/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';
|
||||
import 'package:hub/pages/pets_page/pets_page_model.dart';
|
||||
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
|
@ -85,6 +82,7 @@ class _PetsHistoryScreenState extends State<PetsHistoryScreen>
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.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/nav/nav.dart';
|
||||
import 'package:hub/pages/pets_page/pets_page_widget.dart';
|
||||
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/utils/image_util.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
|
@ -110,7 +108,8 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
String? Function(BuildContext, String?)? textControllerObservationValidator;
|
||||
|
||||
Future<void> initAsync() async {
|
||||
defaultDropDownText = FFLocalizations.of(buildContext!).getVariableText(
|
||||
defaultDropDownText =
|
||||
FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
|
||||
enText: 'Select an option',
|
||||
ptText: 'Selecione uma opção',
|
||||
);
|
||||
|
|
|
@ -76,6 +76,8 @@ class _PetsPageWidgetState extends State<PetsPageWidget>
|
|||
|
||||
PreferredSizeWidget _buildAppBar(BuildContext context) {
|
||||
return AppBarUtil(
|
||||
key: UniqueKey(),
|
||||
appBarKey: ValueKey<String>('BackNavigationAppBar'),
|
||||
title: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Cadastrar Pets',
|
||||
enText: 'Pets Register',
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart';
|
||||
import 'package:hub/features/auth/index.dart';
|
||||
import 'package:hub/features/backend/index.dart';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
|
||||
import 'package:hub/shared/utils/path_util.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/features/local/data/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';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/pages/preferences_settings_page/preferences_settings_model.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PreferencesPageWidget extends StatefulWidget {
|
||||
|
@ -41,6 +38,7 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
|
|||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -36,6 +36,7 @@ class _ProvisionalScheduleState extends State<ProvisionalSchedule> {
|
|||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -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/nav/nav.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/limited_text_size.dart';
|
||||
|
||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
||||
class QrCodePageWidget extends StatefulWidget {
|
||||
|
@ -475,6 +472,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
|||
|
||||
AppBar buildAppBar(BuildContext context) {
|
||||
return AppBar(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
leading: FlutterFlowIconButton(
|
||||
|
@ -492,7 +490,10 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
|||
},
|
||||
),
|
||||
title: Text(
|
||||
FFLocalizations.of(context).getText('ku7jqe53'),
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'QRCode de Acesso',
|
||||
enText: 'Access QRCode',
|
||||
),
|
||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
|
|
|
@ -43,6 +43,7 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
|
|||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
@ -57,8 +58,9 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
|
|||
},
|
||||
),
|
||||
title: Text(
|
||||
FFLocalizations.of(context).getText(
|
||||
'megskb6s' /* Cadastrar Visitante */,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Cadastrar Visitantes',
|
||||
enText: 'Register Visitors',
|
||||
),
|
||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
|
||||
|
|
|
@ -157,6 +157,7 @@ class _ResidentsOnThePropertyState extends State<ResidentsOnTheProperty>
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -126,6 +126,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
forceMaterialTransparency: true,
|
||||
elevation: 0.0,
|
||||
leading: FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -152,6 +152,7 @@ class _VehicleOnThePropertyState extends State<VehicleOnTheProperty>
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -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/pages/visits_on_the_property/model.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/log_util.dart';
|
||||
|
||||
class VisitsOnTheProperty extends StatefulWidget {
|
||||
const VisitsOnTheProperty({super.key});
|
||||
|
@ -135,7 +135,9 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
|
|||
automaticallyImplyLeading: false,
|
||||
title: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Visitas em aberto', enText: 'Opened visits'),
|
||||
ptText: 'Visitas Abertas',
|
||||
enText: 'Opened Visits',
|
||||
),
|
||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
|
@ -155,6 +157,7 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
|
|||
|
||||
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import '/components/templates_components/welcome_template_component/welcome_template_component_widget.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';
|
||||
|
||||
class WelcomePageModel extends FlutterFlowModel<WelcomePageWidget> {
|
||||
class WelcomePageModel extends FlutterFlowModel<WelcomePage> {
|
||||
/// Local state fields for this page.
|
||||
|
||||
String toggleIdx = 'welcome';
|
||||
|
|
|
@ -11,14 +11,14 @@ import 'welcome_page_model.dart';
|
|||
|
||||
export 'welcome_page_model.dart';
|
||||
|
||||
class WelcomePageWidget extends StatefulWidget with Switcher {
|
||||
const WelcomePageWidget({super.key});
|
||||
class WelcomePage extends StatefulWidget with Switcher {
|
||||
const WelcomePage({super.key});
|
||||
|
||||
@override
|
||||
State<WelcomePageWidget> createState() => _WelcomePageWidgetState();
|
||||
State<WelcomePage> createState() => _WelcomePageState();
|
||||
}
|
||||
|
||||
class _WelcomePageWidgetState extends State<WelcomePageWidget> {
|
||||
class _WelcomePageState extends State<WelcomePage> {
|
||||
late WelcomePageModel _model;
|
||||
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
|
|
@ -8,6 +8,7 @@ export 'log_util.dart';
|
|||
export 'path_util.dart';
|
||||
export 'share_util.dart';
|
||||
export 'snackbar_util.dart';
|
||||
export 'string_util.dart';
|
||||
export 'text_util.dart';
|
||||
export 'validator_util.dart';
|
||||
export 'webview_util.dart';
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
class TestUtil {
|
||||
static bool get isInTest {
|
||||
return Platform.environment.containsKey('FLUTTER_TEST');
|
||||
}
|
||||
}
|
336
pubspec.lock
336
pubspec.lock
|
@ -34,10 +34,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: app_links
|
||||
sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99
|
||||
sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.2"
|
||||
version: "6.3.3"
|
||||
app_links_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -66,18 +66,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: app_tracking_transparency
|
||||
sha256: "64d9745931e565790abdea91b518ac8dc3cebe6d0d0aaf7119343271b983259a"
|
||||
sha256: "1f71f4d8402552fbf8b191d4edab301f233c1af794878b7bc56c708470ffd74c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
version: "2.0.6+1"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||
sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
version: "4.0.2"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -130,10 +130,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
||||
sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.4"
|
||||
version: "9.0.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -146,50 +146,50 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.4.2"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||
sha256: "294a2edaf4814a378725bfe6358210196f5ea37af89ecd81bfa32960113d4948"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
version: "4.0.3"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
||||
sha256: "99d3980049739a985cf9b21f30881f46db3ebc62c5b8d5e60e27440876b1ba1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||
sha256: "74691599a5bc750dc96a6b4bfd48f7d9d66453eab04c7f4063134800d6a5c573"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.13"
|
||||
version: "2.4.14"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.2"
|
||||
version: "8.0.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -202,10 +202,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.3"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -286,6 +286,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -338,10 +346,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
|
||||
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
version: "7.0.2"
|
||||
dispose_scope:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dispose_scope
|
||||
sha256: "48ec38ca2631c53c4f8fa96b294c801e55c335db5e3fb9f82cede150cfe5a2af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
dropdown_button2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -466,10 +482,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6
|
||||
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.3.1"
|
||||
version: "5.4.0"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -543,10 +559,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
|
||||
sha256: "153856bdaac302bbdc58a1d1403d50c40557254aa05eaeed40515d88a25a526b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.6"
|
||||
version: "9.0.0"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -641,10 +657,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
|
||||
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.23"
|
||||
version: "2.0.24"
|
||||
flutter_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -657,50 +673,58 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
|
||||
sha256: f7eceb0bc6f4fd0441e29d43cab9ac2a1c5ffd7ea7b64075136b718c46954874
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.2.2"
|
||||
version: "10.0.0-beta.4"
|
||||
flutter_secure_storage_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_darwin
|
||||
sha256: f226f2a572bed96bc6542198ebaec227150786e34311d455a7e2d3d06d951845
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
|
||||
sha256: "9b4b73127e857cd3117d43a70fa3dddadb6e0b253be62e6a6ab85caa0742182c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "2.0.1"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
|
||||
sha256: "75894eb6b402ac7f7f5ee5487d651b87855a338e26eb6993f4b2fce33013a615"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "4.0.0"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
flutter_secure_storage_web:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
sha256: "4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "2.0.0"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||
sha256: ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "4.0.0"
|
||||
flutter_shaders:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -729,10 +753,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: "54900a1a1243f3c4a5506d853a2b5c2dbc38d5f27e52a52618a8054401431123"
|
||||
sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.16"
|
||||
version: "2.0.17"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -808,10 +832,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539"
|
||||
sha256: "7c2d40b59890a929824f30d442e810116caf5088482629c894b9e4478c67472d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.6.2"
|
||||
version: "14.6.3"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -864,26 +888,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
version: "4.1.2"
|
||||
image:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: image
|
||||
sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d
|
||||
sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
version: "4.5.2"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -896,10 +920,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e
|
||||
sha256: b62d34a506e12bb965e824b6db4fbf709ee4589cf5d3e99b45ab2287b008ee0c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+18"
|
||||
version: "0.8.12+20"
|
||||
image_picker_for_web:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -912,10 +936,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker_ios
|
||||
sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b"
|
||||
sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+1"
|
||||
version: "0.8.12+2"
|
||||
image_picker_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -936,10 +960,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
|
||||
sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
version: "2.10.1"
|
||||
image_picker_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1037,10 +1061,10 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
|
||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.1.1"
|
||||
local_auth:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1061,10 +1085,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: local_auth_darwin
|
||||
sha256: "6d2950da311d26d492a89aeb247c72b4653ddc93601ea36a84924a396806d49c"
|
||||
sha256: "5c5127061107278ab4cafa1ac51b3b6760282bf1a2abf011270908a429d1634b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "1.4.2"
|
||||
local_auth_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1117,10 +1141,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: material_symbols_icons
|
||||
sha256: "64404f47f8e0a9d20478468e5decef867a688660bad7173adcd20418d7f892c9"
|
||||
sha256: "89aac72d25dd49303f71b3b1e70f8374791846729365b25bebc2a2531e5b86cd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2801.0"
|
||||
version: "4.2801.1"
|
||||
maybe_just_nothing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1157,10 +1181,10 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: mockito
|
||||
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917"
|
||||
sha256: f99d8d072e249f719a5531735d146d8cf04c580d93920b04de75bef6dfb2daf6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.4"
|
||||
version: "5.4.5"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1169,6 +1193,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1189,26 +1221,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce
|
||||
sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.1"
|
||||
version: "8.1.3"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
|
||||
sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
page_transition:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: page_transition
|
||||
sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6
|
||||
sha256: "9d2a780d7d68b53ae82fbcc43e06a16195e6775e9aae40e55dc0cbb593460f9d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.2.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1273,6 +1305,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
patrol:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: patrol
|
||||
sha256: f2b423122e63b1251fc31165ba1f7d85d60e22b4d20076ef39dcb47f83e35467
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.13.2"
|
||||
patrol_finders:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: patrol_finders
|
||||
sha256: "5a1e2b4c6636e89645fc596d68224cfe6cca28e11c855b98dd0df9bed0d80405"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
patrol_log:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: patrol_log
|
||||
sha256: ad5d7b759d16071ca16aa9b27eb4f106ce23079792d4312941874dbc33e795cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.2"
|
||||
percent_indicator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1369,6 +1425,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
posix:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: posix
|
||||
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.1"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1397,10 +1461,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.5.0"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1461,34 +1525,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: share_plus_platform_interface
|
||||
sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48
|
||||
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.1"
|
||||
version: "5.0.2"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
|
||||
sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.3.5"
|
||||
shared_preferences_android:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
||||
sha256: bf808be89fe9dc467475e982c1db6c2faf3d2acf54d526cd5ec37d86c99dbd84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.4"
|
||||
version: "2.4.1"
|
||||
shared_preferences_foundation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
|
||||
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.3"
|
||||
version: "2.5.4"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1525,10 +1589,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1554,10 +1634,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
|
||||
sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
|
||||
url: "https://pub.dev"
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1602,10 +1698,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_darwin
|
||||
sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474"
|
||||
sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.4.1+1"
|
||||
sqflite_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1642,10 +1738,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1678,6 +1774,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1686,6 +1790,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1698,10 +1810,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1762,18 +1874,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.4.0"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4"
|
||||
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "3.1.4"
|
||||
uuid:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
@ -1794,10 +1906,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_codec
|
||||
sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb"
|
||||
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.12"
|
||||
version: "1.1.13"
|
||||
vector_graphics_compiler:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1826,10 +1938,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1862,6 +1974,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1874,10 +1994,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19"
|
||||
sha256: d1ee28f44894cbabb1d94cc42f9980297f689ff844d067ec50ff88d86e27d63f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.3.0"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1890,10 +2010,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb
|
||||
sha256: "4adc14ea9a770cc9e2c8f1ac734536bd40e82615bd0fa6b94be10982de656cc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.16.3"
|
||||
version: "3.17.0"
|
||||
win32:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
@ -1930,10 +2050,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
dart: ">=3.6.0 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
|
|
28
pubspec.yaml
28
pubspec.yaml
|
@ -37,12 +37,12 @@ dependencies:
|
|||
# flutter_plugin_android_lifecycle: ^2.0.23
|
||||
share_plus: ^10.0.0
|
||||
# connectivity_plus: ^6.0.5
|
||||
flutter_secure_storage: 9.2.2
|
||||
flutter_secure_storage_linux: 1.2.1
|
||||
flutter_secure_storage_macos: 3.1.2
|
||||
flutter_secure_storage_platform_interface: 1.1.2
|
||||
flutter_secure_storage_web: 1.2.1
|
||||
flutter_secure_storage_windows: 3.1.2
|
||||
flutter_secure_storage: ^10.0.0-beta.2
|
||||
flutter_secure_storage_linux: ^2.0.0
|
||||
flutter_secure_storage_macos: ^4.0.0
|
||||
flutter_secure_storage_platform_interface: ^2.0.1
|
||||
flutter_secure_storage_web: ^2.0.0
|
||||
flutter_secure_storage_windows: ^4.0.0
|
||||
flutter_spinkit: 5.2.1
|
||||
flutter_staggered_grid_view: 0.7.0
|
||||
flutter_svg: ^2.0.15
|
||||
|
@ -56,13 +56,13 @@ dependencies:
|
|||
image_picker_for_web: ^3.0.5
|
||||
persistent_bottom_nav_bar: ^6.2.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
|
||||
intl: ^0.19.0
|
||||
# camera: ^0.11.0+2
|
||||
json_path: ^0.7.4
|
||||
mime_type: ^1.0.1
|
||||
page_transition: 2.1.0
|
||||
page_transition: ^2.2.1
|
||||
path_provider: ^2.1.4
|
||||
path_provider_android: ^2.2.12
|
||||
google_mlkit_face_detection: ^0.12.0
|
||||
|
@ -92,7 +92,7 @@ dependencies:
|
|||
material_symbols_icons: ^4.2784.0
|
||||
fluttertoast: ^8.2.8
|
||||
cupertino_icons: ^1.0.0
|
||||
flutter_bloc: ^8.1.6
|
||||
flutter_bloc: ^9.0.0
|
||||
flutter_riverpod: ^2.5.1
|
||||
qr_flutter: ^4.1.0
|
||||
permission_handler: ^11.3.1
|
||||
|
@ -124,6 +124,9 @@ dev_dependencies:
|
|||
build_runner: ^2.4.13
|
||||
freezed: ^2.5.7
|
||||
json_serializable: ^6.9.0
|
||||
test: ^1.25.8
|
||||
patrol: ^3.13.2
|
||||
patrol_finders: ^2.6.0
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
|
@ -157,3 +160,10 @@ fonts:
|
|||
- family: Menu
|
||||
fonts:
|
||||
- asset: assets/fonts/menu.ttf
|
||||
|
||||
patrol:
|
||||
app_name: FRE ACCESS HUB
|
||||
android:
|
||||
package_name: com.freaccess.hub
|
||||
ios:
|
||||
bundle_id: br.com.freaccess.hub
|
|
@ -0,0 +1,11 @@
|
|||
# Ativa o 'patrol_cli' globalmente
|
||||
flutter pub global activate patrol_cli
|
||||
|
||||
# Limpa os builds anteriores do Flutter
|
||||
flutter clean
|
||||
|
||||
# Obtém as dependências do Flutter
|
||||
flutter pub get
|
||||
|
||||
# Verifica a configuração do Patrol
|
||||
patrol doctor
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue