From dd82e75969d08101ed97f8eda9062d2b5874fd7c Mon Sep 17 00:00:00 2001 From: Yasm1nNasc1mento Date: Thu, 19 Dec 2024 15:07:44 -0300 Subject: [PATCH 1/4] =?UTF-8?q?fix(#59):=20Corrige=20e=20ajusta=20apar?= =?UTF-8?q?=C3=AAncia=20da=20WelcomeView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: isabellachoukaira Co-authored-by: zDrNz --- lib/ui/welcome/view/WelcomeView.dart | 158 +++++++++++++++------------ 1 file changed, 86 insertions(+), 72 deletions(-) diff --git a/lib/ui/welcome/view/WelcomeView.dart b/lib/ui/welcome/view/WelcomeView.dart index d6aa41a..c62eae6 100644 --- a/lib/ui/welcome/view/WelcomeView.dart +++ b/lib/ui/welcome/view/WelcomeView.dart @@ -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 createState() => _WelcomeViewState(); +} + +class _WelcomeViewState extends State { @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).push( + 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, + ), + )), + ), ); } - } From 78ffade04e3218ecb4fd1a8052a4fc9bed7a09d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Filipe?= Date: Thu, 19 Dec 2024 17:38:22 -0300 Subject: [PATCH 2/4] test(#59): Realizacao de teste dos componentes shared --- test/ui/Shared/ErrorPopUp_test.dart | 34 ++++++++++ test/ui/Shared/TextEmail_test.dart | 37 +++++++++++ test/ui/Shared/TextName_test.dart | 35 +++++++++++ test/ui/Shared/TextPassword_test.dart | 90 +++++++++++++++++++++++++++ test/widget_test.dart | 30 --------- 5 files changed, 196 insertions(+), 30 deletions(-) create mode 100644 test/ui/Shared/ErrorPopUp_test.dart create mode 100644 test/ui/Shared/TextEmail_test.dart create mode 100644 test/ui/Shared/TextName_test.dart create mode 100644 test/ui/Shared/TextPassword_test.dart delete mode 100644 test/widget_test.dart diff --git a/test/ui/Shared/ErrorPopUp_test.dart b/test/ui/Shared/ErrorPopUp_test.dart new file mode 100644 index 0000000..5977af6 --- /dev/null +++ b/test/ui/Shared/ErrorPopUp_test.dart @@ -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 + }); +} diff --git a/test/ui/Shared/TextEmail_test.dart b/test/ui/Shared/TextEmail_test.dart new file mode 100644 index 0000000..9474a3d --- /dev/null +++ b/test/ui/Shared/TextEmail_test.dart @@ -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 testEmail(String input, String? expectedError) async { + await tester.enterText(emailField, input); + await tester.pump(); + final validator = + tester.widget(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("joao@example.com", null); // Entrada válida + }); +} diff --git a/test/ui/Shared/TextName_test.dart b/test/ui/Shared/TextName_test.dart new file mode 100644 index 0000000..6a493b2 --- /dev/null +++ b/test/ui/Shared/TextName_test.dart @@ -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 testName(String input, String? expectedError) async { + await tester.enterText(nameField, input); + await tester.pump(); + final validator = + tester.widget(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 + }); +} diff --git a/test/ui/Shared/TextPassword_test.dart b/test/ui/Shared/TextPassword_test.dart new file mode 100644 index 0000000..a1551d4 --- /dev/null +++ b/test/ui/Shared/TextPassword_test.dart @@ -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 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(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(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(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(textFieldFinder); + expect(textField.obscureText, true); + }); +} diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 975faa0..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:aranduapp/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} From e76b3f446e8034d8b336fa82e48f8b36814f0228 Mon Sep 17 00:00:00 2001 From: Gabriel Costa de Oliveira Date: Fri, 20 Dec 2024 18:38:30 -0300 Subject: [PATCH 3/4] =?UTF-8?q?fix(#59):=20corrige=20navega=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/welcome/view/WelcomeView.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/welcome/view/WelcomeView.dart b/lib/ui/welcome/view/WelcomeView.dart index c62eae6..af76569 100644 --- a/lib/ui/welcome/view/WelcomeView.dart +++ b/lib/ui/welcome/view/WelcomeView.dart @@ -81,7 +81,7 @@ class _WelcomeViewState extends State { return SingleChildScrollView( child: GestureDetector( onTap: () => { - Navigator.of(context).push( + Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (context) => const OnboardingView(), ), From 4fc01ad5c94187c9db35cdbf58d090514a1a9d2b Mon Sep 17 00:00:00 2001 From: Gabriel Costa de Oliveira Date: Fri, 20 Dec 2024 18:42:59 -0300 Subject: [PATCH 4/4] adiciona link para o apk --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 38c19f4..ff7bd83 100644 --- a/README.md +++ b/README.md @@ -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