diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/ui_components/push_token_widget.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/ui_components/push_token_widget.dart index 0b574311d..77545aa7e 100644 --- a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/ui_components/push_token_widget.dart +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/ui_components/push_token_widget.dart @@ -16,7 +16,7 @@ class PushTokenWidget extends StatelessWidget { @override Widget build(BuildContext context) => InkWell( onTap: () { - if (value != null) { + if (value != null && error == null) { Clipboard.setData(ClipboardData(text: value!)); } }, @@ -50,6 +50,8 @@ class PushTokenWidget extends StatelessWidget { SizedBox(height: context.textFieldDialogTheme.spacingXSS), ShimmerText( error ?? value, + type: + ShimmerType.fixed(placeholderLength: label.length), style: context.textFieldDialogTheme .editFieldTextNotEditedTextStyle .copyWith( @@ -62,7 +64,7 @@ class PushTokenWidget extends StatelessWidget { ), ), Visibility( - visible: value != null, + visible: value != null && error == null, replacement: SizedBox(), child: Padding( padding: EdgeInsets.only( diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/views/notifications_page.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/views/notifications_page.dart index 0bfcf49df..1d2087a45 100644 --- a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/views/notifications_page.dart +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/lib/feature_notifications/views/notifications_page.dart @@ -98,16 +98,19 @@ class NotificationsPage extends StatelessWidget { label: context .l10n.featureNotifications.notificationTokenLabel, value: pushToken, + key: const Key('pushTokenSuccessWidget'), ), buildError: (context, error, bloc) => PushTokenWidget( label: context .l10n.featureNotifications.notificationTokenLabel, error: context.l10n.error.notImplemented, + key: const Key('pushTokenErrorWidget'), ), buildLoading: (context, bloc) => PushTokenWidget( label: context .l10n.featureNotifications.notificationTokenLabel, value: null, + key: const Key('pushTokenLoadingWidget'), ), ), ), diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/mocks/notifications_bloc_mock.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/mocks/notifications_bloc_mock.dart new file mode 100644 index 000000000..81e6a5bd8 --- /dev/null +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/mocks/notifications_bloc_mock.dart @@ -0,0 +1,43 @@ +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:rx_bloc/rx_bloc.dart'; +import 'package:rxdart/rxdart.dart'; +import 'package:{{project_name}}/base/models/errors/error_model.dart'; +import 'package:{{project_name}}/feature_notifications/blocs/notifications_bloc.dart'; + +import 'notifications_bloc_mock.mocks.dart'; + +@GenerateMocks([ + NotificationsBlocEvents, + NotificationsBlocStates, + NotificationsBlocType, +]) +NotificationsBlocType notificationsBlocMockFactory({ + String? pushToken, + ErrorModel? error, +}) { + final notificationsBloc = MockNotificationsBlocType(); + final eventsMock = MockNotificationsBlocEvents(); + final statesMock = MockNotificationsBlocStates(); + + when(notificationsBloc.events).thenReturn(eventsMock); + when(notificationsBloc.states).thenReturn(statesMock); + + final pushTokenState = (pushToken != null + ? Stream.value(Result.success(pushToken)) + : error == null + ? Stream>.value(Result.loading()) + : Stream>.value(Result.error(error))) + .publishReplay(maxSize: 1) + ..connect(); + + when(statesMock.pushToken).thenAnswer( + (_) => pushTokenState, + ); + + when(statesMock.errors).thenAnswer( + (_) => error != null ? Stream.value(error) : const Stream.empty(), + ); + + return notificationsBloc; +} diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/stubs.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/stubs.dart new file mode 100644 index 000000000..bc7dc3b25 --- /dev/null +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/stubs.dart @@ -0,0 +1,6 @@ + + +class Stubs { + static final pushToken = + 'euJaS9wGTQOuzDmVr8VSci:APA91bFHj6T67ns123mStP2PfberpS_srGCMBcFPSOza0lcLtx_231XFRx7kxcVEfYkYaf-YacRVj3ZRk9kFjh9ZC_1PjH6aFUNaWAns4DfcWHzkEO4wSW8'; +} diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/factories/notifications_page_factory.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/factories/notifications_page_factory.dart new file mode 100644 index 000000000..90611b4b2 --- /dev/null +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/factories/notifications_page_factory.dart @@ -0,0 +1,28 @@ +{{> licence.dart }} + +import 'package:flutter/material.dart'; +import 'package:flutter_rx_bloc/flutter_rx_bloc.dart'; +import 'package:provider/provider.dart'; +import 'package:{{project_name}}/base/models/errors/error_model.dart'; +import 'package:{{project_name}}/feature_notifications/blocs/notifications_bloc.dart'; +import 'package:{{project_name}}/feature_notifications/views/notifications_page.dart'; + +import '../../mocks/notifications_bloc_mock.dart'; + +/// wraps a [NotificationsPage] in a [Provider] of type [NotificationsBlocType], creating +/// a mocked bloc depending on the values being tested +Widget notificationsPageFactory({ + ErrorModel? error, + String? pushToken, +}) => + MultiProvider( + providers: [ + RxBlocProvider.value( + value: notificationsBlocMockFactory( + pushToken: pushToken, + error: error, + ), + ), + ], + child: const NotificationsPage(), + ); diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/error.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/error.png new file mode 100644 index 000000000..a38768938 Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/error.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/loading.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/loading.png new file mode 100644 index 000000000..6b698af0e Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/loading.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/success.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/success.png new file mode 100644 index 000000000..3a0a6d2b3 Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/dark_theme/success.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/error.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/error.png new file mode 100644 index 000000000..b12e133b9 Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/error.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/loading.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/loading.png new file mode 100644 index 000000000..da798c97d Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/loading.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/success.png b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/success.png new file mode 100644 index 000000000..37711d927 Binary files /dev/null and b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/goldens/ci/light_theme/success.png differ diff --git a/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/notifications_page_test.dart b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/notifications_page_test.dart new file mode 100644 index 000000000..efef331ff --- /dev/null +++ b/packages/rx_bloc_cli/mason_templates/bricks/rx_bloc_base/__brick__/test/feature_notifications/views/notifications_page_test.dart @@ -0,0 +1,34 @@ +{{> licence.dart }} + +import 'package:flutter_test/flutter_test.dart'; +import 'package:{{project_name}}/base/models/errors/error_model.dart'; + +import '../../helpers/golden_helper.dart'; +import '../stubs.dart'; +import 'factories/notifications_page_factory.dart'; + +void main() { + group( + 'NotificationsPage golden tests', + () => runGoldenTests( + [ + buildScenario( + scenario: 'success', + widget: notificationsPageFactory( + pushToken: Stubs.pushToken, + ), + ), + buildScenario( + scenario: 'error', + widget: notificationsPageFactory( + error: NotFoundErrorModel(message: 'Error message'), + ), + ), + buildScenario( + scenario: 'loading', + widget: notificationsPageFactory(), + ), + ], + ), + ); +}