[ermine] Add more widget tests for App widget.

Test: Adds unittest to toggle between overview and home widgets. Also
switches locales.

Change-Id: Ie0343f149eb45719d27610d1cfa89a46a3d64b66
Reviewed-on: https://fuchsia-review.googlesource.com/c/experiences/+/383810
Commit-Queue: Sanjay Chouksey <sanjayc@google.com>
Reviewed-by: Yeonhee Lee <yhlee@google.com>
Testability-Review: Chase Latta <chaselatta@google.com>
diff --git a/session_shells/ermine/shell/lib/src/widgets/app.dart b/session_shells/ermine/shell/lib/src/widgets/app.dart
index 630443e..b99a8b1 100644
--- a/session_shells/ermine/shell/lib/src/widgets/app.dart
+++ b/session_shells/ermine/shell/lib/src/widgets/app.dart
@@ -53,18 +53,27 @@
                   fit: StackFit.expand,
                   children: <Widget>[
                     // Recents.
-                    RecentsContainer(model: model),
+                    buildRecents(model),
 
                     // Overview or Home.
                     AnimatedBuilder(
                       animation: model.overviewVisibility,
                       builder: (context, _) => model.overviewVisibility.value
-                          ? OverviewContainer(model: model)
-                          : HomeContainer(model: model),
+                          ? buildOverview(model)
+                          : buildHome(model),
                     ),
                   ],
                 )),
           );
         });
   }
+
+  @visibleForTesting
+  Widget buildRecents(AppModel model) => RecentsContainer(model: model);
+
+  @visibleForTesting
+  Widget buildOverview(AppModel model) => OverviewContainer(model: model);
+
+  @visibleForTesting
+  Widget buildHome(AppModel model) => HomeContainer(model: model);
 }
diff --git a/session_shells/ermine/shell/test/app_widget_test.dart b/session_shells/ermine/shell/test/app_widget_test.dart
index 6361930..c52a72a 100644
--- a/session_shells/ermine/shell/test/app_widget_test.dart
+++ b/session_shells/ermine/shell/test/app_widget_test.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:ui';
+import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -17,20 +17,82 @@
 void main() async {
   setupLogger(name: 'ermine_unittests');
 
+  TestApp app;
+  MockAppModel model;
+  StreamController<Locale> controller;
+
+  setUp(() {
+    model = MockAppModel();
+    app = TestApp(model);
+
+    controller = StreamController<Locale>();
+    when(model.localeStream).thenAnswer((_) => controller.stream);
+  });
+
+  tearDown(() async {
+    await controller.close();
+  });
+
   testWidgets('Test locale change', (tester) async {
-    final swissFrench = Locale('fr', 'CH');
+    when(model.overviewVisibility).thenReturn(ValueNotifier<bool>(true));
 
-    final model = MockAppModel();
-    when(model.localeStream).thenAnswer(
-        (_) => Stream<Locale>.value(swissFrench).asBroadcastStream());
-    when(model.overviewVisibility).thenReturn(ValueNotifier<bool>(false));
-
-    final app = App(model: model);
     await tester.pumpWidget(app);
-    // Pump widget for StreamBuilder<Locale>.
-    await tester.pump();
+    // app should be OffStage until locale is pushed.
+    expect(find.byType(MaterialApp), findsNothing);
+
+    // Set default locale.
+    final defaultLocale = Locale('en', 'US');
+    controller.add(defaultLocale);
+    await tester.pumpAndSettle();
+    expect(Intl.defaultLocale, defaultLocale.toString());
+
+    // Switch locale to swiss french.
+    final swissFrench = Locale('fr', 'CH');
+    controller.add(swissFrench);
+    await tester.pumpAndSettle();
     expect(Intl.defaultLocale, swissFrench.toString());
   });
+
+  testWidgets('Toggle between overview and home containers', (tester) async {
+    // Set locale to render the app.
+    controller.add(Locale('en', 'US'));
+
+    // Make Overview visible.
+    final overviewNotifier = ValueNotifier<bool>(true);
+    when(model.overviewVisibility).thenReturn(overviewNotifier);
+
+    await tester.pumpWidget(app);
+    await tester.pumpAndSettle();
+
+    expect(find.byWidget(app.recents), findsOneWidget);
+    expect(find.byWidget(app.overview), findsOneWidget);
+    expect(find.byWidget(app.home), findsNothing);
+
+    // Home should be visible.
+    overviewNotifier.value = false;
+    await tester.pumpAndSettle();
+
+    expect(find.byWidget(app.recents), findsOneWidget);
+    expect(find.byWidget(app.overview), findsNothing);
+    expect(find.byWidget(app.home), findsOneWidget);
+  });
+}
+
+class TestApp extends App {
+  final Widget overview = Container();
+  final Widget home = Container();
+  final Widget recents = Container();
+
+  TestApp(AppModel model) : super(model: model);
+
+  @override
+  Widget buildRecents(AppModel model) => recents;
+
+  @override
+  Widget buildOverview(AppModel model) => overview;
+
+  @override
+  Widget buildHome(AppModel model) => home;
 }
 
 class MockAppModel extends Mock implements AppModel {}