diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 4ec6aa1d..1a819b0d 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -4,6 +4,7 @@ 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'; @@ -20,6 +21,8 @@ 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'; @@ -42,20 +45,20 @@ void main() { setUp(() async {}); tearDown(() async {}); - WelcomeTest.signInToSignUp(); - WelcomeTest.signUpToSignIn(); + // WelcomeTest.signInToSignUp(); + // WelcomeTest.signUpToSignIn(); - AuthenticationTest.signIn(); + // AuthenticationTest.signIn(); AuthenticationTest.signUp(); - AuthenticationTest.signOut(); - - ModularizationTest.switchLicense(); - ModularizationTest.containLicense(); - - MenuTest.navToEntries(); - MenuTest.containEntries(); - MenuTest.labels2AppbarConsistency(); - - LocalsTest.setLocal(); - LocalsTest.unlinkLocal(); + // AuthenticationTest.signOut(); + // + // ModularizationTest.switchLicense(); + // ModularizationTest.containLicense(); + // + // MenuTest.navToEntries(); + // MenuTest.containEntries(); + // MenuTest.labels2AppbarConsistency(); + // + // LocalsTest.setLocal(); + // LocalsTest.unlinkLocal(); } diff --git a/integration_test/auth_test.dart b/integration_test/auth_test.dart index c4ae67e8..769cdd33 100644 --- a/integration_test/auth_test.dart +++ b/integration_test/auth_test.dart @@ -3,20 +3,59 @@ part of 'app_test.dart'; class AuthenticationTest { static Future signIn() async { patrolWidgetTest( - 'Sign-In with erro@exemplo.com', + 'Sign-In with fuzzed emails', (PatrolTester tester) async { $ = tester; - $.tester.printToConsole( - 'Authentication Test - Sign-In with error@exemplo.com'); + $.tester + .printToConsole('Authentication Test - Sign-In with fuzzed emails'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); - final Map credentials = { - 'emailTextFormField': 'erro@exemplo.com', - 'passwordTextFormField': '12345678', - }; + + 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 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($); - await _auth(credentials, $, throwsException); + + 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); + } }, ); @@ -42,26 +81,26 @@ class AuthenticationTest { } static Future 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 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 já registradas', + // (PatrolTester tester) async { + // $ = tester; + // $.tester.printToConsole( + // 'Authentication Test - Sign-Up: credenciais já registradas'); + // + // final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); + // final Map 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', @@ -71,21 +110,61 @@ class AuthenticationTest { .printToConsole('Authentication Test - Sign-Up: credenciais novas'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); - final name = _generateRandomString(7); - final email = '$name@example.com'; - final password = '12345678'; - final Map credentials = { - 'nameTextFormField': name, - 'emailTextFormField': email, - 'passwordTextFormField': password, - }; + + 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 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()); - await _navigateToSignUp($); - await _auth(credentials, $, throwsException); - await Future.delayed(const Duration(milliseconds: 500)); + + 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); + } }, ); } diff --git a/integration_test/fuzzer/fuzzer.dart b/integration_test/fuzzer/fuzzer.dart new file mode 100644 index 00000000..e20c5cfe --- /dev/null +++ b/integration_test/fuzzer/fuzzer.dart @@ -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 inputs; + final dynamic output; + final String message; + + FuzzerResult({ + required this.functionName, + required this.inputs, + this.output, + required this.message, + }); +} + +class Fuzzer { + final List configs; + final int iterations; + final Random _random = Random(); + + Fuzzer({ + required this.configs, + this.iterations = 100, + }); + + List fuzz(Function fn) { + final results = []; + 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 _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)), + ), + ); + } +}