blob: 8213d910486fcfcf58c870f5f61ce869b4b49149 [file] [log] [blame]
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:cocoon_service/protos.dart';
import 'package:app_flutter/build_dashboard_page.dart';
import 'package:app_flutter/main.dart' as app show lightTheme;
import 'package:app_flutter/service/cocoon.dart';
import 'package:app_flutter/service/google_authentication.dart';
import 'package:app_flutter/state/build.dart';
import 'package:app_flutter/widgets/error_brook_watcher.dart';
import 'package:app_flutter/widgets/sign_in_button.dart';
import 'package:app_flutter/widgets/state_provider.dart';
import 'utils/fake_build.dart';
import 'utils/mocks.dart';
import 'utils/output.dart';
void main() {
testWidgets('shows sign in button', (WidgetTester tester) async {
final BuildState buildState = BuildState(
cocoonService: MockCocoonService(),
authService: MockGoogleSignInService(),
);
throwOnMissingStub(buildState.cocoonService as Mock);
when(buildState.cocoonService.fetchFlutterBranches())
.thenAnswer((_) => Completer<CocoonResponse<List<String>>>().future);
when(buildState.cocoonService.fetchCommitStatuses(branch: anyNamed('branch')))
.thenAnswer((_) => Completer<CocoonResponse<List<CommitStatus>>>().future);
when(buildState.cocoonService.fetchTreeBuildStatus(branch: anyNamed('branch')))
.thenAnswer((_) => Completer<CocoonResponse<bool>>().future);
await tester.pumpWidget(
MaterialApp(
home: ValueProvider<BuildState>(
value: buildState,
child: ValueProvider<GoogleSignInService>(
value: buildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
expect(find.byType(SignInButton), findsOneWidget);
await tester.pumpWidget(Container());
buildState.dispose();
});
testWidgets('shows branch dropdown button', (WidgetTester tester) async {
final BuildState fakeBuildState = FakeBuildState();
await tester.pumpWidget(
MaterialApp(
home: ValueProvider<BuildState>(
value: fakeBuildState,
child: ValueProvider<GoogleSignInService>(
value: fakeBuildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
final Type dropdownButtonType = DropdownButton<String>(
onChanged: (_) {},
items: const <DropdownMenuItem<String>>[],
).runtimeType;
expect(find.byType(dropdownButtonType), findsOneWidget);
});
testWidgets('shows loading when fetch tree status is null', (WidgetTester tester) async {
final BuildState fakeBuildState = FakeBuildState()..isTreeBuilding = null;
await tester.pumpWidget(
MaterialApp(
theme: app.lightTheme,
home: ValueProvider<BuildState>(
value: fakeBuildState,
child: ValueProvider<GoogleSignInService>(
value: fakeBuildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
expect(find.text('Loading...'), findsOneWidget);
final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
expect(appbarWidget.backgroundColor, Colors.grey);
});
testWidgets('shows tree closed when fetch tree status is false', (WidgetTester tester) async {
final BuildState fakeBuildState = FakeBuildState()..isTreeBuilding = false;
await tester.pumpWidget(
MaterialApp(
theme: app.lightTheme,
home: ValueProvider<BuildState>(
value: fakeBuildState,
child: ValueProvider<GoogleSignInService>(
value: fakeBuildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
expect(find.text('Tree is Closed'), findsOneWidget);
final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
expect(appbarWidget.backgroundColor, app.lightTheme.errorColor);
});
testWidgets('shows tree open when fetch tree status is true', (WidgetTester tester) async {
final BuildState fakeBuildState = FakeBuildState()..isTreeBuilding = true;
await tester.pumpWidget(
MaterialApp(
theme: app.lightTheme,
home: ValueProvider<BuildState>(
value: fakeBuildState,
child: ValueProvider<GoogleSignInService>(
value: fakeBuildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
expect(find.text('Tree is Open'), findsOneWidget);
final AppBar appbarWidget = find.byType(AppBar).evaluate().first.widget as AppBar;
expect(appbarWidget.backgroundColor, app.lightTheme.appBarTheme.color);
});
testWidgets('show error snackbar when error occurs', (WidgetTester tester) async {
String lastError;
final FakeBuildState buildState = FakeBuildState()..errors.addListener((String message) => lastError = message);
await tester.pumpWidget(
MaterialApp(
home: ValueProvider<BuildState>(
value: buildState,
child: ValueProvider<GoogleSignInService>(
value: buildState.authService,
child: const BuildDashboardPage(),
),
),
),
);
expect(find.text(lastError), findsNothing);
// propagate the error message
await checkOutput(
block: () async {
buildState.errors.send('ERROR');
},
output: <String>[
'ERROR',
],
);
await tester.pump();
await tester.pump(const Duration(milliseconds: 750)); // open animation for snackbar
expect(find.text(lastError), findsOneWidget);
// Snackbar message should go away after its duration
await tester.pump(ErrorBrookWatcher.errorSnackbarDuration); // wait the duration
await tester.pump(); // schedule animation
await tester.pump(const Duration(milliseconds: 1500)); // close animation
expect(find.text(lastError), findsNothing);
});
}