Skip to content

Commit

Permalink
Merge pull request #97 from fga-eps-mds/fix#58/username
Browse files Browse the repository at this point in the history
Fix#58/username
  • Loading branch information
GabrielCostaDeOliveira authored Jan 26, 2025
2 parents 855fc14 + 5bc1efc commit a04245e
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 203 deletions.
5 changes: 4 additions & 1 deletion lib/core/network/token_manager/model/user_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import 'dart:convert';
class UserModel {
final String id;
final String name;
final String userName;
final String email;
final String role;

UserModel({
required this.id,
required this.name,
required this.userName,
required this.email,
required this.role,
});

UserModel.fromMap(Map<String, dynamic> json)
: id = json['userId']! as String,
name = json['name']! as String,
userName = json['username']! as String,
email = json['email']! as String,
role = json['role']! as String;

Expand All @@ -24,6 +27,7 @@ class UserModel {
return UserModel(
id: json['userId']! as String,
name: json['name']! as String,
userName: json['username']! as String,
email: json['email']! as String,
role: json['role']! as String,
);
Expand All @@ -38,4 +42,3 @@ class UserModel {
});
}
}

47 changes: 32 additions & 15 deletions lib/ui/edit_delete_user/view/edit_delete_user_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,39 @@ class EditDeleteUserScreen extends StatelessWidget {
Provider.of<EditDelteUserViewmodel>(context);

return Scaffold(
body: CommandButton(
tap: viewModel.deleteUserCommand.execute,
command: viewModel.deleteUserCommand,
nameButton: "Deltetar",
onSuccessCallback: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const Login(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Tem certeza de que deseja excluir sua conta? Essa ação não pode ser desfeita.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
);
},
onErrorCallback: (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('não foi possível apagar a conta')),
);
},
const SizedBox(height: 20),
CommandButton(
tap: viewModel.deleteUserCommand.execute,
command: viewModel.deleteUserCommand,
nameButton: "Deletar",
onSuccessCallback: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const Login(),
),
);
},
onErrorCallback: (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Não foi possível apagar a conta')),
);
},
),
],
),
),
);
}
Expand Down
1 change: 1 addition & 0 deletions lib/ui/edit_profile/view/edit_profile_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class EditProfileScreen extends StatelessWidget {
label: "Nome de Usuário",
controller: userNameController,
padding: const EdgeInsets.symmetric(vertical: 0),
initialText: user?.userName ?? "",
),
const SizedBox(height: 20),
TextEmail(
Expand Down
34 changes: 23 additions & 11 deletions lib/ui/register_account/view/register_account_view.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:aranduapp/ui/register_account/model/register_request.dart';
import 'package:aranduapp/ui/shared/or_divider.dart';
import 'package:aranduapp/ui/shared/text_and_link.dart';
import 'package:aranduapp/ui/shared/text_name.dart';
Expand All @@ -22,13 +23,19 @@ class RegisterAccount extends StatelessWidget {
Widget build(BuildContext context) {
return ChangeNotifierProvider<RegisterAccountViewModel>.value(
value: GetIt.instance<RegisterAccountViewModel>(),
child: const RegisterAccountScreen(),
child: RegisterAccountScreen(),
);
}
}

class RegisterAccountScreen extends StatelessWidget {
const RegisterAccountScreen({super.key});
RegisterAccountScreen({super.key});

final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final TextEditingController nameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController userNameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -58,28 +65,25 @@ class RegisterAccountScreen extends StatelessWidget {
}

Widget _formSection(BuildContext context) {
RegisterAccountViewModel viewModel =
Provider.of<RegisterAccountViewModel>(context);

return Form(
key: viewModel.formKey,
key: formKey,
child: Column(children: [
TextName(
key: const Key('nameField'),
label: 'Nome',
controller: viewModel.nameController,
controller: nameController,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20)),
TextName(
key: const Key('userNameField'),
label: 'Nome de Usuário',
controller: viewModel.userNameController,
controller: userNameController,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20)),
TextEmail(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
controller: viewModel.emailController),
controller: emailController),
TextPassWord(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
controller: viewModel.passwordController),
controller: passwordController),
_buildTermsCheckbox(context),
const SizedBox(height: 20),
_buildRegisterButton(context),
Expand Down Expand Up @@ -111,7 +115,15 @@ class RegisterAccountScreen extends StatelessWidget {
final viewModel = Provider.of<RegisterAccountViewModel>(context);

return CommandButton(
tap: viewModel.registerCommand.execute,
tap: () {
if (formKey.currentState!.validate()) {
viewModel.registerCommand.execute(RegisterRequest(
name: nameController.text,
email: emailController.text,
userName: userNameController.text,
password: passwordController.text));
}
},
command: viewModel.registerCommand,
nameButton: 'Registrar',
onSuccessCallback: () {
Expand Down
24 changes: 4 additions & 20 deletions lib/ui/register_account/viewmodel/register_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,21 @@ import '../model/register_request.dart';
import '../service/register_service.dart';

class RegisterAccountViewModel extends ChangeNotifier {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final TextEditingController nameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController userNameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();

bool isTermsAccepted = false;

late Command0<void> registerCommand;
late Command1<void, RegisterRequest> registerCommand;

RegisterAccountViewModel() {
registerCommand = Command0<void>(_register);
registerCommand = Command1<void, RegisterRequest>(_register);
}

Future<Result<void>> _register() async {

Future<Result<void>> _register(RegisterRequest registerRequest) async {
if (!isTermsAccepted) {
return Result.error(
'Você deve aceitar os termos de privacidade e políticas de uso.');
}

if (!formKey.currentState!.validate()) {
return Result.error('Por favor, preencha todos os campos corretamente');
}

await GetIt.instance<RegisterService>().register(RegisterRequest(
email: emailController.text,
name: nameController.text,
userName: userNameController.text,
password: passwordController.text,
));
await GetIt.instance<RegisterService>().register(registerRequest);

return Result.value(null);
}
Expand Down
72 changes: 33 additions & 39 deletions test/ui/register_account/view/register_account_view_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:aranduapp/core/state/command.dart';
import 'package:aranduapp/ui/register_account/model/register_request.dart';
import 'package:aranduapp/ui/register_account/view/register_account_view.dart';
import 'package:aranduapp/ui/shared/error_popup.dart';
import 'package:aranduapp/ui/shared/text_and_link.dart';
Expand All @@ -12,36 +13,36 @@ import 'package:get_it/get_it.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';

@GenerateNiceMocks([MockSpec<RegisterAccountViewModel>(), MockSpec<Command0>()])
@GenerateNiceMocks([MockSpec<RegisterAccountViewModel>(), MockSpec<Command1>()])
import 'package:aranduapp/ui/register_account/viewmodel/register_viewmodel.dart';

import 'register_account_view_test.mocks.dart';

void main() {
late MockRegisterAccountViewModel mockViewModel;
late MockCommand0 mockCommand0;
late MockCommand1<void, RegisterRequest> mockRegisterCommand1;

setUp(() async {
mockViewModel = MockRegisterAccountViewModel();
mockCommand0 = MockCommand0();
mockRegisterCommand1 = MockCommand1();

when(mockCommand0.execute()).thenAnswer((_) async => Result.value(null));
when(mockViewModel.registerCommand).thenReturn(mockRegisterCommand1);

when(mockViewModel.registerCommand).thenReturn(mockCommand0);
when(mockViewModel.formKey).thenReturn(GlobalKey<FormState>());
when(mockViewModel.nameController).thenReturn(TextEditingController());
when(mockViewModel.emailController).thenReturn(TextEditingController());
when(mockViewModel.userNameController).thenReturn(TextEditingController());
when(mockViewModel.passwordController).thenReturn(TextEditingController());
when(mockViewModel.isTermsAccepted).thenReturn(false);
when(mockRegisterCommand1.execute(any)).thenAnswer(
(_) async => Result.value(null),
);

when(mockRegisterCommand1.isOk).thenReturn(false);
when(mockRegisterCommand1.isError).thenReturn(false);
when(mockRegisterCommand1.running).thenReturn(false);

when(mockViewModel.isTermsAccepted).thenReturn(false);

await GetIt.instance.reset();
GetIt.I.registerLazySingleton<RegisterAccountViewModel>(() => mockViewModel);
GetIt.I
.registerLazySingleton<RegisterAccountViewModel>(() => mockViewModel);
});


Widget createLoginScreen() {
return const MaterialApp(
home: RegisterAccount(),
Expand All @@ -50,9 +51,6 @@ void main() {

testWidgets('Register Account screen displays fields and send button',
(WidgetTester tester) async {
when(mockViewModel.registerCommand).thenReturn(
Command0<void>(() => Future.delayed(const Duration(seconds: 1))));

await tester.pumpWidget(createLoginScreen());
await tester.pump();

Expand All @@ -67,37 +65,33 @@ void main() {
expect(find.byType(TextAndLink), findsOneWidget);
});

testWidgets('Test sending the request', (WidgetTester tester) async {
await tester.pumpWidget(createLoginScreen());

final sendButton = find.text('Registrar');

await tester.tap(sendButton);
await tester.pump();

verify(mockCommand0.execute()).called(1);
});

testWidgets('Register Account Test User Input', (WidgetTester tester) async {
await tester.pumpWidget(createLoginScreen());

const name = 'test';
const email = 'test@example.com';
const userName = 'test123';
const password = 'password123';
const name = 'gabriel';
const email = 'gabriel.costa513@gmail.com';
const userName = 'gabrile';
const password = '123456789';

await tester.pumpAndSettle();

await tester.enterText(find.byKey(const Key('nameField')), name);
await tester.enterText(find.byKey(const Key('userNameField')), userName);
await tester.enterText(find.byType(TextEmail), email);
await tester.enterText(find.byType(TextPassWord), password);


await tester.tap(find.byKey(const Key('elevated_button_key')));
await tester.pumpAndSettle();

await tester.pumpAndSettle();

expect(mockViewModel.nameController.text, name);
expect(mockViewModel.userNameController.text, userName);
expect(mockViewModel.passwordController.text, password);
expect(mockViewModel.emailController.text, email);
verify(mockRegisterCommand1.execute(argThat(predicate<RegisterRequest>(
(req) =>
req.name == name &&
req.email == email &&
req.userName == userName &&
req.password == password)))).called(1);
});

testWidgets('Checkbox shows correct value when initially unchecked',
Expand Down Expand Up @@ -132,7 +126,7 @@ void main() {

testWidgets('Register Account user notification snackbar',
(WidgetTester tester) async {
when(mockCommand0.isOk).thenReturn(true);
when(mockRegisterCommand1.isOk).thenReturn(true);

await tester.pumpWidget(createLoginScreen());
await tester.pumpAndSettle();
Expand All @@ -142,12 +136,12 @@ void main() {

testWidgets('Register Account user notification popup error',
(WidgetTester tester) async {
when(mockViewModel.registerCommand).thenReturn(mockCommand0);
when(mockCommand0.isError).thenReturn(true);
when(mockViewModel.registerCommand).thenReturn(mockRegisterCommand1);
when(mockRegisterCommand1.isError).thenReturn(true);

const error = 'error message.';

when(mockCommand0.result).thenReturn(Result.error(error));
when(mockRegisterCommand1.result).thenReturn(Result.error(error));

await tester.pumpWidget(createLoginScreen());
await tester.pumpAndSettle();
Expand Down
Loading

0 comments on commit a04245e

Please sign in to comment.