From e4ecfe53f9cbadfb953b6d5115992524bc70ed27 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Sun, 25 Aug 2024 16:51:01 +0100 Subject: [PATCH] Tests for EventList Error Pages --- .../events/pages/event_list_page.dart | 30 ++++-- .../events/providers/event_providers.dart | 4 +- .../features/events/error_pages_test.dart | 100 ++++++++++++++++++ 3 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 app/test/features/events/error_pages_test.dart diff --git a/app/lib/features/events/pages/event_list_page.dart b/app/lib/features/events/pages/event_list_page.dart index 1878480733f6..f8949d8804d9 100644 --- a/app/lib/features/events/pages/event_list_page.dart +++ b/app/lib/features/events/pages/event_list_page.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'package:acter/common/providers/space_providers.dart'; import 'package:acter/common/toolkit/buttons/primary_action_button.dart'; +import 'package:acter/common/toolkit/errors/error_page.dart'; import 'package:acter/common/utils/routes.dart'; import 'package:acter/common/widgets/acter_search_widget.dart'; import 'package:acter/common/widgets/add_button_with_can_permission.dart'; @@ -34,7 +35,7 @@ class _EventListPageState extends ConsumerState { String get searchValue => ref.watch(searchValueProvider); - EventFilters get eventFilterValue => ref.watch(eventFilerProvider); + EventFilters get eventFilterValue => ref.watch(eventFilterProvider); @override Widget build(BuildContext context) { @@ -85,10 +86,19 @@ class _EventListPageState extends ConsumerState { Expanded( child: calEventsLoader.when( data: (calEvents) => _buildEventList(calEvents), - error: (e, s) { - _log.severe('Failed to search events in space', e, s); - return Center( - child: Text(L10n.of(context).searchingFailed(e)), + error: (error, stack) { + _log.severe('Failed to search events in space', error, stack); + return ErrorPage( + background: const EventListSkeleton(), + error: error, + stack: stack, + onRetryTap: () { + ref.invalidate( + eventListSearchFilterProvider( + (spaceId: widget.spaceId, searchText: searchValue), + ), + ); + }, ); }, loading: () => const EventListSkeleton(), @@ -109,7 +119,7 @@ class _EventListPageState extends ConsumerState { selected: eventFilterValue == EventFilters.all, label: Text(L10n.of(context).all), onSelected: (value) => ref - .read(eventFilerProvider.notifier) + .read(eventFilterProvider.notifier) .state = EventFilters.all, ), const SizedBox(width: 10), @@ -117,7 +127,7 @@ class _EventListPageState extends ConsumerState { selected: eventFilterValue == EventFilters.bookmarked, label: Text(L10n.of(context).bookmarked), onSelected: (value) => ref - .read(eventFilerProvider.notifier) + .read(eventFilterProvider.notifier) .state = EventFilters.bookmarked, ), const SizedBox(width: 10), @@ -125,7 +135,7 @@ class _EventListPageState extends ConsumerState { selected: eventFilterValue == EventFilters.ongoing, label: Text(L10n.of(context).happeningNow), onSelected: (value) => ref - .read(eventFilerProvider.notifier) + .read(eventFilterProvider.notifier) .state = EventFilters.ongoing, ), const SizedBox(width: 10), @@ -133,7 +143,7 @@ class _EventListPageState extends ConsumerState { selected: eventFilterValue == EventFilters.upcoming, label: Text(L10n.of(context).upcoming), onSelected: (value) => ref - .read(eventFilerProvider.notifier) + .read(eventFilterProvider.notifier) .state = EventFilters.upcoming, ), const SizedBox(width: 10), @@ -141,7 +151,7 @@ class _EventListPageState extends ConsumerState { selected: eventFilterValue == EventFilters.past, label: Text(L10n.of(context).past), onSelected: (value) => ref - .read(eventFilerProvider.notifier) + .read(eventFilterProvider.notifier) .state = EventFilters.past, ), ], diff --git a/app/lib/features/events/providers/event_providers.dart b/app/lib/features/events/providers/event_providers.dart index e7e52e0f1c6d..4fe22f4c7716 100644 --- a/app/lib/features/events/providers/event_providers.dart +++ b/app/lib/features/events/providers/event_providers.dart @@ -125,7 +125,7 @@ enum EventFilters { past, } -final eventFilerProvider = +final eventFilterProvider = StateProvider.autoDispose((ref) => EventFilters.all); //SEARCH EVENTS @@ -138,7 +138,7 @@ final eventListSearchFilterProvider = FutureProvider.autoDispose List filteredEventList = []; //Filter events based on the selection - EventFilters eventFilter = ref.watch(eventFilerProvider); + EventFilters eventFilter = ref.watch(eventFilterProvider); switch (eventFilter) { case EventFilters.bookmarked: { diff --git a/app/test/features/events/error_pages_test.dart b/app/test/features/events/error_pages_test.dart new file mode 100644 index 000000000000..88ddb517a10a --- /dev/null +++ b/app/test/features/events/error_pages_test.dart @@ -0,0 +1,100 @@ +import 'package:acter/common/providers/room_providers.dart'; +import 'package:acter/common/providers/space_providers.dart'; +import 'package:acter/common/widgets/acter_search_widget.dart'; +import 'package:acter/features/events/pages/event_list_page.dart'; +import 'package:acter/features/events/providers/event_providers.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../helpers/error_helpers.dart'; +import '../../helpers/test_util.dart'; + +void main() { + group('Event List Error Pages', () { + testWidgets('full list', (tester) async { + bool shouldFail = true; + await tester.pumpProviderWidget( + overrides: [ + eventListSearchFilterProvider.overrideWith((a, b) { + if (shouldFail) { + // toggle failure so the retry works + shouldFail = !shouldFail; + throw 'Expected fail: Space not loaded'; + } + return []; + }), + hasSpaceWithPermissionProvider.overrideWith((_, ref) => false), + ], + child: const EventListPage(), + ); + await tester.ensureErrorPageWithRetryWorks(); + }); + testWidgets('full list with search', (tester) async { + bool shouldFail = true; + + await tester.pumpProviderWidget( + overrides: [ + searchValueProvider + .overrideWith((_) => 'some string'), // set a search string + + eventListSearchFilterProvider.overrideWith((a, b) { + if (shouldFail) { + // toggle failure so the retry works + shouldFail = !shouldFail; + throw 'Expected fail: Space not loaded'; + } + return []; + }), + hasSpaceWithPermissionProvider.overrideWith((_, ref) => false), + ], + child: const EventListPage(), + ); + await tester.ensureErrorPageWithRetryWorks(); + }); + + testWidgets('space list', (tester) async { + bool shouldFail = true; + await tester.pumpProviderWidget( + overrides: [ + roomDisplayNameProvider.overrideWith((a, b) => 'test'), + eventListSearchFilterProvider.overrideWith((a, b) { + if (shouldFail) { + // toggle failure so the retry works + shouldFail = !shouldFail; + throw 'Expected fail: Space not loaded'; + } + return []; + }), + hasSpaceWithPermissionProvider.overrideWith((_, ref) => false), + ], + child: const EventListPage( + spaceId: '!test', + ), + ); + await tester.ensureErrorPageWithRetryWorks(); + }); + + testWidgets('space list with search', (tester) async { + bool shouldFail = true; + await tester.pumpProviderWidget( + overrides: [ + roomDisplayNameProvider.overrideWith((a, b) => 'test'), + searchValueProvider + .overrideWith((_) => 'some search'), // set a search string + eventListSearchFilterProvider.overrideWith((a, b) { + if (shouldFail) { + // toggle failure so the retry works + shouldFail = !shouldFail; + throw 'Expected fail: Space not loaded'; + } + return []; + }), + hasSpaceWithPermissionProvider.overrideWith((_, ref) => false), + ], + child: const EventListPage( + spaceId: '!test', + ), + ); + await tester.ensureErrorPageWithRetryWorks(); + }); + }); +}