From a38bed9237643dd023b88cee7d699c2e83a11151 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:46:01 +0100 Subject: [PATCH] Replace `AlphaVersionBanner` with `DevelopmentStageBanner`. (#1291) This replaces the `AlphaVersionBanner` with `DevelopmentStageBanner` so that a banner is always shown if the user uses a non-stable version of Sharezone. This is useful for #1290 (new "preview" stage for preview builds in PRs). Currently the banner is only shown in alpha, not in beta. This will show a banner in alpha and beta. ![grafik](https://github.com/SharezoneApp/sharezone-app/assets/29028262/44bcbfa5-8137-4fe2-81f0-a0cc7db2e9d1) ## Summary by CodeRabbit - **New Features** - Introduced a Development Stage Banner to inform users about the current development stage of the app. - **Refactor** - Improved the flexibility of testing by allowing the development stage variable to be overridden. - Enhanced the Development Stage Banner to dynamically display the app's development stage. - **Tests** - Added tests to ensure the Development Stage Banner accurately reflects the app's current stage. --- app/lib/main/constants.dart | 3 + app/lib/main/sharezone.dart | 8 +- ...ner.dart => development_stage_banner.dart} | 32 ++++--- .../widgets/alpha_version_banner_test.dart | 76 ----------------- .../development_stage_banner_test.dart | 85 +++++++++++++++++++ 5 files changed, 109 insertions(+), 95 deletions(-) rename app/lib/widgets/{alpha_version_banner.dart => development_stage_banner.dart} (55%) delete mode 100644 app/test_goldens/widgets/alpha_version_banner_test.dart create mode 100644 app/test_goldens/widgets/development_stage_banner_test.dart diff --git a/app/lib/main/constants.dart b/app/lib/main/constants.dart index 132508a07..eac2e26b7 100644 --- a/app/lib/main/constants.dart +++ b/app/lib/main/constants.dart @@ -6,4 +6,7 @@ // // SPDX-License-Identifier: EUPL-1.2 +// Can be overridden for testing purposes. +String? kDevelopmentStageOrNull = + kDevelopmentStage == "" ? null : kDevelopmentStage; const kDevelopmentStage = String.fromEnvironment('DEVELOPMENT_STAGE'); diff --git a/app/lib/main/sharezone.dart b/app/lib/main/sharezone.dart index 8a6ec8cea..bfe286750 100644 --- a/app/lib/main/sharezone.dart +++ b/app/lib/main/sharezone.dart @@ -14,6 +14,7 @@ import 'package:bloc_provider/multi_bloc_provider.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:overlay_support/overlay_support.dart'; +import 'package:platform_check/platform_check.dart'; import 'package:provider/provider.dart'; import 'package:sharezone/account/theme/theme_settings.dart'; import 'package:sharezone/dynamic_links/beitrittsversuch.dart'; @@ -21,7 +22,6 @@ import 'package:sharezone/dynamic_links/dynamic_link_bloc.dart'; import 'package:sharezone/dynamic_links/dynamic_links.dart'; import 'package:sharezone/main/auth_app.dart'; import 'package:sharezone/main/bloc_dependencies.dart'; -import 'package:sharezone/main/constants.dart'; import 'package:sharezone/main/sharezone_app.dart'; import 'package:sharezone/main/sharezone_bloc_providers.dart'; import 'package:sharezone/navigation/logic/navigation_bloc.dart'; @@ -29,10 +29,9 @@ import 'package:sharezone/notifications/notifications_permission.dart'; import 'package:sharezone/onboarding/group_onboarding/logic/signed_up_bloc.dart'; import 'package:sharezone/sharezone_plus/subscription_service/subscription_flag.dart'; import 'package:sharezone/util/flavor.dart'; -import 'package:sharezone/widgets/alpha_version_banner.dart'; import 'package:sharezone/widgets/animation/color_fade_in.dart'; +import 'package:sharezone/widgets/development_stage_banner.dart'; import 'package:sharezone_utils/device_information_manager.dart'; -import 'package:platform_check/platform_check.dart'; import 'package:sharezone_widgets/sharezone_widgets.dart'; /// Defines if the app is running in integration test mode. @@ -112,8 +111,7 @@ class _SharezoneState extends State with WidgetsBindingObserver { textDirection: TextDirection.ltr, child: _ThemeSettingsProvider( blocDependencies: widget.blocDependencies, - child: AlphaVersionBanner( - enabled: kDevelopmentStage == 'ALPHA', + child: DevelopmentStageBanner( child: Stack( children: [ MultiProvider( diff --git a/app/lib/widgets/alpha_version_banner.dart b/app/lib/widgets/development_stage_banner.dart similarity index 55% rename from app/lib/widgets/alpha_version_banner.dart rename to app/lib/widgets/development_stage_banner.dart index 841ed47c5..8974c87d7 100644 --- a/app/lib/widgets/alpha_version_banner.dart +++ b/app/lib/widgets/development_stage_banner.dart @@ -8,49 +8,53 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:sharezone/main/constants.dart'; -/// Displays a [Banner] saying "ALPHA" when running an alpha version at top left -/// hand corner. +/// Displays the current development stage as a [Banner] if it is not stable. /// -/// Displays nothing when [enabled] is false. +/// Sharezone has different development stages e.g. "alpha", "beta", "preview". +/// This widget displays the current development stage as a [Banner] at the top +/// hand corner of the screen if we are not in the stable/production development +/// stage. +/// +/// This is intended so that users know that they are using a non-stable version +/// of the app and that they should expect bugs and other issues. /// /// This widget is similar and inspired by the [CheckedModeBanner] which displays /// "DEBUG" at the top right hand corner when running a Flutter app in debug /// mode. -class AlphaVersionBanner extends StatelessWidget { +class DevelopmentStageBanner extends StatelessWidget { /// Creates a const alpha version banner. - const AlphaVersionBanner({ + const DevelopmentStageBanner({ super.key, required this.child, - required this.enabled, }); /// The widget to show behind the banner. final Widget child; - /// Defines if the alpha banner should shown. - /// - /// If set to false, the banner will not be shown and is not visible. - final bool enabled; + bool get _isStable => + kDevelopmentStageOrNull == null || _uppercasedStage == 'STABLE'; + String? get _uppercasedStage => kDevelopmentStageOrNull?.toUpperCase(); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); String message = 'disabled'; - if (enabled) { - message = 'ALPHA'; + if (!_isStable) { + message = _uppercasedStage!; } properties.add(DiagnosticsNode.message(message)); } @override Widget build(BuildContext context) { - if (!enabled) { + if (_isStable) { return child; } return Banner( - message: 'ALPHA', + message: _uppercasedStage!, textDirection: TextDirection.ltr, location: BannerLocation.topEnd, color: Colors.blue, diff --git a/app/test_goldens/widgets/alpha_version_banner_test.dart b/app/test_goldens/widgets/alpha_version_banner_test.dart deleted file mode 100644 index 6e942a3da..000000000 --- a/app/test_goldens/widgets/alpha_version_banner_test.dart +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2022 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:golden_toolkit/golden_toolkit.dart'; -import 'package:sharezone/widgets/alpha_version_banner.dart'; - -void main() { - group('AlphaVersionBanner', () { - testGoldens( - 'displays the banner at the correct position', - (tester) async { - await tester.pumpWidgetBuilder( - const AlphaVersionBanner( - enabled: true, - child: MaterialApp( - debugShowCheckedModeBanner: false, - home: Scaffold( - body: Text("Text"), - ), - ), - ), - ); - - await screenMatchesGolden(tester, 'alpha_version_banner'); - }, - ); - - testWidgets("does display the banner if [enabled] is true", (tester) async { - await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: AlphaVersionBanner( - enabled: true, - child: MaterialApp( - debugShowCheckedModeBanner: false, - home: Scaffold( - body: Text("Text"), - ), - ), - ), - ), - ); - - expect(find.byType(Banner), findsOneWidget); - }); - - testWidgets( - "does not display the banner if [enabled] is false", - (tester) async { - await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: AlphaVersionBanner( - enabled: false, - child: MaterialApp( - debugShowCheckedModeBanner: false, - home: Scaffold( - body: Text("Text"), - ), - ), - ), - ), - ); - - expect(find.byType(Banner), findsNothing); - }, - ); - }); -} diff --git a/app/test_goldens/widgets/development_stage_banner_test.dart b/app/test_goldens/widgets/development_stage_banner_test.dart new file mode 100644 index 000000000..ba0400015 --- /dev/null +++ b/app/test_goldens/widgets/development_stage_banner_test.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2022 Sharezone UG (haftungsbeschränkt) +// Licensed under the EUPL-1.2-or-later. +// +// You may obtain a copy of the Licence at: +// https://joinup.ec.europa.eu/software/page/eupl +// +// SPDX-License-Identifier: EUPL-1.2 + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:golden_toolkit/golden_toolkit.dart'; +import 'package:sharezone/main/constants.dart'; +import 'package:sharezone/widgets/development_stage_banner.dart'; + +void main() { + group('$DevelopmentStageBanner', () { + testGoldens( + 'displays the banner at the correct position', + (tester) async { + kDevelopmentStageOrNull = 'alpha'; + + await tester.pumpWidgetBuilder( + const DevelopmentStageBanner( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold( + body: Text("Text"), + ), + ), + ), + ); + + await screenMatchesGolden(tester, 'alpha_version_banner'); + }, + ); + + testWidgets("does display the banner if stage is alpha, beta or preview", + (tester) async { + for (var stage in ['alpha', 'beta', 'preview']) { + kDevelopmentStageOrNull = stage; + + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: DevelopmentStageBanner( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold( + body: Text("Text"), + ), + ), + ), + ), + ); + + expect(find.byType(Banner), findsOneWidget, + reason: 'Stage "$stage" should display the banner'); + } + }); + + testWidgets("does not display the banner if stage is 'stable' or null", + (tester) async { + for (var stage in ['stable', null]) { + kDevelopmentStageOrNull = stage; + + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: DevelopmentStageBanner( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold( + body: Text("Text"), + ), + ), + ), + ), + ); + + expect(find.byType(Banner), findsNothing, + reason: 'Stage "$stage" should not display the banner'); + } + }); + }); +}