Skip to content

Commit

Permalink
Merge pull request #112 from fga-eps-mds/fix#64/ajusta-refreshIndicator
Browse files Browse the repository at this point in the history
[FIX]: Resolve retorno refresh indicator(fga-eps-mds/2024.2-ARANDU-DOC#64)
  • Loading branch information
GabrielCostaDeOliveira authored Feb 9, 2025
2 parents 71af664 + 658d15b commit c7c6949
Show file tree
Hide file tree
Showing 12 changed files with 657 additions and 46 deletions.
54 changes: 35 additions & 19 deletions lib/ui/journey/view/journey_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,48 +67,64 @@ class _JourneyScreen extends StatelessWidget {
return RefreshIndicator(
onRefresh: () => viewModel.getJourneyCommand.execute(subject.id),
child: ListenableBuilder(
listenable: viewModel.getJourneyCommand,
builder: (context, child) {
if (viewModel.getJourneyCommand.isOk) {
return _buildListView(context);
} else if (viewModel.getJourneyCommand.isError) {
return ErrorScreen(message: "Deslize para baixo\n\n ${viewModel.getJourneyCommand.result!.asError!.error.toString()}");
} else {
return const LoadingWidget();
}
},
),
listenable: viewModel.getJourneyCommand,
builder: (context, child) {
if (viewModel.getJourneyCommand.isOk) {
return _buildListView(context);
} else {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (viewModel.getJourneyCommand.isError)
ErrorScreen(
message:
"Deslize para baixo \n\n ${viewModel.getJourneyCommand.result!.asError!.error.toString()}",
)
else if (!viewModel.isReloadingData)
const LoadingWidget(),
],
),
),
),
);
}
}),
);
}

ListView _buildListView(BuildContext context) {

JourneyViewModel viewModel = Provider.of<JourneyViewModel>(context);

return ListView.builder(
itemCount: viewModel.getJourneyCommand.result!.asValue!.value.length,
shrinkWrap: true,
itemBuilder: (context, index) {
var journey = viewModel.getJourneyCommand.result!.asValue!.value[index];
var journey =
viewModel.getJourneyCommand.result!.asValue!.value[index];
return ListTile(
leading: Icon(
Icons.border_right,
color: Theme.of(context).colorScheme.primary,
size: 32,
),
title: Text(journey.title),
subtitle: Text(journey.description?? "Sem descrição"),
subtitle: Text(journey.description ?? "Sem descrição"),
trailing: Icon(
Icons.chevron_right,
color: Theme.of(context).colorScheme.primary,
size: 32,
),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Trails(journey: journey),
),
);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Trails(journey: journey),
),
);
},
);
});
Expand Down
6 changes: 6 additions & 0 deletions lib/ui/journey/viewmodel/journey_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import 'package:get_it/get_it.dart';

class JourneyViewModel extends ChangeNotifier {
late Command1<List<JourneyModel>, String> getJourneyCommand;
bool _isReloadingData = false;

JourneyViewModel() {
getJourneyCommand = Command1(getJourney);
}

bool get isReloadingData => _isReloadingData;

Future<Result<List<JourneyModel>>> getJourney(String subjectId) async {
_isReloadingData = true;
notifyListeners();

List<JourneyModel> res = await GetIt.instance<JourneyService>()
.getJourneys(JourneyRequest(subjectId: subjectId));

Expand Down
25 changes: 19 additions & 6 deletions lib/ui/subjects/view/subjects_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,31 @@ class _SubjectScreen extends StatelessWidget {
final screenHeight = MediaQuery.of(context).size.height;

return RefreshIndicator(
onRefresh: viewModel.subjectCommand.execute,
onRefresh: () async { await viewModel.subjectCommand.execute();},
child: ListenableBuilder(
listenable: viewModel.subjectCommand,
builder: (context, child) {
if (viewModel.subjectCommand.isOk) {
return _createListView(viewModel, screenHeight);
} else if (viewModel.subjectCommand.isError) {
return ErrorScreen(
message:
"Deslize para baixo \n\n ${viewModel.subjectCommand.result!.asError!.error.toString()}");
} else {
return const LoadingWidget();
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (viewModel.subjectCommand.isError)
ErrorScreen(message:"Deslize para baixo \n\n ${viewModel.subjectCommand.result!.asError!.error.toString()}",
)
else if (!viewModel.isReloadingData)
const LoadingWidget(),
],
),
),
),
);
}
},
),
Expand Down
7 changes: 7 additions & 0 deletions lib/ui/subjects/viewmodel/subjects_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ class SubjectsViewmodel extends ChangeNotifier {
late Command0<List<SubjectModel>> subjectCommand;
late Command1<bool, String> isUserSUbscribedCommand;

bool _isReloadingData = false;

SubjectsViewmodel() {
subjectCommand = Command0(_subject);
subjectCommand.execute();

isUserSUbscribedCommand = Command1<bool, String>(_isUserSUbscribed);
}

bool get isReloadingData => _isReloadingData;

Future<Result<List<SubjectModel>>> _subject() async {
_isReloadingData = true;
notifyListeners();

final res = await GetIt.instance<SubjectService>().getSubjects();

return Result.value(res);
Expand Down
31 changes: 23 additions & 8 deletions lib/ui/trails/view/trails_view.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'package:aranduapp/core/log/log.dart';
import 'package:aranduapp/ui/content/view/content_view.dart';
import 'package:aranduapp/ui/journey/model/journey_model.dart';
import 'package:aranduapp/ui/pages_content/view/pages_content_view.dart';
import 'package:aranduapp/ui/shared/erro_screen.dart';
Expand Down Expand Up @@ -72,12 +70,27 @@ class _TrailsScreen extends StatelessWidget {
builder: (context, child) {
if (viewModel.getTrailsCommand.isOk) {
return _buildListView(context);
} else if (viewModel.getTrailsCommand.isError) {
return ErrorScreen(
message:
"Deslize para baixo\n\n ${viewModel.getTrailsCommand.result!.asError!.error.toString()}");
} else {
return const LoadingWidget();
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (viewModel.getTrailsCommand.isError)
ErrorScreen(
message:
"Deslize para baixo \n\n ${viewModel.getTrailsCommand.result!.asError!.error.toString()}",
)
else if (!viewModel.isReloadingData)
const LoadingWidget(),
],
),
),
),
);
}
},
),
Expand Down Expand Up @@ -108,7 +121,9 @@ class _TrailsScreen extends StatelessWidget {
if (trails.contects != null) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PagesContentView(listContent: trails.contects ?? [],),
builder: (context) => PagesContentView(
listContent: trails.contects ?? [],
),
),
);
}
Expand Down
7 changes: 7 additions & 0 deletions lib/ui/trails/viewmodel/trails_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ import 'package:get_it/get_it.dart';
class TrailsViewmodel extends ChangeNotifier {
late Command1<List<TrailsModel>, String> getTrailsCommand;

bool _isReloadingData = false;

TrailsViewmodel() {
getTrailsCommand = Command1(getTrails);
}

bool get isReloadingData => _isReloadingData;

Future<Result<List<TrailsModel>>> getTrails(String journeyId) async {
_isReloadingData = true;
notifyListeners();

List<TrailsModel> res = await GetIt.instance<TrailsService>()
.getTrails(TrailsRequest(journeyId: journeyId));

Expand Down
34 changes: 34 additions & 0 deletions test/ui/Shared/erro_screen_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/erro_screen.dart';

void main() {
testWidgets('Testa ErrorScreen', (WidgetTester tester) async {
const errorMessage = 'Esta é uma mensagem de erro de teste.';

await tester.pumpWidget(
const MaterialApp(
home: ErrorScreen(message: errorMessage),
),
);

expect(find.byIcon(Icons.error_sharp), findsOneWidget);

expect(find.text('Algo deu errado...'), findsOneWidget);

expect(find.text(errorMessage), findsOneWidget);

final iconFinder = find.byIcon(Icons.error_sharp);
final Icon iconWidget = tester.widget(iconFinder);
expect(iconWidget.color, isNotNull);

final textFinder1 = find.text('Algo deu errado...');
final Text textWidget1 = tester.widget(textFinder1);
expect(textWidget1.style?.color, isNotNull);

final textFinder2 = find.text(errorMessage);
final Text textWidget2 = tester.widget(textFinder2);
expect(textWidget2.style?.color, isNotNull);

});
}
28 changes: 15 additions & 13 deletions test/ui/join_subjects/view/join_subjects_view_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:aranduapp/core/network/auth_api.dart';
import 'package:aranduapp/core/state/command.dart';
import 'package:aranduapp/ui/join_subjects/view/join_subjects_view.dart';
import 'package:aranduapp/ui/join_subjects/viewmodel/join_subjects_viewmodel.dart';
Expand All @@ -15,27 +14,28 @@ import 'package:mockito/mockito.dart';
import 'join_subjects_view_test.mocks.dart';

@GenerateNiceMocks([MockSpec<JoinSubjectsViewmodel>(), MockSpec<Command1>()])
void main(){
void main() {
late MockJoinSubjectsViewmodel mockJoinSubjectsViewmodel;
late MockCommand1<void, String> mockJoinsubjectsCommand1;

final testSubject =
SubjectModel(id: '1', name: 'calculo1', shortName: '', description: 'derivadas');
final testSubject = SubjectModel(
id: '1', name: 'calculo1', shortName: '', description: 'derivadas');

setUp(() async {
mockJoinSubjectsViewmodel = MockJoinSubjectsViewmodel();
mockJoinsubjectsCommand1 = MockCommand1();

when(mockJoinSubjectsViewmodel.joinsubjectsCommand).thenReturn(mockJoinsubjectsCommand1);
when(mockJoinSubjectsViewmodel.joinsubjectsCommand)
.thenReturn(mockJoinsubjectsCommand1);

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

await GetIt.instance.reset();
GetIt.I.registerLazySingleton<JoinSubjectsViewmodel>(
() => mockJoinSubjectsViewmodel);
GetIt.I.registerLazySingleton<JourneyViewModel>(() => JourneyViewModel());
() => mockJoinSubjectsViewmodel);
GetIt.I.registerFactory<JourneyViewModel>(() => JourneyViewModel());
});

Widget createScreen() {
Expand All @@ -44,7 +44,7 @@ void main(){
);
}

testWidgets('Join subjects screen display', (WidgetTester tester) async{
testWidgets('Join subjects screen display', (WidgetTester tester) async {
await tester.pumpWidget(createScreen());
await tester.pumpAndSettle();

Expand All @@ -55,23 +55,25 @@ void main(){
expect(find.byType(CommandButton), findsOneWidget);
});

testWidgets('checks if when pressing the button it passes an ID', (WidgetTester tester) async{
testWidgets('checks if when pressing the button it passes an ID',
(WidgetTester tester) async {
await tester.pumpWidget(createScreen());
await tester.pumpAndSettle();

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

verify(mockJoinsubjectsCommand1.execute(testSubject.id)).called(1);

});
testWidgets('navigates to SubjectsView after successful join', (WidgetTester tester) async {

testWidgets('navigates to SubjectsView after successful join',
(WidgetTester tester) async {
when(mockJoinsubjectsCommand1.isOk).thenReturn(true);

await tester.pumpWidget(createScreen());

await tester.pumpAndSettle();

expect(find.byType(Journey), findsOneWidget);
});

}
}
Loading

0 comments on commit c7c6949

Please sign in to comment.