Skip to content

Commit

Permalink
Move widgets of Sharezone Plus page into it's own package (#1233)
Browse files Browse the repository at this point in the history
This PR moves the UI widgets of the Sharezone Plus page into its own
package called `sharezone_plus_page_ui`. The motivation behind this is
to reuse these widgets on our website. This package only contains the UI
not any logic, like `SharezonePlusPageController` because the logic is
different between our app and the website (in our app you have an
account, on our website you don't have an account).
  • Loading branch information
nilsreichardt authored Jan 6, 2024
1 parent 90a401d commit 7bd1e84
Show file tree
Hide file tree
Showing 32 changed files with 1,780 additions and 776 deletions.
678 changes: 23 additions & 655 deletions app/lib/sharezone_plus/page/sharezone_plus_page.dart

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions app/pubspec.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ dependencies:
path: ../lib/sharezone_common
sharezone_utils:
path: ../lib/sharezone_utils
sharezone_plus_page_ui:
path: ../lib/sharezone_plus/sharezone_plus_page_ui
sharezone_widgets:
path: ../lib/sharezone_widgets
showcaseview: ^2.0.1
Expand Down
10 changes: 6 additions & 4 deletions app/test/sharezone_plus/sharezone_plus_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:sharezone/sharezone_plus/page/sharezone_plus_page.dart';
import 'package:sharezone/sharezone_plus/page/sharezone_plus_page_controller.dart';
import 'package:sharezone_plus_page_ui/sharezone_plus_page_ui.dart';

class MockSharezonePlusPageController extends ChangeNotifier
implements SharezonePlusPageController {
Expand Down Expand Up @@ -52,26 +53,27 @@ void main() {
}

testWidgets(
'shows $PriceLoadingIndicator if plus status has loaded but the price hasnt',
'shows $SharezonePlusPriceLoadingIndicator if plus status has loaded but the price hasnt',
(tester) async {
controller.hasPlus = true;
controller.price = null;

await pumpPlusPage(tester);
await tester.ensureVisible(find.byType(CallToActionButton));

expect(find.byType(PriceLoadingIndicator), findsOneWidget);
expect(find.byType(SharezonePlusPriceLoadingIndicator), findsOneWidget);
});

testWidgets('if loading then the $PriceLoadingIndicator is shown',
testWidgets(
'if loading then the $SharezonePlusPriceLoadingIndicator is shown',
(tester) async {
controller.hasPlus = null;
controller.price = null;

await pumpPlusPage(tester);
await tester.ensureVisible(find.byType(CallToActionButton));

expect(find.byType(PriceLoadingIndicator), findsOneWidget);
expect(find.byType(SharezonePlusPriceLoadingIndicator), findsOneWidget);
});

testWidgets('if loading then the "subscribe" button is disabled',
Expand Down
117 changes: 0 additions & 117 deletions app/test_goldens/sharezone_plus/sharezone_plus_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,6 @@ void main() {
);
}

Future<void> tapEveryExpansionCard(WidgetTester tester) async {
for (final element in find.byType(ExpansionCard).evaluate()) {
// We need to scroll the element into view before we can tap it.
await tester.dragUntilVisible(
find.byWidget(element.widget),
find.byType(SingleChildScrollView),
const Offset(0, 50),
);

await tester.tap(find.byWidget(element.widget));
}
await tester.pumpAndSettle();
}

testGoldens('renders page as expected (light theme)', (tester) async {
await pumpPlusPage(tester, theme: getLightTheme());

Expand Down Expand Up @@ -158,108 +144,5 @@ void main() {
devices: [Device.tabletPortrait],
);
});

// ignore: invalid_use_of_visible_for_testing_member
group(PlusAdvantages, () {
for (final typeOfUser in [
TypeOfUser.parent,
TypeOfUser.teacher,
TypeOfUser.student
]) {
Future<void> pumpPlusAdvantages(
WidgetTester tester, {
required ThemeData theme,
required TypeOfUser typeOfUser,
}) async {
await tester.pumpWidgetBuilder(
Provider<TypeOfUser?>(
create: (context) => typeOfUser,
child: const SingleChildScrollView(
child: PlusAdvantages(),
),
),
wrapper: materialAppWrapper(theme: theme),
);
}

testGoldens(
'renders advantages for ${typeOfUser.name} as expected (dark theme)',
(tester) async {
await pumpPlusAdvantages(
tester,
theme: getDarkTheme(),
typeOfUser: typeOfUser,
);

await tapEveryExpansionCard(tester);

await multiScreenGolden(
tester,
'sharezone_plus_advantages_${typeOfUser.name}_dark_theme',
// Since we only need to test the expanded advantages and we have
// already tested the Sharezone Plus page for all devices, we don't
// need to test it for all devices. Using a tablet portrait is
// sufficient.
devices: [Device.tabletPortrait],
);
});

testGoldens(
'renders advantages for ${typeOfUser.name} as expected (light theme)',
(tester) async {
await pumpPlusAdvantages(
tester,
theme: getLightTheme(),
typeOfUser: typeOfUser,
);

await tapEveryExpansionCard(tester);

await multiScreenGolden(
tester,
'sharezone_plus_advantages_${typeOfUser.name}_light_theme',
// See comment above.
devices: [Device.tabletPortrait],
);
});
}
});

// ignore: invalid_use_of_visible_for_testing_member
group(PlusFaqSection, () {
testGoldens('renders faq section as expected (dark theme)',
(tester) async {
await tester.pumpWidgetBuilder(
const SingleChildScrollView(child: PlusFaqSection()),
wrapper: materialAppWrapper(theme: getDarkTheme()),
);

await tapEveryExpansionCard(tester);

await multiScreenGolden(
tester,
'sharezone_plus_faq_section_dark_theme',
// See comment above.
devices: [Device.tabletPortrait],
);
});

testGoldens('renders faq section as expected (light theme)',
(tester) async {
await tester.pumpWidgetBuilder(
const SingleChildScrollView(child: PlusFaqSection()),
wrapper: materialAppWrapper(theme: getLightTheme()),
);

await tapEveryExpansionCard(tester);

await multiScreenGolden(
tester,
'sharezone_plus_faq_section_light_theme',
// See comment above.
devices: [Device.tabletPortrait],
);
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023 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

include: package:sharezone_lints/analysis_options.yaml
15 changes: 15 additions & 0 deletions lib/sharezone_plus/sharezone_plus_page_ui/dart_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 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

tags:
# The tag "golden" is used by the "golden_toolkit" package.
#
# This will indicate that goldens are an expected test tag. All tests that use
# testGoldens() will automatically be given this tag. This allows you to
# easily target golden tests from the command line.
golden:
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2023 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

library sharezone_plus_page_ui;

export 'src/sharezone_plus_advantages.dart';
export 'src/sharezone_plus_faq.dart';
export 'src/sharezone_plus_legal_text.dart';
export 'src/sharezone_plus_page_header.dart';
export 'src/sharezone_plus_page_theme.dart';
export 'src/sharezone_plus_support_note.dart';
export 'src/why_sharezone_plus_card.dart';
export 'src/sharezone_plus_price.dart';
export 'src/call_to_action_button.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2024 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:sharezone_widgets/sharezone_widgets.dart';

class CallToActionButton extends StatelessWidget {
const CallToActionButton({
required this.text,
this.onPressed,
this.backgroundColor,
}) : super(key: const ValueKey('call-to-action-button'));

final Widget text;
final VoidCallback? onPressed;
final Color? backgroundColor;

@override
Widget build(BuildContext context) {
return MaxWidthConstraintBox(
maxWidth: 300,
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor,
textStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.5),
),
foregroundColor: Colors.white,
shadowColor: Colors.transparent,
elevation: 0,
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
child: text,
),
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2024 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_markdown/flutter_markdown.dart';
import 'package:url_launcher/url_launcher.dart';

class MarkdownCenteredText extends StatelessWidget {
const MarkdownCenteredText({super.key, required this.text});

final String text;

@override
Widget build(BuildContext context) {
return MarkdownBody(
data: text,
styleSheet: MarkdownStyleSheet(
a: TextStyle(
color: Theme.of(context).primaryColor,
decoration: TextDecoration.underline,
),
textAlign: WrapAlignment.center,
),
onTapLink: (text, href, title) async {
if (href == null) return;

if (href == 'https://sharezone.net/privacy-policy') {
Navigator.pushNamed(context, 'privacy-policy');
return;
}

await launchUrl(Uri.parse(href));
},
);
}
}
Loading

0 comments on commit 7bd1e84

Please sign in to comment.