impl Fuzzer e refactor auth_test

This commit is contained in:
J. A. Messias 2025-01-17 10:52:59 -03:00
parent 92174836d6
commit bddbcb8d31
3 changed files with 273 additions and 53 deletions

View File

@ -4,6 +4,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.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/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/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/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:material_symbols_icons/symbols.dart';
import 'package:patrol_finders/patrol_finders.dart'; import 'package:patrol_finders/patrol_finders.dart';
import 'fuzzer/fuzzer.dart';
part 'auth_test.dart'; part 'auth_test.dart';
part 'home_test.dart'; part 'home_test.dart';
part 'locals_test.dart'; part 'locals_test.dart';
@ -42,20 +45,20 @@ void main() {
setUp(() async {}); setUp(() async {});
tearDown(() async {}); tearDown(() async {});
WelcomeTest.signInToSignUp(); // WelcomeTest.signInToSignUp();
WelcomeTest.signUpToSignIn(); // WelcomeTest.signUpToSignIn();
AuthenticationTest.signIn(); // AuthenticationTest.signIn();
AuthenticationTest.signUp(); AuthenticationTest.signUp();
AuthenticationTest.signOut(); // AuthenticationTest.signOut();
//
ModularizationTest.switchLicense(); // ModularizationTest.switchLicense();
ModularizationTest.containLicense(); // ModularizationTest.containLicense();
//
MenuTest.navToEntries(); // MenuTest.navToEntries();
MenuTest.containEntries(); // MenuTest.containEntries();
MenuTest.labels2AppbarConsistency(); // MenuTest.labels2AppbarConsistency();
//
LocalsTest.setLocal(); // LocalsTest.setLocal();
LocalsTest.unlinkLocal(); // LocalsTest.unlinkLocal();
} }

View File

@ -3,20 +3,59 @@ part of 'app_test.dart';
class AuthenticationTest { class AuthenticationTest {
static Future<void> signIn() async { static Future<void> signIn() async {
patrolWidgetTest( patrolWidgetTest(
'Sign-In with erro@exemplo.com', 'Sign-In with fuzzed emails',
(PatrolTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester
'Authentication Test - Sign-In with error@exemplo.com'); .printToConsole('Authentication Test - Sign-In with fuzzed emails');
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
final Map<String, String> credentials = {
'emailTextFormField': 'erro@exemplo.com', final Fuzzer fuzzer = Fuzzer(
'passwordTextFormField': '12345678', 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 _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignIn($); 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<void> signUp() async { static Future<void> signUp() async {
patrolWidgetTest( // patrolWidgetTest(
'Sign Up - credenciais já registradas', // 'Sign Up - credenciais já registradas',
(PatrolTester tester) async { // (PatrolTester tester) async {
$ = tester; // $ = tester;
$.tester.printToConsole( // $.tester.printToConsole(
'Authentication Test - Sign-Up: credenciais já registradas'); // 'Authentication Test - Sign-Up: credenciais já registradas');
//
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); // final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
final Map<String, String> credentials = { // final Map<String, String> credentials = {
'nameTextFormField': 'app', // 'nameTextFormField': 'app',
'emailTextFormField': 'email_app@exemplo.com', // 'emailTextFormField': 'email_app@exemplo.com',
'passwordTextFormField': '12345678', // 'passwordTextFormField': '12345678',
}; // };
await _unlogged(); // await _unlogged();
await $.pumpWidgetAndSettle(const App()); // await $.pumpWidgetAndSettle(const App());
await _navigateToSignUp($); // await _navigateToSignUp($);
await _auth(credentials, $, throwsException); // await _auth(credentials, $, throwsException);
await Future.delayed(const Duration(milliseconds: 500)); // await Future.delayed(const Duration(milliseconds: 500));
}, // },
); // );
patrolWidgetTest( patrolWidgetTest(
'Sign Up - credenciais novas', 'Sign Up - credenciais novas',
@ -71,21 +110,61 @@ class AuthenticationTest {
.printToConsole('Authentication Test - Sign-Up: credenciais novas'); .printToConsole('Authentication Test - Sign-Up: credenciais novas');
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
final name = _generateRandomString(7);
final email = '$name@example.com'; final Fuzzer fuzzer = Fuzzer(
final password = '12345678'; configs: [
final Map<String, String> credentials = { FuzzConfig(
'nameTextFormField': name, label: 'name',
'emailTextFormField': email, type: AcceptedTypes.string,
'passwordTextFormField': password, 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 _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignUp($);
await _auth(credentials, $, throwsException); for (var credential in credentials) {
await Future.delayed(const Duration(milliseconds: 500)); 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);
}
}, },
); );
} }

View File

@ -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)),
),
);
}
}