diff --git a/lib/game/components/backbox/backbox.dart b/lib/game/components/backbox/backbox.dart index 36b4d597..e3b935fe 100644 --- a/lib/game/components/backbox/backbox.dart +++ b/lib/game/components/backbox/backbox.dart @@ -65,6 +65,8 @@ class Backbox extends PositionComponent with ZIndex, HasGameRef { _display.add(LoadingDisplay()); } else if (state is LeaderboardSuccessState) { _display.add(LeaderboardDisplay(entries: state.entries)); + } else if (state is LeaderboardFailureState) { + _display.add(LeaderboardFailureDisplay()); } else if (state is InitialsFormState) { if (_platformHelper.isMobile) { gameRef.overlays.add(PinballGame.mobileControlsOverlay); diff --git a/lib/game/components/backbox/displays/displays.dart b/lib/game/components/backbox/displays/displays.dart index 4dda7048..06b0a4e3 100644 --- a/lib/game/components/backbox/displays/displays.dart +++ b/lib/game/components/backbox/displays/displays.dart @@ -2,4 +2,5 @@ export 'initials_input_display.dart'; export 'initials_submission_failure_display.dart'; export 'initials_submission_success_display.dart'; export 'leaderboard_display.dart'; +export 'leaderboard_failure_display.dart'; export 'loading_display.dart'; diff --git a/lib/game/components/backbox/displays/leaderboard_failure_display.dart b/lib/game/components/backbox/displays/leaderboard_failure_display.dart new file mode 100644 index 00000000..a519f9e2 --- /dev/null +++ b/lib/game/components/backbox/displays/leaderboard_failure_display.dart @@ -0,0 +1,23 @@ +import 'package:flame/components.dart'; +import 'package:pinball/l10n/l10n.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +/// {@template leaderboard_failure_display} +/// Display showing an error message when the leaderboard couldn't be loaded +/// {@endtemplate} +class LeaderboardFailureDisplay extends Component { + /// {@macro leaderboard_failure_display} + LeaderboardFailureDisplay(); + + @override + Future onLoad() async { + final l10n = readProvider(); + await add( + ErrorComponent( + label: l10n.leaderboardErrorMessage, + position: Vector2(0, -18), + ), + ); + } +} diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 6f265fd5..fd633efe 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -159,5 +159,9 @@ "initialsErrorMessage": "Please try a different combination of letters", "@initialsErrorMessage": { "description": "Message on shown when the initials submission fails" + }, + "leaderboardErrorMessage": "No connection. Leaderboard and sharing functionality is unavailable.", + "@leaderboardErrorMessage": { + "description": "Text shown when the leaderboard had an error while loading" } } diff --git a/test/game/components/backbox/backbox_test.dart b/test/game/components/backbox/backbox_test.dart index 2c2ea5db..4b257345 100644 --- a/test/game/components/backbox/backbox_test.dart +++ b/test/game/components/backbox/backbox_test.dart @@ -105,6 +105,8 @@ class _MockAppLocalizations extends Mock implements AppLocalizations { @override String get initialsErrorMessage => ''; + + String get leaderboardErrorMessage => ''; } void main() { @@ -319,6 +321,28 @@ void main() { }, ); + flameTester.test( + 'adds LeaderboardFailureDisplay on LeaderboardFailureState', + (game) async { + whenListen( + bloc, + Stream.empty(), + initialState: LeaderboardFailureState(), + ); + + final backbox = Backbox.test( + bloc: bloc, + platformHelper: platformHelper, + ); + await game.pump(backbox); + + expect( + game.descendants().whereType().length, + equals(1), + ); + }, + ); + flameTester.test( 'closes the subscription when it is removed', (game) async { diff --git a/test/game/components/backbox/displays/leaderboard_failure_display_test.dart b/test/game/components/backbox/displays/leaderboard_failure_display_test.dart new file mode 100644 index 00000000..8ce4c839 --- /dev/null +++ b/test/game/components/backbox/displays/leaderboard_failure_display_test.dart @@ -0,0 +1,60 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball/game/components/backbox/displays/displays.dart'; +import 'package:pinball/l10n/l10n.dart'; +import 'package:pinball_components/gen/assets.gen.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class _TestGame extends Forge2DGame { + @override + Future onLoad() async { + await super.onLoad(); + images.prefix = ''; + await images.loadAll( + [ + Assets.images.errorBackground.keyName, + ], + ); + } + + Future pump(LeaderboardFailureDisplay component) { + return ensureAdd( + FlameProvider.value( + _MockAppLocalizations(), + children: [component], + ), + ); + } +} + +class _MockAppLocalizations extends Mock implements AppLocalizations { + @override + String get leaderboardErrorMessage => 'Message'; +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group('LeaderboardFailureDisplay', () { + final flameTester = FlameTester(_TestGame.new); + + flameTester.test('renders correctly', (game) async { + await game.pump(LeaderboardFailureDisplay()); + + expect( + game + .descendants() + .where( + (component) => + component is TextComponent && component.text == 'Message', + ) + .length, + equals(1), + ); + }); + }); +} diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index b05e349f..ba54939c 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -57,7 +57,10 @@ class _TestDebugPinballGame extends DebugPinballGame { class _MockGameBloc extends Mock implements GameBloc {} -class _MockAppLocalizations extends Mock implements AppLocalizations {} +class _MockAppLocalizations extends Mock implements AppLocalizations { + @override + String get leaderboardErrorMessage => ''; +} class _MockEventPosition extends Mock implements EventPosition {} diff --git a/test/game/view/pinball_game_page_test.dart b/test/game/view/pinball_game_page_test.dart index 18dbeec7..b2cde26e 100644 --- a/test/game/view/pinball_game_page_test.dart +++ b/test/game/view/pinball_game_page_test.dart @@ -50,7 +50,10 @@ class _MockAssetsManagerCubit extends Mock implements AssetsManagerCubit {} class _MockStartGameBloc extends Mock implements StartGameBloc {} -class _MockAppLocalizations extends Mock implements AppLocalizations {} +class _MockAppLocalizations extends Mock implements AppLocalizations { + @override + String get leaderboardErrorMessage => ''; +} class _MockPinballAudioPlayer extends Mock implements PinballAudioPlayer {}