Skip to content

Commit

Permalink
Merge branch 'dev' into qa/recover_account
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielCostaDeOliveira committed Dec 22, 2024
2 parents 75972ba + 4fc01ad commit e984826
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 72 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# APP em Flutter para o Projeto Arandu

A new Flutter project.
## APK

- [apk](https://drive.google.com/file/d/1TPG-VqmmfdZMZebikvrZ33AvWLwHhWbx/view?usp=drive_link)

## Getting Started

Expand Down
158 changes: 86 additions & 72 deletions lib/ui/welcome/view/WelcomeView.dart
Original file line number Diff line number Diff line change
@@ -1,92 +1,106 @@
import 'package:aranduapp/core/log/Log.dart';
import 'package:aranduapp/ui/onboarding/view/onboarding_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:google_fonts/google_fonts.dart';


class WelcomeView extends StatelessWidget {
//final WelcomeModel model = WelcomeModel("Arandú","Começar");
class WelcomeView extends StatefulWidget {

WelcomeView({super.key});

@override
State<WelcomeView> createState() => _WelcomeViewState();
}

class _WelcomeViewState extends State<WelcomeView> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 95),

//Cículo com gradiente com possível logo sobreposta
Stack(
alignment: Alignment.center,
children: [



Container(
width: 278,
height: 278,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),

],
),
const SizedBox(height: 20),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_logo(context),
const SizedBox(height: 80),
_startButton(context),
const SizedBox(width: 80),
],
))));
}

//Titulo "arandú" com fonte amarante
Text(
"Arandú",
style: GoogleFonts.amarante(
fontSize: 60,
fontWeight: FontWeight.w500,
Widget _logo(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;

double circleDiameter = screenSize.height;
double nameSize = screenSize.height * 0.075;

return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//Cículo com gradiente com possível logo sobreposta
Stack(
alignment: Alignment.center,
children: [
Container(
width: circleDiameter * 0.3,
height: circleDiameter *0.3,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),
const Spacer(),

//Botão de começar com gradiente
GestureDetector(
onTap: () => {


Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const OnboardingView(),
),
)


},
],
),

const SizedBox(height: 25),

child: Container(
padding: const EdgeInsets.symmetric(horizontal:120, vertical: 15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.primary,
),
child: Text(
"Começar",
style: GoogleFonts.comfortaa(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w500, //coloca a fonte certa
//Titulo "arandú" com fonte amarante
Text(
"Arandú",
style: GoogleFonts.amarante(
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontSize: nameSize,
fontWeight: FontWeight.w500,
),
),
),
],
)));
}

),
)
),

Widget _startButton(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;

double paddingHorizontal =
screenSize.width * 0.07; // largura da tela
double paddingVertical = screenSize.height * 0.025; // da altura da tela
return SingleChildScrollView(
child: GestureDetector(
onTap: () => {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const OnboardingView(),
),
const SizedBox(height:50),
],
)
)
)
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: paddingHorizontal, vertical: paddingVertical),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.primary,
),
child: Text(
"Começar",
style: Theme.of(context).textTheme.bodyLarge?.apply(
color: Theme.of(context).colorScheme.onPrimary,
),
)),
),
);
}

}
34 changes: 34 additions & 0 deletions test/ui/Shared/ErrorPopUp_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:aranduapp/ui/shared/ErrorPopUp.dart';

void main() {
testWidgets('Testa ErrorPopUp', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: ErrorPopUp(
content: Text('Este é um erro'),
),
),
),
);

// Verificar se o ícone de erro está presente
expect(find.byIcon(Icons.error), findsOneWidget);

// Verificar se o conteúdo do popup está correto
expect(find.text('Este é um erro'), findsOneWidget);

// Verificar se o botão 'OK' está presente
expect(find.text('OK'), findsOneWidget);

// Tocar no botão OK
await tester.tap(find.text('OK'));

// Rebuild após o tap para processar a navegação
await tester.pumpAndSettle();

expect(find.text('OK'), findsNothing); // O popup desapareceu
});
}
37 changes: 37 additions & 0 deletions test/ui/Shared/TextEmail_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:aranduapp/ui/shared/TextEmail.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Testa se Email é válido ou inválido',
(WidgetTester tester) async {
final controller = TextEditingController();

await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: TextEmail(
padding: const EdgeInsets.all(10), controller: controller),
),
),
);

final emailField = find.byType(TextFormField);

// Função auxiliar para validar diferentes entradas de e-mail
Future<void> testEmail(String input, String? expectedError) async {
await tester.enterText(emailField, input);
await tester.pump();
final validator =
tester.widget<TextFormField>(emailField).validator!(input);
expect(validator, expectedError);
}

// Teste de validação para diferentes casos
await testEmail("", "E-mail inválido"); // Campo vazio
await testEmail("joaozinhi", "E-mail inválido"); // Sem '@'
await testEmail("joaozinhi@", "E-mail inválido"); // Sem domínio
await testEmail("joao@domain", "E-mail inválido"); // Sem extensão
await testEmail("[email protected]", null); // Entrada válida
});
}
35 changes: 35 additions & 0 deletions test/ui/Shared/TextName_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:aranduapp/ui/shared/TextName.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Testa se o nome é válido', (WidgetTester tester) async {
final controller = TextEditingController();

await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: TextName(
controller: controller,
padding: const EdgeInsets.all(10),
),
)));

final nameField = find.byType(TextFormField);

// Função auxiliar para validar diferentes entradas de nome
Future<void> testName(String input, String? expectedError) async {
await tester.enterText(nameField, input);
await tester.pump();
final validator =
tester.widget<TextFormField>(nameField).validator!(input);
expect(validator, expectedError);
}

// Teste de validação para diferentes casos de nome
await testName("", 'Nome inválido'); // Campo vazio
await testName(" a", 'Nome inválido'); // Nome com menos de 3 caracteres
await testName("Jo", 'Nome inválido'); // Nome com 2 caracteres
await testName("João", null); // Nome válido
await testName("Maria", null); // Outro nome válido
});
}
90 changes: 90 additions & 0 deletions test/ui/Shared/TextPassword_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:aranduapp/ui/shared/TextPassword.dart';

void main() {
// Testa a validação da senha no widget TextPassWord
testWidgets('Testa se a senha é válida', (WidgetTester tester) async {
final controller = TextEditingController();

// Monta o widget de teste com TextPassWord
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: TextPassWord(
controller: controller,
padding: const EdgeInsets.all(10),
),
),
),
);

// Localiza o campo de texto do formulário
final passwordField = find.byType(TextFormField);

// Função para testar diferentes cenários de validação de senha
Future<void> testPassword(String input, String? expectedError) async {
await tester.enterText(passwordField, input); // Insere texto no campo
await tester.pump(); // Re-renderiza o widget para capturar mudanças
final validator =
tester.widget<TextFormField>(passwordField).validator!(input);
expect(validator,
expectedError); // Verifica se o erro retornado é o esperado
}

// Testa senhas inválidas, válidas e campo vazio
await testPassword('12345', "Senha inválida"); // Senha muito curta
await testPassword('validPassword123', null); // Senha válida
await testPassword('', 'Senha inválida'); // Campo vazio
});

// Testa a funcionalidade de visibilidade da senha
testWidgets('Testa a visibilidade da senha', (WidgetTester tester) async {
final controller = TextEditingController();

// Monta o widget de teste com TextPassWord
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: TextPassWord(
controller: controller,
padding: const EdgeInsets.all(10),
),
),
),
);

// Localiza o ícone de visibilidade e o campo de texto
final visibilityIcon = find.byIcon(Icons.visibility_off_outlined);
final textFieldFinder = find.byType(TextField);

// Verifica se o ícone inicial de visibilidade está presente
expect(visibilityIcon, findsOneWidget);

// Verifica o estado inicial de obscureText (deve ser verdadeiro)
TextField textField = tester.widget<TextField>(textFieldFinder);
expect(textField.obscureText, true);

// Simula o clique no ícone para alterar a visibilidade da senha
await tester.tap(visibilityIcon);
await tester.pump();

// Verifica se o ícone foi alterado para o estado visível
expect(find.byIcon(Icons.visibility_outlined), findsOneWidget);

// Verifica se obscureText agora é falso
textField = tester.widget<TextField>(textFieldFinder);
expect(textField.obscureText, false);

// Simula outro clique para voltar a ocultar a senha
await tester.tap(find.byIcon(Icons.visibility_outlined));
await tester.pump();

// Verifica se o ícone voltou para o estado inicial
expect(find.byIcon(Icons.visibility_off_outlined), findsOneWidget);

// Verifica novamente se obscureText é verdadeiro
textField = tester.widget<TextField>(textFieldFinder);
expect(textField.obscureText, true);
});
}

0 comments on commit e984826

Please sign in to comment.